你一定在你的Jsp文件中的监本片段中使用过以下九个对象的几种:out、config、page、pageContext、exception、request、response、application、session。就像下面这样:
<html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <!-- Jsp脚本片段:用来在里面写Java代码--> <% for(int i=0;i<10;i++){ out.print(i); } %> <!-- JSP表达式 :用来想浏览器输出对象--> <%="I'm JSP expression" %> <!-- JSP九大隐含对象 --> <h1>欢迎你,<%=request.getParameter("username") %></h1> </body> </html>
上面这段标签中的脚本片段中使用了out对象,但这个out对象是怎么来的呢?上一篇关于Jsp底层原理中我们介绍过,Tomcat会为每一个jsp文件产生相应的的servlet,也就是在这个servlet类中,帮我们创建了这久个隐藏对象,其中的exception比较特别,只有在Jsp文件中指定了isErrorPage=“true”时,Tomcat才会为此jsp创建带有exception对象的servlet类。
虽然在jsp文件中显示的使用了隐藏对象,但实际上使用却在对应的Servlet类中,所以所有的jsp文件中的隐藏对象都是有据可循的。在这九个对象中,有四个比较特殊,也比较重要,他们被称为域对象。
分别是:page、request、session、application。下面介绍四者的区别:<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <!-- 四个域: page域 范围:当前页面 对应的域对象:pageContext 域对象的类型:PageContext request域 范围:当前请求(一次请求) 对应的域对象:request 域对象的类型:HttpServletRequest session域 范围:当前会话(一次会话) 对应的域对象:session 域对象的类型:HttpSession application域 范围:当前Web应用 对应的域对象:application 域对象的类型:ServletContext 四个域对象都以下三个方法: void setAttribute(String key , Object value) Object getAttribute(String key) void removeAttribute(String key) 四个域对象的使用规则: 能用小的就不用大的 --> <!-- 在当前页面分别向四个域中添加四个属性 --> <% pageContext.setAttribute("pageKey", "pageValue"); request.setAttribute("reqKey", "reqValue"); session.setAttribute("sessKey", "sessValue"); application.setAttribute("appKey", "appValue"); %> <h1>在当前页面中获取四个域中的属性值</h1> page域中的属性值是:<%=pageContext.getAttribute("pageKey") %><br> request域中的属性值是:<%=request.getAttribute("reqKey") %><br> session域中的属性值是:<%=session.getAttribute("sessKey") %><br> application域中的属性值是:<%=application.getAttribute("appKey") %><br> <!-- 转发到scope2.jsp页面 --> <%-- <jsp:forward page="/scope2.jsp"></jsp:forward> --%>
<a href="/Web_JSP/scope2.jsp">去scope2.jsp页面</a> </body> </html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <h1>在scope2.jsp页面中获取四个域中的属性值</h1> page域中的属性值是:<%=pageContext.getAttribute("pageKey") %><br> request域中的属性值是:<%=request.getAttribute("reqKey") %><br> session域中的属性值是:<%=session.getAttribute("sessKey") %><br> application域中的属性值是:<%=application.getAttribute("appKey") %><br> </body> </html>
在上面这个页面中,分别向四个域对象中设置了值,打开页面后会发现本页面的四个域对象的都能取出来相应的value,而通过本页面转发的页面不能取出pagevalue,原因就是page域的作用范围仅仅在本页面中,别的页面是无法获取本页面page域对象的值的。而如果将转发改为跳转(重定向也是跳转的一种),即重新向服务器发送一次请求,会发现第二个请求的页面pagevalue和reqValue都取不出来,pagevalue的值取不出来是因为其所在的page域对象因为页面已经跳转而失效,reqValue值悟不出来的原因是request域对象的作用域仅限于一次请求,上面之所以能在第二个页面中获取到热情Value,是因为虽然页面跳转了,但跳转的方式是“转发”,所以本质上还是一个请求。如果此时重启浏览器并输入二号页面的URL直接访问二号页面,就只能获取到application的值了,原因就是session的作用域仅限于一个会话,重启浏览器以后再次访问就是一个新的会话了,上一次会话的域对象就失效了。而如果重启服务器后,再访问二号页面,四个值都将无法获得,四个域对象都失效了。