购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

第3章
JSP内置对象

3.1 JSP内置对象概述

JSP内置对象又称为隐式对象,是指在JSP页面系统中已经默认内置的Java对象,这些对象不需要显式声明即可使用,也就是可以直接使用。在JSP页面中,可以通过存取JSP内置对象实现与JSP页面和Servlet环境的相互访问,极大地提高了程序的开发效率。

JSP的内置对象主要有以下特点:

· 内置对象是自动载入的,不需要直接实例化。

· 内置对象通过Web容器来实现和管理。

· 所有的JSP页面都可以直接调用内置对象。

· 只有在脚本元素的表达式或代码段中才可以使用(<%=使用内置对象%>或<%使用内置对象%>)。

表3.1所示为JSP的九大内置对象。

表3.1 JSP的内置对象

下面我们逐步介绍几个重要的内置对象的使用。

3.2 request对象

request对象是HttpServletRequestWrapper类的实例(笔者这里引入的是Tomcat 10版本的servlet-api.jar)。request对象的继承体系如图3.1所示。

图3.1 request对象的继承关系

ServletRequest接口的唯一子接口是HttpServletRequest,HttpServletRequest接口的唯一实现类是HttpServletRequestWrapper,可以看出,Java Web标准类库只支持HTTP协议。Servlet/JSP中大量使用了接口而不是实现类,就是面向接口编程的最佳应用。

request内置对象可以用来封装HTTP请求的参数信息、进行属性值的传递以及完成服务端的跳转。

3.2.1 访问请求参数

在上一章JSP动作标识示例代码中,我们使用<jsp:param>传递参数,在接收参数页面,我们其实已经用到了request内置对象。本小节我们来学习使用URL传递参数。

主页面示例代码如下:

    <li><a href="jsp_req_param.jsp?name=张三李四&sex=man&id=" rel="external
nofollow">访问请求参数</a></li>

跳转子页面的示例代码如下(jsp_req_param.jsp):

     name:<%= request.getParameter("name") %><br>
     sex:<%= request.getParameter("sex") %><br>
     id:<%= request.getParameter("id") %><br>
     pwd:<%= request.getParameter("pwd") %><br>

程序执行后显示的页面如图3.2所示。

图3.2 程序执行结果

如果指定的参数不存在,则返回null(如pwd参数);如果指定了参数名,但未指定参数值,则返回空的字符串"(如id参数)。

3.2.2 在作用域中管理属性

在进行请求转发时,需要把一些数据传递到转发后的页面进行处理,这时需要调用request对象的setAttribute方法将数据保存在request范围内的变量中,转发后的页面则调用getAttribute方法接收数据。

具体代码如下(jsp_req_attr.jsp):

接收信息的页面代码如下(jsp_req_attr_b.jsp):

     request作用域中的属性值:<%= request.getAttribute("result") %>

getAttribute方法的返回值是Object,需要调用toString方法转换为字符串。

提示: 把语句<jsp:forward page="jsp_req_attr_b.jsp"/>改成response.sendRedirect("jsp_req_attr_b.jsp")或者跳转,将得不到request范围内的属性值,页面会出现异常。

3.2.3 获取Cookie

Cookie是网络服务器上生成并发送给浏览器的小段文本信息。通过Cookie可以标识一些常用的信息(比如用户身份,记录用户名和密码等),以便跟踪重复的用户。Cookie以键-值对的形式保存在客户端的某个目录下。

通过调用request.getCookies()方法来获得一个jakarta.servlet.http.Cookie对象的数组,然后遍历这个数组,调用getName()方法和getValue()方法来获取每一个Cookie的名称和值。

示例代码如下:

程序执行结果如图3.3所示。

图3.3 获取Cookie

3.2.4 获取客户端信息

request对象提供了很多方法获取客户端信息,具体示例如下:

· 客户使用的协议:<%=request.getProtocol() %><br />。

· 客户提交信息的方式:<%=request.getMethod() %><br />。

· 客户端地址:<%=request.getRequestURL() %><br />。

· 客户端IP地址:<%=request.getRemoteAddr() %><br />。

