javaweb之jsp详解二

JSP的九大内置(隐式)对象

在JSP中有九个对象可以直接使用而不用获取,在JSP转为Servlet的过程中会帮我们定义获取好,所以可以直接使用,如下。

  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;
隐式对象 说明
request 转译后对应HttpServletRequest/ServletRequest对象
response 转译后对应HttpServletRespons/ServletResponse对象
session 转译后对应HttpSession对象
application 转译后对应ServletContext对象
out 转译后对应JspWriter对象,其内部关联一个PringWriter对象
page 转译后对应this
config 转译后对应ServletConfig对象
exception 译后对应Throwable对象,代表由其他JSP页面抛出的异常对象,只会出现于JSP错误页面(isErrorPage设置为true的JSP页面)
pageContext 转译后对应PageContext对象,它提供了JSP页面资源的封装,并可设置页面范围属性

转译后的对象我们基本都很熟悉,也就不过多的介绍了,不明白的看看我的servlet的文章吧。

out对象

需要注意的是out这个隐式对象,转译后为JSPWriter,用于向客户端发送文本数据。

out对象是通过调用pageContext对象的getOut方法返回的,其作用和用法与ServletResponse.getWriter方法返回的PrintWriter对象非常相似。
JSP页面中的out隐式对象的类型为JspWriter,JspWriter相当于一种带缓存功能的PrintWriter,设置JSP页面的page指令的buffer属性可以调整它的缓存大小,甚至可以关闭它的缓存。

只有向out对象中写入了内容,且满足如下任何一个条件时,out对象才去调用ServletResponse.getWriter方法,并通过该方法返回的PrintWriter对象将out对象的缓冲区中的内容真正写入到Servlet引擎提供的缓冲区中:
1.设置page指令的buffer属性关闭了out对象的缓存功能
2.out对象的缓冲区已满
3.整个JSP页面结束
《javaweb之jsp详解二》

举例如下:

<body>
     aaa<br>
     <%
     out.print("bbb"); 
     response.getWriter().write("ccc");  
     %>
  </body>

浏览器返回结果如下:

ccc aaa
bbb 

原因如下:JSP在运行到 response.getWriter().write(“ccc”); 时会将内容输出至response的出ccc,而aaa和bbb的输出都是由out来完成的,而aaa在bbb的前面,在jsp页面结束,两者被输出,结果就是如上

pageContext对象

pageContext与其他8大对象的关系

pageContext对象是JSP技术中最重要的一个对象,它代表JSP页面的运行环境,这个对象不仅封装了对其它8大隐式对象的引用,它自身还是一个域对象(还有三个域对象:ServletContext,Session,Request),这个域对象的生命周期最短,作用域最小,他的作用域就是当前的jsp页面,当然它可以用来保存数据。并且,这个对象还封装了web开发中经常涉及到的一些常用操作,例如引入和跳转其它资源、检索其它域对象中的属性等。

pageContext获取其他8大对象:

  • getException方法返回exception隐式对象
  • getPage方法返回page隐式对象
  • getRequest方法返回request隐式对象
  • getResponse方法返回response隐式对象
  • getServletConfig方法返回config隐式对象
  • getServletContext方法返回application隐式对象
  • getSession方法返回session隐式对象
  • getOut方法返回out隐式对象

pageContext对forward和include的简写

pageContext为什么要封装其它8大内置对象呢?在JSP中不是都可以直接获取吗?如果在编程过程中,把pageContext对象传递给一个普通java对象,那么这个java对象将可以操作其他8大对象,可以做的事情就很多了。

request.getRequestDispatcher("/xxxx/xxx").forward(request, response);
request.getRequestDispatcher("/xxxx/xxx").include(request, response);
pageContext.forward("/xxxx/xxx");//jsp下
pageContext.include("/xxxx/xxx");//jsp下

servlet中获取pageContext的方法为:

PageContext pageContext = javax.servlet.jsp.JspFactory.getDefaultFactory().getPageContext(this, request, response, null, true, 8192, true);

pageContext域的属性操作

pageContext对象中的操作域中数据的方法

  • public void setAttribute(java.lang.String name,java.lang.Object value)
  • public java.lang.Object getAttribute(java.lang.String name)
  • public void removeAttribute(java.lang.String name)

