一、什么是jsp,为何要使用jsp。html
再使用idea建立完一个web工程后,在webapp目录下会生成一个index.jspjava
直接编译运行,网站将自动打开这样一个网页:web
因此咱们能够推测这个index.jsp就是决定这个项目的初始页面的HTML编码的,这里的hello-world是部署Tomcat时设置的。浏览器
因此其实JSP就是用来编写HTML编码的一种解决方案,那为何须要额外的这样一套解决方案呢?缓存
这是我以前对Servlet简单的使用:安全
PrintWriter writer = resp.getWriter(); writer.append("<!DOCTYPE html>\r\n") .append("<html >\r\n") .append(" <head>\r\n") .append(" <title>hello user application</title>\r\n") .append(" </head>\r\n") .append(" <body>\r\n") .append(" Hello, ").append(user).append("!<br/><br/>\r\n") .append(" <form action=\"first\" method=\"POST\">") .append(" Enter your name:<br/>\r\n") .append(" <input type=\"text\" name=\"user\"/><br/>\r\n") .append(" <input type=\"submit\" value=\"Submit\"/>\r\n") .append(" </form>\r\n") .append(" </body>\r\n") .append("</html>\r\n");
这是在像response添加正文,用于HTML的编码,能够发现这里HTML和Java结合得并很差,致使代码很长还很乱,特别是引号须要转义符。因此其实咱们应该把这一块HTML编码独立出去,因此就有了这样一套名为JSP(JavaServerPages)的混合解决方案,它结合了Java代码和HTML标签,JSP包括了全部的HTML标签,以及内建的JSP标签、自定义的JSP标签以及表达式语言。session
二、JSP在运行时的处理app
三、JSP指令webapp
JSP指令用来设置整个JSP页面相关的属性,如网页的编码方式和脚本语言。jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
其中language将告诉容器JSP使用的是那种脚本语言,contentType和charset将设置JSP页面的MIME类型和字符编码,
page指令相关的属性:
buffer | 指定out对象使用缓冲区的大小 |
autoFlush | 控制out对象的 缓存区 |
contentType | 指定当前JSP页面的MIME类型和字符编码 |
errorPage | 指定当JSP页面发生异常时须要转向的错误处理页面 |
isErrorPage | 指定当前页面是否能够做为另外一个JSP页面的错误处理页面 |
extends | 指定servlet从哪个类继承 |
import | 导入要使用的Java类 |
info | 定义JSP页面的描述信息 |
isThreadSafe | 指定对JSP页面的访问是否为线程安全 |
language | 定义JSP页面所用的脚本语言,默认是Java |
session | 指定JSP页面是否使用session |
isELIgnored | 指定是否执行EL表达式 |
isScriptingEnabled | 肯定脚本元素可否被使用 |
<%@ include file="文件相对 url 地址" %>
JSP API容许用户自定义标签,一个自定义标签库就是自定义标签的集合。Taglib指令引入一个自定义标签集合的定义,包括库路径、自定义标签。
<%@ taglib uri="uri" prefix="prefixOfTag" %>
四、在JSP中使用Java
jsp中写java代码有以下三种方式:
<%! %>,这里面能够申明变量或方法,注意:这里面申明的变量是全局的
<% %>,与上面的方法相比,这个方法的局部的
<%= %>,用于输出表达式到浏览器,注意:这里面的表达式不能跟分号
JSP文件提供了几个能够在脚本和表达式中可使用的隐式变量,这些变量不须要在任何位置定义便可使用它们,JSP规范要求JSP的转换器和编译器提供这些变量,名字也要彻底相同。从一个编译后的JSP文件中能够看到这样一些代码片断
1 public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response) 2 throws java.io.IOException, javax.servlet.ServletException { 3 4 final javax.servlet.jsp.PageContext pageContext; 5 javax.servlet.http.HttpSession session; 6 final javax.servlet.ServletContext application; 7 final javax.servlet.ServletConfig config; 8 javax.servlet.jsp.JspWriter out = null; 9 final java.lang.Object page = this; 10 javax.servlet.jsp.JspWriter _jspx_out = null; 11 javax.servlet.jsp.PageContext _jspx_page_context = null; 12 13 try { 14 response.setContentType("text/html; charset=UTF-8"); 15 pageContext = _jspxFactory.getPageContext(this, request, response, 16 null, false, 8192, true); 17 _jspx_page_context = pageContext; 18 application = pageContext.getServletContext(); 19 config = pageContext.getServletConfig(); 20 out = pageContext.getOut(); 21 _jspx_out = out; 22 }
这里总共定义了8个隐式变量,分别是:
HttpServletRequest类和HttpServletResponse类的实例
PageContext类的实例,提供对JSP页面全部对象以及命名空间的访问
HttpSession类的实例,若是在page指令中的session特性设置为假那么JSP中就没有这个变量
ServletContext类的实例,与应用上下文有关
ServletConfig类的实例,可使用该对象访问JSP Servlet的配置,例如Servlet初始化参数
JspWriter类的实例,用于把结果输出至网页上
相似于Java类中的this关键字,提供了请求特性和回话特性值、访问请求和响应、包含其余文件、转发请求的几个便利方法
最后还有一个exception这里没有出现,这个变量须要经过page指令的isErrorPage特性设置为真,表示该JSP的目的是用于处理错误,才会出现这个变量。
建立一个first.jsp文件,添加如下的代码
<%@ page language="java" contentType="text/html; charset=UTF-8" %> <%! private static final String DEFAULT_USER = "Guest"; %> <% String user = request.getParameter("user"); if(user == null){ user = DEFAULT_USER; } %> <!DOCTYPE html> <html> <head> <title>first user application</title> </head> <body> hello, <%= user %> ! <br/><br/> <form action="first.jsp" method="post"> 输入用户名:<br/> <input type="text" name="user"/><br/> <input type="submit" value="Submit"/> </form> </body> </html>
编译运行,在浏览器中输入http://localhost:8080/hello-world/first.jsp就能够获得下面这个网页
这里就实现了以前的Servlet,不过其实并不该该在JSP中使用Java
五、注释
在JSP中实现代码注释的方法有四种:
<!-- 这是被注释的内容 -->
可是这种类型的注释将被发送到客户端,浏览器将会忽略它,可是它会出如今响应的源代码中注释中的任何JSP代码都将会被处理,
<!-- 这是被注释的内容<%!private static final String DEFAULT_USER = "Guest";%> -->
这里的java代码就将会被执行。
<% String user = request.getParameter("user"); // if(user == null){ // user = DEFAULT_USER; // } /* String pwd = req.getParameter("pwd"); String sex = req.getParameter("sex"); */ %>
<%-- JSP注释掉的内容 --%>
六、结合使用Servlet和JSP
在空的web.xml文件(只包含<display-name>)中,添加如下内容:
<jsp-config> <jsp-property-group> <url-pattern>*.jsp</url-pattern> <url-pattern>*.jspf</url-pattern> <page-encoding>UTF-8</page-encoding> <scripting-invalid>false</scripting-invalid> <include-prelude>/WEB-INF/jsp/base.jspf</include-prelude> <trim-directive-whitespaces>true</trim-directive-whitespaces> <default-content-type>text/html</default-content-type> </jsp-property-group> </jsp-config>
标签<jsp-config>中能够包含任意数目的</jsp-property-group>标签,这个属性用于区分不一样JSP组的属性。例如为/WEB-ING/JSP/admin文件夹中全部的JSP定义一组通用的属性,为/WEB-ING/JSP/help定义另外一组属性,那么须要经过定义<url-pattern>标签来区分不一样的属性组,其中一个被设置为<url-pattern>/WEB-ING/JSP/admin/*.jsp</url-pattern>,另外一个则被设置为<url-pattern>/WEB-ING/JSP/help/*.jsp</url-pattern>。
<include-prelude>标签将告诉容器在全部属于该属性组中的JSP的头部添加文件/WEB-INF/jsp/base.jspf,能够用于定义公共变量、标签库声明或共享其余可做用于属性组全部的JSP资源。相似的<include-coda>标签订义了包含在组中全部JSP尾部的文件。在一个JSP组中能够同时屡次使用这些标签。
<page-encoding>与page指令的pageEncoding特性一致,由于JSP的默认内容类型为text/html,因此只须要经过<page-encoding>将字符编码设置为UTF-8便可。还可使用<default-content-type>标签以其余默认的内容类型覆盖text/html。
<trim-directive-whitespaces>标签告诉JSP转换器删除响应输出中的空白,只保留由指令、声明、脚本和其余JSP标签建立的文本。
<scripting-invalid>标签设置为假时:容许在组中的全部JSP中使用Java。若是把这个设置为真,在组中使用Java将引发转换错误。标签<el-ignored>的做用相似,不过它对应的是page指令中的isELIgnored特性。若是它的值为真,那么组内的JSP将禁止使用表达式语言。它的默认值一样为假。
<%@ page import="model.Ticket, model.Ticket" %> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
以上是base.jspf的内容,该代码完成了两件事情:为全部的JSP导入这些类,并声明JSPL核心代码库。
这是webapp的文件结构,将文件添加到WEB-INF下能够阻止用户经过浏览器访问这些JSP,由于WEB-INF目录中的文件是禁止经过Web访问的。依赖于由重定向Servlet和JSP提供的回话和请求特性的JSP均可以添加到WEB-INF中。
先写一个简单的jsp:
<%@ page session="false" %> <!DOCTYPE html> <html> <head> <title>Customer Support</title> </head> <body> <h2>Create a Ticket</h2> <form method="POST" action="tickets" enctype="multipart/form-data"> <input type="hidden" name="action" value="create"/> Your Name<br/> <input type="text" name="customerName"><br/><br/> Subject<br/> <input type="text" name="subject"><br/><br/> Body<br/> <textarea name="body" rows="5" cols="30"></textarea><br/><br/> <b>Attachments</b><br/> <input type="file" name="file1"/><br/><br/> <input type="submit" value="Submit"/> </form> </body> </html>
而后建立一个简单的Servlet在加上代码:
@WebServlet(
name = "TestServlet",
urlPatterns = {"/test"}
)
public class TestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/WEB-INF/jsp/view/ticketForm.jsp")
.forward(request, response);
}
}
而后在使用浏览器访问http://localhost:8080/hello-world/test时就是在访问这个JSP了