一、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("\r\n");
out.write("\r\n");
out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n");
out.write("<html>\r\n");
out.write(" <head>\r\n");
out.write(" <title>test</title>\r\n");
out.write(" </head>\r\n");
out.write(" <body>\r\n");
out.write(" \r\n");
out.write(" \t");
out.write("\r\n");
out.write("\r\n");
out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n");
out.write("<html>\r\n");
out.write(" <head>\r\n");
out.write(" <title>My JSP 'head.jsp' starting page</title>\r\n");
out.write(" </head>\r\n");
out.write(" \r\n");
out.write(" <body>\r\n");
out.write(" \r\n");
out.write(" <h1><font color=\"red\">这是网页首部</font> </h1>\r\n");
out.write(" \r\n");
out.write("\r\n");
out.write(" \t<h1><font color=\"black\">这是网页内容</font> </h1>\r\n");
out.write(" ");
out.write("\r\n");
out.write("\r\n");
out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n");
out.write("<html>\r\n");
out.write(" <head>\r\n");
out.write(" <title>My JSP 'head.jsp' starting page</title>\r\n");
out.write(" </head>\r\n");
out.write(" \r\n");
out.write(" <body>\r\n");
out.write(" \r\n");
out.write(" <h1><font color=\"blue\">这是网页尾部</font> </h1>\r\n");
out.write(" \r\n");
out.write(" </body>\r\n");
out.write("</html>\r\n");
out.write("\r\n");
out.write(" </body>\r\n");
out.write("</html>\r\n");
} 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("\r\n");
out.write("\r\n");
out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n");
out.write("<html>\r\n");
out.write(" <head>\r\n");
out.write(" <title>test</title>\r\n");
out.write(" </head>\r\n");
out.write(" <body>\r\n");
out.write(" \r\n");
out.write(" \t");
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "/head.jsp", out, false);
out.write("\r\n");
out.write(" \t<h1><font color=\"black\">这是网页内容...</font> </h1>\r\n");
out.write(" \t");
org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "/foot.jsp", out, false);
out.write("\r\n");
out.write(" </body>\r\n");
out.write("</html>\r\n");
} 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