pageContext对象中还封装了访问其它域的方法(和上面的方法不同之处就是多了一个参数,这个参数是可以直接指定相应的域)

  • public java.lang.Object getAttribute(java.lang.String name,int scope)
  • public void setAttribute(java.lang.String name, java.lang.Object value,int scope)
  • public void removeAttribute(java.lang.String name,int scope)

代表各个域的常量

  • PageContext.APPLICATION_SCOPE
  • PageContext.SESSION_SCOPE
  • PageContext.REQUEST_SCOPE
  • PageContext.PAGE_SCOPE

下面这个方法是非常重要的,因为这个方法是在所有的域中查找数据,查找顺序是:pageContext->request->session->ServletContext,如果查找不到相应的数据的话,就返回一个空字符串,这个方法和之后要说到的el表达式的功能是一样的
findAttribute方法 (*重点,查找各个域中的属性)

四大作用域

到此为止,web开发接触到了4个域对象:

  • pageContext(称之为page域)
  • request(称之为request域)
  • session(称之为session域)
  • servletContext(称之为application域)

四大作用域的作用范围大小为pageContext<request<session<servletContext

application(ServletContext)

1、生命周期:当Web应用被加载进容器时创建代表整个web应用的application对象,当服务器关闭或Web应用被移除时,application对象跟着销毁。

2、作用范围:整个Web应用。

3、作用:

  • 3.1 application.setAttribute(“key”,Object value):存储整个web应用公用的数据

  • 3.2 在不同Servlet 之间转发(不常用)
      this.getServletContext().getRequestDispatcher(“/servlet/Demo10Servlet”).forward(request,response);

注意:由于request对象也有getRequestDispatcher(“**”)方法,所有我们开发是通常使用request调用该方法实现重定向。

  • 3.3 读取资源文件。
    资源的读取一般用到以下方法:
    this.getServletContext().getRealPath(“/1.properties”)
    this.getServletContext().getResourceAsStream(“/1.properties”)

session 域 (HttpSession)

HttpSession 在服务器中,为浏览器创建独一无二的内存空间,在其中保存会话相关的信息。

1、生命周期:在第一次调用 request.getSession() 方法时,服务器会检查是否已经有对应的session,如果没有就在内存 中创建一个session并返回。

当一段时间内session没有被使用(默认为30分钟),则服务器会销毁该session。

如果服务器非正常关闭(强行关闭),没有到期的session也会跟着销毁。

如果调用session提供的invalidate() ,可以立即销毁session。

注意:服务器正常关闭,再启动,Session对象会进行钝化和活化操作。同时如果服务器钝化的时间在session 默认销毁时间之内,则活化后session还是存在的。否则Session不存在。 如果JavaBean 数据在session钝化时,没有实现Serializable 则当Session活化时,会消失。所以保存在session中的javaBean应该实现Serializable。

2、作用范围:一次会话。

3、作用:保存登录的用户信息、购物车信息等

request域 –(HttpServletRequest)

1、生命周期:在service 方法调用前由服务器创建,传入service方法。整个请求结束,request生命结束。

2、作用范围:整个请求链(请求转发也存在)。

3、作用: 在整个请求链中共享数据。最常用到:在Servlet 中处理好的数据交给Jsp显示,此时参数就可以放置在Request域中带过去。

pageContext域—(PageContext)

1、生命周期:当对JSP的请求时开始,当响应结束时销毁。

2、作用范围:整个JSP页面,是四大作用域中最小的一个。

3、作用:

(1)获取其它八大隐式对象,可以认为是一个入口对象。
(2)获取其所有域中的数据
(3)跳转到其他资源 其身上提供了forward和include方法,简化重定向和转发的操作

JSP标签库

虽然我们希望JSP页面仅用作数据显示模块,不要嵌套任何java代码引入任何业务逻辑,但在实际开发中不引入一点业务逻辑是不可能的,但引入业务逻辑会导致页面出现难看java代码,怎么办?
Sun公司允许用户开发自定义标签封装页面的java代码,以便jsp页面不出现一行java代码。当然sun公司在jsp页面中也内置了一些标签(这些标签叫做jsp标签),开发人员使用这些标签可以完成页面的一些常用业务逻辑。
JSP标签也称之为Jsp Action(JSP动作)元素,它用于在JSP页面中提供业务逻辑功能。

