一、JSP域对象
1.JSP属性范围(域对象范围)
JSP提供了四个域对象,分别是pageContext、request、session、application。
pageContext: 属性范围仅限于当前JSP页面。一个属性只能在一个页面取得,跳转到其他页面无法取得。
request: 属性作用范围仅限于同一个请求。一个页面中设置的属性,只要经过了服务器的跳转,跳转之后的页面都可以继续取得。
session: 存储在session对象中的属性可以被属于同一个会话的所有Servlet和JSP页面访问。浏览器打开到关闭称作一次会话。
application: 存储在application对象中的属性可以被同一个Web应用程序的所有Servlet和JSP页面访问。
2.域对象的相关方法
(1)setAttribute()
设置属性的方法。之前所讲解的四种属性范围,实际上都是通过pageContext属性范围设置上的。打开pageContext所在的说明文档。
PageContext类继承了JspContext类,在JspContext类中定义了setAttribute方法,如下:
此方法中存在一个scope的整型变量,此变量就表示一个属性的保存范围。
后面有一个int类型的变量,在PageContext中可以发现有4种。
public static final int PAGE_SCOPE = 1; public static final int REQUEST_SCOPE = 2; public static final int SESSION_SCOPE = 3; public static final int APPLICATION_SCOPE = 4;
这个setAttribute()方法如果不写后面的int类型的scope参数,则此参数默认为PAGE_SCOPE,则此时setAttribute()方法设置的就是page属性范围,如果传递过来的int类型参数scope为REQUEST_SCOPE,则此时setAttribute()方法设置的就是request属性范围,同理,传递的scope参数为SESSION_SCOPE和APPLICATION_SCOPE时,则表示setAttribute()方法设置的就是session属性范围和application属性范围。
(2)getAttribute(String name)
获取指定的属性。
(3)getAttributeNames()
获取所有属性名字组成的Enumeration对象。
(2)removeAttribute(String name)
移除指定的属性。
二、请求转发和重定向
1.用法
<html> <head> <title>My JSP 'hello.jsp' starting page</title> </head> <body> <form action="ForwardServlet"> 年龄: <input type="text" name="age"><br> <input type="submit" value="提交"> </form> </body> </html>
ForwardServlet.java
public class ForwardServlet extends HttpServlet{ public void doGet(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException{ String age = req.getParameter("age"); System.out.println("ForwardServlet: age = " + age); //请求的转发 //1.调用HttpServletRequest的getRequestDispatcher()方法获取RequestDispatcher对象。 String path = "TestServlet"; RequestDispatcher dispatcher = req.getRequestDispatcher("/" + path); //2.调用RequestDispatcher对象的forward()方法 dispatcher.forward(req,resp); } public void doPost(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException{ doGet(req,resp); } }
TestServlet.java
public class TestServlet extends HttpServlet{ public void doGet(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException{ String age = req.getParameter("age"); System.out.println("TestServlet: age = " + age); } public void doPost(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException{ doGet(req,resp); } }
结果:
ForwardServlet: age = 123
TestServlet: age = 123
如果把ForwardServlet内部重定向到TestServlet。
public class ForwardServlet extends HttpServlet{ public void doGet(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException{ String age = req.getParameter("age"); System.out.println("ForwardServletage = " + age); //请求的重定向 String path = "TestServlet"; resp.sendRedirect(path); } public void doPost(HttpServletRequest req,HttpServletResponse resp) throws ServletException,IOException{ doGet(req,resp); } }
结果:
ForwardServletage = 23
TestServlet: age = null
sendRedirect 方法不仅可以重定向到当前应用程序中的其他资源,它还可以重定向到同一个站点上的其他应用程序中的资源,甚至是使用绝对URL重定向到其他站点的资源。
如果传递给sendRedirect 方法的相对URL以“/”开头,则是相对于整个WEB站点的根目录,而不是相对于当前WEB应用程序的根目录。
2.区别
(1)请求转发:只向服务器发出一次请求。重定向: 向服务器发两次请求。
(2)请求转发: 调用者与被调用者之间共享相同的request对象。重定向: 调用者与被调用者使用各自的request和response对象,它们属于两个独立的请求和响应过程。
(3)请求转发:地址栏是初次发出请求的地址。重定向:地址栏不再是初次发送的请求地址,地址栏是最后响应的地址。
(4)请求转发: 只能将请求转发给同一个WEB应用中的组件。重定向: 可以重定向到同一个站点上的其他应用程序中的资源,甚至是使用绝对URL重定向到其他站点的资源。
(5)如果请求转发的相对URL以“/”开头,它是相对于整个WEB站点的根目录;如果重定向指定的相对URL以“/”开头,它是相对于当前WEB应用程序的根目录。
三、JSP指令
JSP指令的基本语法格式: <%@ 指令 属性名=属性值 %>
eg: <%@ page contentType="text/html;charset=gb2312"%>
在目前JSP中,定义了page、include、taglib这三种指令,每种指令有都定义了一些各自的属性。
如果要在一个JSP页面设置同一条指令的多个属性,可以使用多条指令语句单独设置每个属性,也可以使用同一条语句设置该指令。
第一种方式:
<%@ page contentType="text/html;charset=gb2312"%> <%@ page import="java.util.Date"%>
第二种方式:
<%@ page contentType="text/html;charset=gb2312" import="java.util.Date"%>
1.Page指令
JSP 2.0规范中定义的page指令的完整语法:
<%@ page [ language="java" ] [ extends="package.class" ] [ import="{package.class | package.*}, ..." ] [ session="true | false" ] [ buffer="none | 8kb | sizekb" ] [ autoFlush="true | false" ] [ isThreadSafe="true | false" ] [ info="text" ] [ errorPage="relative_url" ] [ isErrorPage="true | false" ] [ contentType="mimeType [ ;charset=characterSet ]" | "text/html ; charset=ISO-8859-1" ] [ pageEncoding="characterSet | ISO-8859-1" ] [ isELIgnored="true | false" ] %>
(1)使用errorPage属性指明出错后跳转的错误页面
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <%@ page errorPage="/error.jsp" %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>测试page指令的errorPage属性</title> </head> <body> <% //这行代码肯定会出错,因为除数是0,一运行就会抛出异常 int x = 1 / 0; %> </body> </html>
error.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>My JSP 'error.jsp' starting page</title> </head> <body> <h1><font color="red">对不起,出错了!!!</font></h1> </body> </html>
结果:
(2)在web.xml使用<error-page>标签为整个web应用设置错误处理页面
- 可以在web.xml文件中使用<error-page>元素为整个Web应用程序设置错误处理页面。
- <error-page>元素有3个子元素,<error-code>、<exception-type>、<location>
- <error-code>: 指定错误的状态码,例如:<error-code>404</error-code>
- <exception-type>: 指定异常类的完全限定名,例如:<exception-type>java.lang.ArithmeticException</exception-type>
- <location>: 指定以“/”开头的错误处理页面的路径,例如:<location>/ErrorPage/404Error.jsp</location>
- 如果设置了某个JSP页面的errorPage属性,那么在web.xml文件中设置的错误处理将不对该页面起作用。
web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <display-name></display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <!-- 针对404错误处理页面 --> <error-page> <error-code>404</error-code> <location>/error404.jsp</location> </error-page> </web-app>
error404.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>My JSP 'error.jsp' starting page</title> </head> <body> <h1><font color="red">各位看官,404哟</font></h1> </body> </html>
当访问一个不存在的web资源时,就会跳转到在web.xml中配置的404错误处理页面
2.include指令
语法: <%@ include file="相对URL"%>。路径以"/"开头,代表当前Web应用。
include指令用于引入其它JSP页面,如果使用include指令引入了其它JSP页面,那么JSP引擎将把这两个JSP翻译成一个servlet。所以include指令引入通常也称之为静态引入。
include指令细节注意问题:
(1)被引入的文件必须遵循JSP语法。
(2)被引入的文件可以使用任意的扩展名,即使其扩展名是html,JSP引擎也会按照处理jsp页面的方式处理它里面的内容,为了见明知意,JSP规范建议使用.jspf(JSP fragments(片段))作为静态引入文件的扩展名。
(3)由于使用include指令将会涉及到2个JSP页面,并会把2个JSP翻译成一个servlet,所以这2个JSP页面的指令不能冲突(除了pageEncoding和导包除外)。
head.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>My JSP 'head.jsp' starting page</title> </head> <body> <h1><font color="red">这是网页首部</font> </h1> </body> </html>
foot.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>My JSP 'head.jsp' starting page</title> </head> <body> <h1><font color="blue">这是网页尾部</font> </h1> </body> </html>
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>test</title> </head> <body> <%@ include file="/head.jsp" %> <h1><font color="black">这是网页内容</font> </h1> <%@ include file="/foot.jsp" %> </body> </html>
结果:
public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent, org.apache.jasper.runtime.JspSourceImports { private static final javax.servlet.jsp.JspFactory _jspxFactory = javax.servlet.jsp.JspFactory.getDefaultFactory(); private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants; static { _jspx_dependants = new java.util.HashMap<java.lang.String,java.lang.Long>(2); _jspx_dependants.put("/head.jsp", Long.valueOf(1460347479277L)); _jspx_dependants.put("/foot.jsp", Long.valueOf(1460347481392L)); } private static final java.util.Set<java.lang.String> _jspx_imports_packages; private static final java.util.Set<java.lang.String> _jspx_imports_classes; static { _jspx_imports_packages = new java.util.HashSet<>(); _jspx_imports_packages.add("javax.servlet"); _jspx_imports_packages.add("java.util"); _jspx_imports_packages.add("javax.servlet.http"); _jspx_imports_packages.add("javax.servlet.jsp"); _jspx_imports_classes = null; } private volatile javax.el.ExpressionFactory _el_expressionfactory; private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager; public java.util.Map<java.lang.String,java.lang.Long> getDependants() { return _jspx_dependants; } public java.util.Set<java.lang.String> getPackageImports() { return _jspx_imports_packages; } public java.util.Set<java.lang.String> getClassImports() { return _jspx_imports_classes; } public javax.el.ExpressionFactory _jsp_getExpressionFactory() { if (_el_expressionfactory == null) { synchronized (this) { if (_el_expressionfactory == null) { _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory(); } } } return _el_expressionfactory; } public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() { if (_jsp_instancemanager == null) { synchronized (this) { if (_jsp_instancemanager == null) { _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig()); } } } return _jsp_instancemanager; } public void _jspInit() { } public void _jspDestroy() { } public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response) throws java.io.IOException, javax.servlet.ServletException { final java.lang.String _jspx_method = request.getMethod(); if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) { response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET POST or HEAD"); return; } final javax.servlet.jsp.PageContext pageContext; javax.servlet.http.HttpSession session = null; final javax.servlet.ServletContext application; final javax.servlet.ServletConfig config; javax.servlet.jsp.JspWriter out = null; final java.lang.Object page = this; javax.servlet.jsp.JspWriter _jspx_out = null; javax.servlet.jsp.PageContext _jspx_page_context = null; try { response.setContentType("text/html;charset=UTF-8"); pageContext = _jspxFactory.getPageContext(this, request, response, null, true, 8192, true); _jspx_page_context = pageContext; application = pageContext.getServletContext(); config = pageContext.getServletConfig(); session = pageContext.getSession(); out = pageContext.getOut(); _jspx_out = out; out.write(" "); out.write(" "); out.write("<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> "); out.write("<html> "); out.write(" <head> "); out.write(" <title>test</title> "); out.write(" </head> "); out.write(" <body> "); out.write(" "); out.write(" "); out.write(" "); out.write(" "); out.write("<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> "); out.write("<html> "); out.write(" <head> "); out.write(" <title>My JSP 'head.jsp' starting page</title> "); out.write(" </head> "); out.write(" "); out.write(" <body> "); out.write(" "); out.write(" <h1><font color="red">这是网页首部</font> </h1> "); out.write(" "); out.write(" "); out.write(" <h1><font color="black">这是网页内容</font> </h1> "); out.write(" "); out.write(" "); out.write(" "); out.write("<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> "); out.write("<html> "); out.write(" <head> "); out.write(" <title>My JSP 'head.jsp' starting page</title> "); out.write(" </head> "); out.write(" "); out.write(" <body> "); out.write(" "); out.write(" <h1><font color="blue">这是网页尾部</font> </h1> "); out.write(" "); out.write(" </body> "); out.write("</html> "); out.write(" "); out.write(" </body> "); out.write("</html> "); } catch (java.lang.Throwable t) { if (!(t instanceof javax.servlet.jsp.SkipPageException)){ out = _jspx_out; if (out != null && out.getBufferSize() != 0) try { if (response.isCommitted()) { out.flush(); } else { out.clearBuffer(); } } catch (java.io.IOException e) {} if (_jspx_page_context != null) _jspx_page_context.handlePageException(t); else throw new ServletException(t); } } finally { _jspxFactory.releasePageContext(_jspx_page_context); } } }
四、JSP标签
JSP的常用标签有三个: <jsp:include>、<jsp:forward>、<jsp:param>。
1.<jsp:include>标签
<jsp:include>标签用于把另外一个资源的输出内容插入进当前JSP页面的输出内容之中,这种在JSP页面执行时的引入方式称之为动态引入。
语法:<jsp:include page="relativeURL | <%=expression%>" flush="true|false" />
page属性用于指定被引入资源的相对路径,它也可以通过执行一个表达式来获得。
flush属性指定在插入其他资源的输出内容时,是否先将当前JSP页面的已输出的内容刷新到客户端。
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>test</title> </head> <body> <jsp:include page="/head.jsp"/> <h1><font color="black">这是网页内容...</font> </h1> <jsp:include page="/foot.jsp"/> </body> </html>
结果:
注意:
这种动态包含并不像include指令生产一个Servlet源文件,而是生成两个Servlet源文件,然后通过一个方法的方式把目标页面包含起来。
public final class index_jsp extends org.apache.jasper.runtime.HttpJspBase implements org.apache.jasper.runtime.JspSourceDependent, org.apache.jasper.runtime.JspSourceImports { private static final javax.servlet.jsp.JspFactory _jspxFactory = javax.servlet.jsp.JspFactory.getDefaultFactory(); private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants; private static final java.util.Set<java.lang.String> _jspx_imports_packages; private static final java.util.Set<java.lang.String> _jspx_imports_classes; static { _jspx_imports_packages = new java.util.HashSet<>(); _jspx_imports_packages.add("javax.servlet"); _jspx_imports_packages.add("java.util"); _jspx_imports_packages.add("javax.servlet.http"); _jspx_imports_packages.add("javax.servlet.jsp"); _jspx_imports_classes = null; } private volatile javax.el.ExpressionFactory _el_expressionfactory; private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager; public java.util.Map<java.lang.String,java.lang.Long> getDependants() { return _jspx_dependants; } public java.util.Set<java.lang.String> getPackageImports() { return _jspx_imports_packages; } public java.util.Set<java.lang.String> getClassImports() { return _jspx_imports_classes; } public javax.el.ExpressionFactory _jsp_getExpressionFactory() { if (_el_expressionfactory == null) { synchronized (this) { if (_el_expressionfactory == null) { _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory(); } } } return _el_expressionfactory; } public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() { if (_jsp_instancemanager == null) { synchronized (this) { if (_jsp_instancemanager == null) { _jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig()); } } } return _jsp_instancemanager; } public void _jspInit() { } public void _jspDestroy() { } public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response) throws java.io.IOException, javax.servlet.ServletException { final java.lang.String _jspx_method = request.getMethod(); if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method) && !javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) { response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSPs only permit GET POST or HEAD"); return; } final javax.servlet.jsp.PageContext pageContext; javax.servlet.http.HttpSession session = null; final javax.servlet.ServletContext application; final javax.servlet.ServletConfig config; javax.servlet.jsp.JspWriter out = null; final java.lang.Object page = this; javax.servlet.jsp.JspWriter _jspx_out = null; javax.servlet.jsp.PageContext _jspx_page_context = null; try { response.setContentType("text/html;charset=UTF-8"); pageContext = _jspxFactory.getPageContext(this, request, response, null, true, 8192, true); _jspx_page_context = pageContext; application = pageContext.getServletContext(); config = pageContext.getServletConfig(); session = pageContext.getSession(); out = pageContext.getOut(); _jspx_out = out; out.write(" "); out.write(" "); out.write("<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> "); out.write("<html> "); out.write(" <head> "); out.write(" <title>test</title> "); out.write(" </head> "); out.write(" <body> "); out.write(" "); out.write(" "); org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "/head.jsp", out, false); out.write(" "); out.write(" <h1><font color="black">这是网页内容...</font> </h1> "); out.write(" "); org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "/foot.jsp", out, false); out.write(" "); out.write(" </body> "); out.write("</html> "); } catch (java.lang.Throwable t) { if (!(t instanceof javax.servlet.jsp.SkipPageException)){ out = _jspx_out; if (out != null && out.getBufferSize() != 0) try { if (response.isCommitted()) { out.flush(); } else { out.clearBuffer(); } } catch (java.io.IOException e) {} if (_jspx_page_context != null) _jspx_page_context.handlePageException(t); else throw new ServletException(t); } } finally { _jspxFactory.releasePageContext(_jspx_page_context); } } }
2.<jsp:forward>标签
<jsp:forward>: 用于把请求转发给另外一个资源。
语法:<jsp:forward page="relativeURL | <%=expression%>" />
page属性用于指定请求转发到的资源的相对路径,它也可以通过执行一个表达式来获得。
3.<jsp:param>标签
当使用<jsp:include>和<jsp:forward>标签引入或将请求转发给其它资源时,可以使用<jsp:param>标签向这个资源传递参数。
语法1:
<jsp:include page="relativeURL | <%=expression%>"> <jsp:param name="parameterName" value="parameterValue|<%= expression %>" /> </jsp:include>
语法2:
< jsp:forward page="relativeURL | <%=expression%>"> <jsp:param name="parameterName" value="parameterValue|<%= expression %>" /> </jsp:forward >
<jsp:param>标签的name属性用于指定参数名,value属性用于指定参数值。在<jsp:include>和<jsp:forward>标签中可以使用多个<jsp:param>标签来传递多个参数。
tempHTML