· 客户端主机名:<%=request.getRemoteHost() %><br />。

· 客户端所请求的脚本文件的文件路径:<%=request.getServletPath() %><br />。

· 服务器端口号:<%=request.getServerPort() %><br />。

· 服务器名称:<%=request.getServerName() %><br />。

· HTTP头文件中Host的值:<%=request.getHeader("host") %><br />。

· HTTP头文件中User-Agent的值:<%=request.getHeader("user-agent") %><br />。

· HTTP头文件中accept的值:<%=request.getHeader("accept") %><br />。

· HTTP头文件中accept-language的值:<%=request.getHeader("accept-language")%><br/>。

运行结果如图3.4所示。

图3.4 获取客户端信息

3.2.5 显示国际化信息

JSP国际化是指能同时应对世界不同地区和国家的访问请求,并针对不同地区和国家的访问请求提供符合来访者阅读习惯的页面或数据。

我们先了解几个相关的概念:

· 国际化(I18N):一个页面根据访问者的语言或国家来呈现不同的语言版本。

· 本地化(L10N):向网站添加资源,以使它适应不同的地区和文化。

· 区域:指特定的区域、文化和语言,通常是一个地区的语言标志和国家标志,通过下画线连接起来,比如"en_US"代表美国英语地区。

浏览器可以通过accept-language的HTTP报头向Web服务器指明它所使用的本地语言。java.util.Local类型对象封装了一个国家或地区所使用的一种语言。示例如下:

通过语言设置,可以在不同的语言地区,在页面上显示不同的信息提示,因此,比较大型的网站都会对不同地区的客户进行语言适配,从而更加本地化、国际化。

提示: 不少初学者在中文处理过程中都会碰到中文乱码的情况,这个主要是文件(JSP文件)、工具(IDEA)和服务器(Tomcat)三者编码的问题。目前笔者搭建的Tomcat 10 + IDEA 2022.1.1没有出现过中文乱码的情况。建议读者在创建项目初期,所有的工具和服务器统一使用UTF-8编码。

3.3 response对象

response对象用于响应客户请求,向客户端输出信息。与request对象类似,response对象是HttpServletResponseWrapper类的实例,它封装了JSP产生的响应客户端请求的有关信息(如回应的Header、HTML的内容以及服务器的状态码等),以提供给客户端。请求的信息可以是各种数据类型的信息,甚至可以是文件。response对象的继承体系如图3.5所示。

图3.5 response对象的继承关系

3.3.1 重定向网页

在很多情况下,当客户要进行某些操作时,需要将客户引导至另一个页面。例如,当客户输入正确的登录信息时,就需要被引导到登录成功页面,否则被引导到错误显示页面。此时,可以调用response对象的sendRedirect(URL)方法将客户请求重定向到一个不同的页面。重定向会丢失所有的请求参数,使用重定向的效果与在地址栏重新输入新地址再按回车键的效果完全一样,即发送了第二次请求。

下面我们通过简单的登录页面来演示重定向:

jsp_rsp_redirect_check.jsp:

jsp_rsp_redirect_promp.jsp:

3.3.2 处理HTTP文件头

response对象的setHeader()方法的作用是设置指定名字的HTTP文件头的值,如果该值已经存在,则新值会覆盖旧值。比较常用的头信息有缓存设置,页面自动刷新或者页面定时跳转。

1.禁用缓存

浏览器通常会对网页进行缓存,目的是提高网页的显示速度。但是很多安全性要求较高的网站(比如支付和个人信息网站)通常需要禁用缓存。

2.自动刷新

实现页面一秒刷新一次,代码如下:

3.定时跳转

实现页面定时跳转,如10秒后自动跳转到URL所指的页面,设置语句如下:

     <!-- 3.设置页面定时跳转 -->
     <% response.setHeader("refresh", "10;URL=index.jsp");%>

3.3.3 设置输出缓冲区

一般来说,服务器要输出到客户端的内容不会直接写到客户端,而是先写到输出缓冲区。当满足以下3种情况之一时,就会把缓冲区的内容写到客户端:

· JSP页面的输出信息已经全部写入缓冲区。

