本帖最后由 li745547 于 2018-3-25 13:32 编辑
5. JSP运行原理和9大隐式对象 由上文可知:每个JSP页面在第一次被访问时,web容器都会把请求交给JSP引擎(即一个java程序)去处理。JSP引擎现将JSP翻译成一个_jspServlet(实质上也是一个Servlet),然后按照Servlet的调用方式进行调用。由于JSP第一次访问时会翻译成Servlet,所以第一次访问通常会比较慢,但第二次访问,JSP引擎如果发现JSP没有变化,就不再翻译,而是直接调用,所以程序的执行效率不会受到影响。
JSP引擎在调用JSP对应的_jspServlet时,会传递或创建9个与web开发相关的对象供_jspServlet使用。JSP技术的设计者为便于开发人员在编写JSP页面时获得这些web对象的引用,特意定义了9个相应的变量,开发人员在JSP页面中通过这些变量就可以快速获得这9大对象的引用,9大隐式对象是哪些以及各自的作用是什么?
[java] view plain copy
- request://就是Servlet里的request
- response: //就是Servlet里的response
- session: //就是Servlet里的session
- application: //就是servlet里的servletContext
- config: //就是Servlet里的servletConfig
- page: //就是Servlet自己
- exception: //异常,只有errorPage才有
- out://JSP页面输出
- pageContext:<span style="font-family:Microsoft YaHei;">//</span>pageContext对象是JSP技术中最重要的一个对象,它代表JSP页面的运行环境
pageContext对象是JSP技术中最重要的一个对象,它代表JSP页面的运行环境,这个对象不仅封装了对其它8大隐式对象的引用,它自身还是一个域对象,可以用来保存数据。并且,这个对象还封装了web开发中经常涉及到的一些常用操作,例如引入和跳转其它资源、检索其它域对象中的属性等。
[java] view plain copy
- getException<span style="font-family:Microsoft YaHei;">() //</span>方法返回exception隐式对象
- getPage<span style="font-family:Microsoft YaHei;">() //</span>方法返回page隐式对象
- getRequest() //方法返回request隐式对象
- getResponse() //方法返回response隐式对象
- getgetServletContext() //方法返回application隐式对象
- getServletConfig() //方法返回config隐式对象
- getSession() //方法返回session隐式对象
- getOut() //方法返回out隐式对象
pageContext作为一个域对象,还封装了下面的方法:
[java] view plain copy
- //pageContext域对象的方法:
- public void setAttribute(String name, Object value)
- public Object getAttribute(String name)
- public void removeAttribute(String name)
- //pageContext对象中还封装了访问其它域的方法(重要)
- public void setAttribute(String name, Object value, int scope)
- public Object getAttribute(String name, int scope)
- public void removeAttribute(String name, int scope)
- //代表各个域的常量
- pageContext.APPLICATION_SCOPE
- pageContext.SESSION_SCOPE
- pageContext.REQUEST.SCOPE
- pageContext.PAGE_SCOPE
到现在为止,应该可以看出pageContext对象的强大之处了!另外还有个findAttribute方法(*重要,查找各个域中的属性,EL表达式就依赖于这个方法),可以直接调用pageContext.findAttribute(String name),首先会从pageContext里找该属性,如果没有,会依次按照下面顺序在相应的域中查找:request, session, servletContext,如果没找着,返回null,否则返回属性值。
pageContext类中定义了一个forward方法和两个include方法分别简化和替代RequestDispatcher.forward方法和include方法,方法接收的资源如果以"/"开头,"/"代表当前web应用。不过这里的include是动态包含,不建议使用include。
6. JSP标签 JSP标签也称为JSP动作元素,它用于在JSP页面中提供业务逻辑功能,避免在JSP页面中直接编写java代码造成JSP页面难以维护。JSP有三种标签
1) <jsp:include>标签
<jsp:include>标签用于把另外一个资源的输出内容插入进当前JSP页面的输出内容之中,这种在JSP页面执行时的引入方式称为动态引入。
语法: [html] view plain copy
- <jsp:include page="relativeURL | <%= expression%>" flush="true | false" />
相当于调用pageContext.include("relativeURL")
page属性用于指定被引入资源的相对路径,它也可以通过执行一个表达式来获得。flush属性指定在插入其他资源的输出内容时,是否先将当前JSP页面都已输出的内容刷新到客户端。
2) <jsp:forward>标签 <jsp:forward>标签用于把请求转发给另一个资源
语法: [html] view plain copy
- <jsp:forward page="relativeURL | <%= expression%>" />
page属性用于指定请求转发到的资源的相对路径,它可以通过执行一个表达式来获得。
3) <jsp:param>标签
当使用<jsp:include>和<jsp:forward>标签引入或将请求转发给其它资源时,可以使用<jsp:param>标签向这个资源传递参数。
语法1: [html] view plain copy
- <jsp:include page="relativeURL | <%=expression%>">
- <jsp:param name="parameterName" value="parameterValue | <%=expression%>" />
- </jsp:include>
相当于relativeURL?name=...&value=....
语法2:[html] view plain copy
- <jsp:forward page="relativeURL | <%=exception%>">
- <jsp:param name="parameterName" value="parameterValue | <%=expression%>" />
- </jsp:forward>
相当于relativeURL?name=...&value=....
<jsp:param>标签的name属性用于指定参数名,value属性用于指定参数值。在<jsp:include>和<jsp:forward>标签中可以使用多个<jsp:param>标签来传递多个参数。
7. JSP映射 JSP也可以像Servlet那样映射,因为JSP本来就是Servlet。
[html] view plain copy
- <servlet>
- <servlet-name>SimpleJspServlet</servlet-name>
- <jsp-file>/jsp/simple.jsp</jsp-file>
- </servlet>
-
- <servlet-mapping>
- <servlet-name>SimpleJspServlet</servlet-name>
- <url-pattern>/xxx/yyy.html</url-pattern>
- </servlet-mapping>
/jsp/simple.jsp表示在webRoot/jsp目录下的simple.jsp文件
8. 四个域对象 到目前为止,web开发共接触到了4个域对象,这4个域对象是学习web的重点,也是笔试经常考察的知识点:
[java] view plain copy
- pageContext(称为page域): //pageContext中存的数据在页面范围都可以取出
- request(称为request域): //request中存的数据在请求范围内都可以取出
- session(称为session域): //session中存的数据在会话范围内都可以取出
- servletContext(称为application域)://servletContext中存的数据在整个应用程序范围内都可以取出
明确如下两个问题:这四个对象的生命周期?哪种情况下用哪种对象?
request:如果客户机向服务器发请求产生的数据,用户看完就没用了,向这样的数据就存在request域中。如用户看的新闻。
session:如果客户机向服务器发请求产生的数据,用户用完了等一会儿还有用,向这样的数据就存在session域中。如用户购买的东西,因为结账还要用到。
servletContext:如果客户机向服务器发请求产生的数据,用户用完了还要给其他用户用,向这样的数据就存在servletContext域中。如聊天室中说出的话,因为话要在自己页面中看到,别人也要看到。
实际中,能用小的容器就不要用大的,即request能满足就不要用session,session能满足就不要用servletContext
9. 总结 由于JSP一般都是通过servlet转发过来,servlet会通过容器将数据带过来,所以会使用JSP从容器中取出数据然后显示出来即可。取数据用脚本片段<%%>来取,显示用脚本表达式<%= %>处理。在学习了EL表达式和自定义标签后,脚本片段就可以用自定义标签替代,脚本表达式就可以用EL表达式替代了。
|