<jsp:include>标签  
<jsp:forward>标签  
<jsp:param>标签  
<jsp:useBean>标签
<jsp:setProperty>标签
<jsp:getProperty>标签

1.标签

标签用于把另外一个资源的输出内容插入进当前JSP页面的输出内容之中,这种在JSP页面执行时的引入方式称之为动态引入。
语法:

<jsp:include page="relativeURL | <%=expression%>" flush="true|false" />

page属性用于指定被引入资源的相对路径,它也可以通过执行一个表达式来获得。
flush属性指定在插入其他资源的输出内容时,是否先将当前JSP页面的已输出的内容刷新到客户端。

- 动态引入
<jsp:include>
标签是动态引入(和使用代码进行include一样),<jsp:include>标签涉及到的2个JSP页面会被翻译成2个servlet,这2个servlet的内容在执行时进行合并。 

- 静态引入
<%@ include file="/head.jsp"%>
include指令是静态引入(编译时引入),涉及到的2个JSP页面会被翻译成一个servlet,其内容是在源文件级别进行合并。

- 重点注意
不管是<jsp:include>标签,还是include指令,它们都会把两个JSP页面内容合并输出,所以这两个页面不要出现重复的HTML全局架构标签,否则输出给客户端的内容将会是一个格式混乱的HTML文档。

2.标签

<jsp:forward>标签用于把请求转发给另外一个资源。
语法:
<jsp:forward page="relativeURL | <%=expression%>" />
page属性用于指定请求转发到的资源的相对路径,它也可以通过执行一个表达式来获得。

3.或者标签

当使用<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>标签来传递多个参数。

4.标签,标签,标签

<body> 
    <!-- 找到就直接用,找不到实例化 scope默认是page域--> 
    <jsp:useBean id="person" class="com.wy.entity.Person" scope="page"/> 

    <!-- 直接设置属性值(8种基本类型的转换) --> 
    <jsp:setProperty name="person" property="name" value="xxx"/> 

    <!-- 用请求参数给属性赋值(8中基本类型的转换) --> 
    <jsp:setProperty name="person" property="name" param="name"/> 

    <!-- 获取Person中的属性name的值 --> 
    <jsp:getProperty name="person" property="name"/> 
  </body>  

同时我们定义了一个Bean对象:com.wy.entity.Person,其中有一个name属性(一定要有get/set方法才叫属性)
对于标签<jsp:useBean>他可以指定在哪个域中创建这个bean对象,他的规则是首先在这个域中查找有没有这个对象,没有就创建,有就直接拿来使用。

对于<jsp:setProperty>标签,可以直接使用value属性设置属性的值,这里面他内部是有一个类型转换的,可以将字符串值转化成8中基本类型的值,其他对象类型的转化是会报错的,比如我们现在Person类中有一个属性birthday是Date型的,那么我们这里就不能直接写成这样:

<jsp:setProperty name="person" property="birthday" value="1990-08-01"/> 

这样系统会报类型转化错误,
当然我们可以直接使用脚本表达式给这个属性值传递一个Date类型的对象,这样就不会又错了:

<jsp:setProperty name="person" property="birthday" value="<%=new Date()%>"/> 

当然我们也可以使用请求参数来设置属性值:

<jsp:setProperty name="person" property="names" param="name"/> 

我们访问:http://localhost:8080/JspDemo/bean.jsp?names=person,这样就可以进行属性赋值

同时这里的name属性中的填的是<jsp:useBean>标签中的id值,所以说,当我们在使用get/setProperty标签的时候一定是在useBean标签之后

关于取出属性值的标签<jsp:getProperty>的话就简单了。

JSP的路径配置

由于JSP本质就是一个Servlet,所以配置融Servlet一样

<!-- jsp路径配置 -->
<servlet> 
    <servlet-name>SimpleJspServlet</servlet-name> 
    <jsp-file>/index.jsp</jsp-file> 
    <load-on-startup>1</load-on-startup > 
</servlet> 

<servlet-mapping> 
    <servlet-name>SimpleJspServlet</servlet-name> 
    <url-pattern>/index5.jsp</url-pattern> 
</servlet-mapping>

对jsp做路径映射会使得访问控制更加灵活

参考

JavaWeb学习篇之—-Jsp详解
菜鸟教程jsp
servlet的九大内置对象
四大作用域对象总结

点赞

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注