· 缓冲区已经满了。

· 在JSP页面中调用了response对象的flushBuffer()方法或out对象的flush()方法。

response对象提供了对缓冲区进行配置的方法,如表3.2所示。

表3.2 response缓冲区配置说明

3.3.4 转发和重定向

从表面上看,转发(Forward)动作和重定向(Redirect)动作有些相似:它们都可以将请求传递到另一个页面。但实际上它们之间存在较大的差异。

执行转发动作后依然是上一次的请求;执行重定向动作后生成第二次请求。注意地址栏的变化,执行重定向动作时,地址栏的URL会变成重定向的目标URL。

转发的目标页面可以访问所有原请求的请求参数,转发后是同一次请求,所有原请求的请求参数、request范围的属性全部存在;重定向的目标页面不能访问原请求的请求参数,因为发生了第二次请求,所有原请求的请求参数全部都会失效。

转发地址栏请求的URL不会变;重定向地址栏改为重定向的目标URL,相当于在浏览器地址栏输入新的URL。

3.4 session对象

Session(会话)表示客户端与服务器的一次对话。从客户端打开浏览器并连接服务器开始,到客户端关闭浏览器离开这个服务器结束,被称为一个会话。设置Session是为了服务器识别客户。由于HTTP是一种无状态协议,即当客户端向服务器发出请求,服务器接收请求,并返回响应后,该连接就结束了,而服务器不保存相关的信息。通过Session可以在的Web页面进行跳转时保存用户的状态,使整个会话一直存在下去,直到服务器关闭。

session对象是HttpSession类的实例。

3.4.1 创建及获取客户的会话

session对象提供了setAttribute()和getAttribute()方法创建和获取客户的会话。

setAttribute()方法用于设置指定名称的属性值,并将它存储在session对象中(用于获取修改输出)。

其语法格式如下:

     session.setAttribute(String name, Object value);

其中,name为属性名称,value为属性值(可以是类,也可以是值)。

调用getAttribute()方法获取与指定属性名name相关联的属性值,返回值为Object类型(所以可能需要转换为String或者Integer类型)。

其语法格式如下:

     session.getAttribute(String name);

创建Session的示例代码如下:

     session.setAttribute("name","创建Session");
     session.setAttribute("info","向Session中保存数据");

获取Session的示例代码如下:

程序执行的结果如图3.6所示。

图3.6 获取Session

3.4.2 从会话中移除指定的绑定对象

调用removeAttribute()方法将指定名称的对象移除,即从这个会话中删除与指定名称绑定的对象。其语法格式如下:

     session.removeAttribute(String name);

示例代码如下:

移除对象之后,通过getAttribute()获取的值是null,表示对象已经不存在了。

3.4.3 销毁会话

虽然session对象经历一段时间后会自动消失,但是有时我们也需要手动销毁会话(比如用户登录之后信息存储在会话对象中,退出的时候应该销毁会话对象以保存的用户数据)。

销毁会话有3种方式:

· 调用session.invalidate()方法。

· 会话过期(超时)。

· 服务器重新启动。

通常我们会调用session.invalidate()方法销毁会话。

3.4.4 会话超时的管理

在session对象中提供了设置会话生命周期的方法,分别说明如下:

· getLastAccessedTime():返回客户端最后一次与会话相关联的请求时间。

· getMaxInactiveInterval():以秒为单位返回一个会话内两个请求之间的最大时间间隔。

· setMaxInactiveInterval():以秒为单位设置会话的有效时间。

例如,设置会话的有效期为1000秒,超出这个范围会话将会失效。

3.4.5 session对象的应用

本例通过对session对象的综合学习,使用session对象统计页面的创建时间和访问量。

示例代码如下:

显示信息的代码如下:

本示例应用的执行结果如图3.7所示。

图3.7 Session页面访问次数

3.5 application对象

服务器启动后就产生了application对象,当客户在同一个网站的各个页面浏览时,这个application对象都是同一个,它在服务器启动时自动创建,在服务器停止时销毁。与session对象相比,application对象的生命周期更长,类似于系统的全局变量。

