JSP页面九大内置对象:request 、response 、session、 application 、out 、pageContext 、config、 page、exception。
注:
1. 九大内置对象中,有四个是域对象。
2. page对象指的就是当前JSP页面,而JSP页面经过编译就变成了servlet(JSP的本质就是servlet),page在JSP页面中的作用就类似于this在servlet类中的作用。这个对象使用较少,只需了解。
JSP页面四大域对象:pageContext(当前页面有效)、 request(当前请求有效)、 session(当前会话有效)、 application(当前网站或当前Web应用)。
下面介绍一下四大域对象:
1. application 服务器开启产生,服务器关闭销毁。保存在服务器端,不同客户端共用一个application。
注:application的父类是javax.servlet.ServletContext,application是servletContext在JSP页面层次的封装,两者可以看作是同一个对象。通过 application.setAttribute() 方法设置的值,可以通过 servletContext.getAttribute() 获取。通过servletContext.setAttribute() 设置的值可以通过 application.getAttribute() 获取。application使用在JSP页面,servletContext使用在servlet中。servletContext也是和application一样,同一个Web应用共享一个servletContext。
2. session 某一客户端第一次请求服务器时产生,超过生效时间销毁。保存在服务器端,每一个客户端都有单独的session供自己使用。
session和cookie交流过程:
<1> 客户端第一次发送request请求给服务器的时候,服务器创建一个服务于此客户端的Session,并分配SessionId
<2>SessionId随response传递回客户端,并存储在cookie中。
<3>客户端再发送request请求给服务器的时候,request请求中包含cookie信息,服务器提取cookie中的SessionId。
<4>服务器通过此SessionId找到此客户端对应的session对象,并认为该session对象活跃了一次。
<5>从现在到上次"活跃时间"的时间长度超过了session的失效时间,服务器删除此session对象。
注:客户端的cookie和服务器端的session是一一对应的,客户端的request请求中会携带cookie,通过cookie中的SessionId找到属于本客户端的session。在客户端第一次发送request请求时,cookie中是不包含SessionId的。
session的使用:
前后端传值:可以通过在JSP页面中使用session.setAttribute()方法,在servlet中使用session.getAttribute()方法进行;
或者在servlet中使用session.setAttribute()方法,在JSP中使用session.getAttribute()方法进行前后端传值。
3. request
前后端传值:
1. 在JSP页面通过可以通过在JSP页面中使用request.setAttribute()方法,在servlet中使用request.getAttribute()方法实现从前端到后台的传值。
2. 在servlet中使用request.setAttribute()方法,在JSP中使用request.getAttribute()进行前后端传值需要注意两点:
① 不能使用重定向:response.sendRedirect(); 因为重定向后只返回了response,没有返回request,所以前端是取不到servlet中使用request.setAttribute()设置的值得。
② 需要使用下面的方法,这样可以将request也返回给JSP页面。
RequestDispatcher dispatcher = request.getRequestDispatcher("");
dispatcher.forward(request, response);
附:
Web服务器:如Apache,负责解析静态页面。对于servlet请求,Web服务器是解析不了的,它只能解析静态页面,无法解析java代码。
Servlet容器:如Tomcat ,servlet容器指的是提供了servlet功能的服务器,响应servlet请求。servlet容器在接收到servlet请求的时候,创建一个HttpServletResponse(用于封装响应信息)和HttpServletRequest(用于封装请求信息)。
4. pageContext (功能强大,但使用较少)
几点说明:
1. pageContext提供了对其他八个内置对象的获取方法。
2. pageContext域代表了当前页面的运行环境。
3. .setAttribute(String name,Object value,int scope)方法和 .getAttribute(String name,Object value,int scope)方法。方法中的第三个参数scope指定的是当前设置或者获取的参数所属于的作用域(pageContext,request,session,application)即四大域对象。参数值分别是:pageContext.PAGE_SCOPE 、pageContext.REQUEST_SCOPE 、pageContext.SESSION_SCOPE 、pageContext.APPLICATION_SCOPE 。也就是说,通过pageContext的setAttribute()和getAttribute()方法,可以给其他域对象赋予属性。
注:pageContext虽然功能强大,但是因为功能太多,没办法分门别类,导致它对于功能区分不明确,影响代码可读性,所以很少使用。
5. EL表达式:为了更方便的获取servlet域对象中存储的数据。
(JSP经过编译最终变成了servlet,所以域对象实质是对servlet的。)
1. 基本格式:${ }
2. 关键点:对于EL表达式,最重要的一点,就是要明白,EL表达式中变量的值从何而来,或者说这个变量代表着什么。
实际上,EL表达式中的变量代表的实,依次访问次序为:pageContext、际上是四大域对象的属性request、session、application。
<body>
<%
//这是一个javabean,或者称实体类,
User user = new User();
%>
<!-- 判断user是不是null -->
${user==null}
<br>
<%
User user2 = new User();
//将user2对象放到session里面,属性名为elUser,值为user2这个对象
session.setAttribute("elUser", user2);
%>
<!-- 判断elUser是不是null -->
${elUser==null}
</body>
输出为:
true
false
这表明user这个变量是不存在的,elUser这个变量是存在的。因为user这个对象并不属于四大域对象中的任何一个对象的属性,而elUser属于session的属性。
现在${ elUser }就等价于session.getAttribute("elUser");
6. Filter(过滤器)
1. Filter映射 (在web.xml中的配置信息)
举个例子说明:
(例子中包含了几种映射方法,附有详细的注释说明)
<filter>
<display-name>TestFilter</display-name>
<filter-name>TestFilter</filter-name>
<filter-class>sdut.shop.filter.TestFilter</filter-class>
</filter>
<!--
说明:增加一个index.jsp的映射,当页面访问WebRoot下的index.jsp时会转到这个TestFilter。
如:http://localhost:8080/shopping/index.jsp
注:shopping是你的项目名称。
-->
<filter-mapping>
<filter-name>TestFilter</filter-name>
<url-pattern>/index.jsp</url-pattern>
</filter-mapping>
<!--
说明:增加一个/page/index/index.jsp的映射,当页面访问WebRoot下page文件夹中的index文件夹中的index.jsp时会转到这个TestFilter。
如:http://localhost:8080/shopping/page/index/index.jsp
注:shopping是你的项目名称。
-->
<filter-mapping>
<filter-name>TestFilter</filter-name>
<url-pattern>/page/index/index.jsp</url-pattern>
</filter-mapping>
<!--
说明:增加一个/goodsData的映射,当页面访问goodsData这个路径对应的servlet时,会调用这个TestFilter
如:http://localhost:8080/shopping/goodsData
http://localhost:8080/shopping/goodsData?type=select
http://localhost:8080/shopping/goodsData?type=select&value=1
注:1. 无论goodsData后面是否有参数都会进入这个TestFilter
2. shopping是你的项目名称
-->
<filter-mapping>
<filter-name>TestFilter</filter-name>
<url-pattern>/goodsData</url-pattern>
</filter-mapping>
<!--
说明:这其中的login.jsp跳转必须是从servlet中被触发的,从浏览器中直接输入是不行的。
错误示范如:http://localhost:8080/shopping/login.jsp (是不可以的,是错误的)
正确示范如:http://localhost:8080/shopping/loginServlet 然后从loginServlet这个映射对应的servlet中使用重定向,或者RequestDispatcher的forward或者include:
request.getRequestDispatcher(request.getContextPath()+"/login.jsp").include(request, response);
response.sendRedirect(request.getContextPath()+"/login.jsp");
这种方式是可行的,是正确的
注: 1.shopping是你的项目名称
2.是从servlet中进行跳转的那些请求
3.是从servlet中进行跳转的那些请求
3.是从servlet中进行跳转的那些请求 重要的问题说三遍
-->
<filter-mapping>
<filter-name>TestFilter</filter-name>
<url-pattern>/login.jsp</url-pattern>
<dispatcher>REQUEST</dispatcher> <!--接受直接的request请求,如:重定向 -->
<dispatcher>FORWARD</dispatcher> <!--接受上面说的forward请求 -->
<dispatcher>INCLUDE</dispatcher> <!--接受上面说的include请求 -->
</filter-mapping>
<!--
说明:增加一个到ShopCartServlet这个servlet的映射,当页面访问ShopCartServlet这个servlet对应的所有映射的时候会调用这个TestFilter。
假设ShopCartServlet这个servlet有以下这个映射的话。
<servlet-mapping>
<servlet-name>ShopCartServlet</servlet-name>
<url-pattern>/ShopCartData</url-pattern>
</servlet-mapping>
如:http://localhost:8080/shopping/ShopCartData 就会被拦截
http://localhost:8080/shopping/ShopCartData?type=0000 就会被拦截
注:1. 无论ShopCartServlet对应的映射后面是否有参数都会进入这个TestFilter
2. shopping是你的项目名称
3. servlet对应的所有映射都会包含到这个Filter
-->
<filter-mapping>
<filter-name>TestFilter</filter-name>
<servlet-name>ShopCarServlet</servlet-name> <!--对应的servlet的名字-->
</filter-mapping>