一个Web应用程序启动后,会自动创建一个application对象,而且在整个应用程序的运行过程中只有一个application对象,即所有访问该网站的客户都共享一个application对象。

3.5.1 访问应用程序初始化参数

在web.xml文件中,可利用context-param元素来设置系统范围内的初始化参数。

context-param元素应该包含param-name、param-value以及可选的description子元素,如图3.8所示。

图3.8 application应用程序配置图

使用application对象获取初始化参数:

3.5.2 管理应用程序环境属性

application对象设置的属性在整个程序范围内都有效,即使所有的用户都不发送请求,只要不关闭服务器,在其中设置的属性仍然是有效的。

application对象的环境属性示例代码如下:

3.5.3 session对象和application对象的比较

1.作用范围不同

session对象是用户级的对象,而application对象是应用程序级的对象。

一个用户对应一个session对象(客户端对象),每个用户的session对象不同,在用户所访问网站的多个页面之间共享同一个session对象。

一个Web应用程序对应一个application对象(服务端对象),每个Web应用程序的application对象不同,但一个Web应用程序的多个用户之间共享同一个application对象。

在同一网站下,每个用户的session对象不同,每个用户的application对象相同。

在不同网站下,每个用户的session对象不同,每个用户的application对象也不同。

2.生命周期不同

session对象的生命周期:用户首次访问网站创建,用户离开该网站(不一定要关闭浏览器)消亡。

application对象的生命周期:启动Web服务器就被创建,关闭Web服务器就被销毁。

3.6 out对象

out对象是一个输出流,用来向客户端输出各种数据类型的内容。同时它还可以管理应用服务器上的输出缓冲区,缓冲区大小的默认值为8KB,可以通过页面指令page来改变这个默认值。out对象继承自抽象类jakarta.servlet.jsp.JspWriter的实例,在实际应用中,out对象会通过JSP容器变换为java.io.PrintWriter类的对象。

在使用out对象输出数据时,可以对数据缓冲区进行操作,及时清除缓冲区中的残余数据,为其他的输出腾出缓冲空间。数据输出完毕后要及时关闭输出流。

3.6.1 向客户端输出数据

out对象调用print()或println()方法向客户端输出数据。由于客户端是浏览器,因此可以使用HTML中的一些标记控制输出格式。例如:

其输出结果与HTML标记一样。

3.6.2 管理输出缓冲区

默认情况下,服务端要输出到客户端的内容不直接写到客户端,而是先写到一个输出缓冲区中。调用out对象的getBufferSize()方法获取当前缓冲区的大小(单位是KB),调用getRemaining()方法获取当前尚剩余的缓冲区的大小(单位是KB)。

     <h2>管理输出缓冲区</h2>
     <%out.println("out对象缓冲区内容:");%><br>
     缓冲大小:<%=out.getBufferSize()%><br>
     剩余缓存大小:<%=out.getRemaining()%><br>
     是否自动刷新:<%=out.isAutoFlush()%><br>

程序执行结果如图3.9所示。

图3.9 out对象缓冲输出结果

3.7 其他内置对象

3.7.1 获取会话范围的pageContext对象

pageContext对象是jakarta.servlet.jsp.PageContext类的实例对象。它代表页面上下文,主要用于访问JSP之间的共享数据,使用pageContext可以访问page、request、session、application范围的变量。

1.获得其他对象

获得其他对象的几个重要方法说明如下:

· forward(String relativeUrlPath):将当前页面转发到另一个页面或者Servlet组件上。

· getRequest():返回当前页面的request对象。

· getResponse():返回当前页面的response对象。

· getServetConfig():返回当前页面的servletConfig对象。

· getServletContext():返回当前页面的ServletContext对象,这个对象是所有页面共享的。

· getSession():返回当前页面的session对象。

· findAttribute():按照页面、请求、会话以及应用程序范围的属性实现对某个属性的搜索。

· setAttribute():设置默认页面范围或特定对象范围中的对象。

· removeAttribute():删除默认页面对象或特定对象范围中已命名的对象。

下面用pageContext完成一次页面跳转功能,代码如下:

    <% pageContext.forward("jsp_pagecontext2.jsp?info=张三
zhangsan@gmail.com"); %>

jsp_pagecontext2.jsp代码如下:

     <h3>info=<%=pageContext.getRequest().getParameter("info")%></h3>
     <h3>realpath=<%=pageContext.getServletContext().getRealPath("/")%></h3>

执行结果如图3.10所示。

图3.10 pageContext执行结果

2.操作作用域对象

pageContext对象可以操作所有作用域对象(4个域,request、session、application和pageContext),在getAttribute()、setAttribute()、removeAttribute()三个方法中添加一个参数scope来指定作用域(即范围)。

在PageContext类中包含4个int类型的常量表示4个作用域:

· PAGE_SCOPE:pageContext作用域。

· REQUEST_SCOPE:request作用域。

· SESSION_SCOPE:session作用域。

· APPLICATION_SCOPE:application作用域。

示例代码如下:

jsp_pagecontext.jsp:

jsp_pagecontext2.jsp:

findAttribute(String name):依次按照page、request、session、application作用域查找指定名称的对象,直到找到为止。

3.7.2 读取web.xml配置信息的config对象

config对象是ServletConfig的实例,它主要用于读取配置的参数,很少在JSP页面使用,常用于Servlet中,因为Servlet需要在web.xml文件中进行配置。

先看一下config内置对象获取servlet名称,代码如下:

     <!-- 直接输出config的getServletName的值 -->
     <%=config.getServletName()%>

上面的程序代码输出了config的getServletName()的返回值,所有的JSP都有相同的名字:jsp,所以此行代码将输出jsp。

获取初始化信息示例(web.xml)如下:

跳转代码如下:

     <li><a href="myconfig">config 对象</a></li>

显示代码如下:

     <!-- 直接输出config的getServletName的值 -->
     ServletName:<%=config.getServletName() %><br>
     <!-- 输出该JSP中名为name的参数配置信息 -->
     name配置参数的值:<%=config.getInitParameter("name")%><br>
     <!-- 输出该JSP中名为age的参数配置信息 -->
     age配置参数的值:<%=config.getInitParameter("age")%><br>

代码执行结果如图3.11所示。

图3.11 config对象输出结果

3.7.3 应答或请求的page对象

page对象是java.lang.Object类的实例。它指向当前JSP页面本身,有点像类中的this指针,用于设置JSP页面的属性,这些属性将用于和JSP通信,控制所生成的Servlet结构。page对象很少使用,我们调用Object类的一些方法来了解这个对象。

示例代码如下:

     当前page页面对象的字符串描述: <%= page.toString() %><br>
     当前page页面对象的class描述: <%= page.getClass() %><br>
     page跟this是否等价: <%= page.equals(this) %><br>

代码执行结果如图3.12所示。

图3.12 page对象输出结果

提示: page对象虽然是this的引用,但是page的类型是java.lang.Object,所以无法通过page调用实例变量、方法等,只能调用Object类型的一些方法。

3.7.4 获取异常信息的exception对象

JSP引擎在执行过程中可能会抛出种种异常。exception对象表示的就是JSP引擎在执行代码过程中抛出的种种异常。exception对象的作用是显示异常信息,只有在包含isErrorPage="true"的页面中才可以使用,在一般的JSP页面中使用该对象将无法编译JSP文件。

在Java程序中,可以使用try/catch关键字来处理异常情况;如果在JSP页面中出现没有捕获到的异常,就会生成exception对象,并把exception对象传送到在page指令设定的错误页面中,然后在错误页面中处理相应的exception对象。

示例代码如下:

jsp_exception_err.jsp代码如下:

3.8 实践与练习

1.自主学习并尝试添加和删除Cookie。

2.利用会话完成一个猜数字的游戏。

3.应用JSP内置对象,设计并实现登录框架,登录之后用户信息可以在任何页面显示。

4.掌握request和response对象的使用,使用config对象包装URL地址。 ZuRb5NARs499upek83wDhi+4XIK0oYHEnsLQZKvND77mWroMktxojHIgE2hurOLu

点击中间区域
呼出菜单
上一章
目录
下一章
×