7. JSP脚本中的9个内置对象
打开任意一个JSP页面对应生成的Servlet类文件,都有如下片段:(如下图:)
appliction :该实例代表 JSP 所属的 WEB 应用本身,用于 JSP 页面,或者在 Servlet 之间信息交换。 常用方法有 getAttribute( name , value)、setAttribute( name , value)、getInitParameter( name ) 等。
config :代表 JSP 的配置信息, 常用方法有 getInitParameter( String paramName) 、getInitParameternames()等。
exception :代表页面中的异常和错误。只有页面是错误处理页面,page 的isErrorPage 属性为 true 时该对象才可以使用。常用方法 getMessage() 、printStrackTrace()等。
out : JSP 页面输出流,用于输出内容,形成 HTML 页面。
page : 代表该页面本身,也就是 Servlet 中的 this ,能用 page 的地方就可以用 this .
pageContext: 代表 JSP 页面上下文,可以访问页面中的共享数据。 常用方法有:getServletContext() 和 getServletConfig() 等。
request : 客户端的请求参数都被封装在该对象里。这是一个常用对象,获取客户端请求参数必须使用该对象。常用方法:getParameter(String paramName)、getParameterValues(String paramName)、setAttribute(String arrtName,Object attrValue)、getAttribute(String attrName) 和 setCharacterEncoding(String env)等。
response : 代表服务器对客户端的响应, response 对象常用于重定向,常用的方法有 getOutputStream() 、 sendRedirect(java.lang.String location)等。
session : 该对象代表一次会话。当客户端与站点建立连接时,会话开始;当客户端关闭浏览器时,会话结束。常用方法: getAttribute(String attrName)、setAttribute(String attrName, Object attrValue) 等。
JSP 与 Servlet 之间如何交换数据?
为了解决这个问题,几乎所有的服务器(包括Java、ASP、PHP、Ruby 等)将数据放入这4个类似 Map 的结构,分别是application 、session、 request、page 。
application :对于整个Web 应用有效,一旦JSP 、Servlet 将数据放入application 中,该数据可以被该应用下的其他所有的 JSP Servlet 访问。
session : 仅对一次会话有效,可被本次会话的其他所有的 JSP 、Servlet 访问。
request : 仅对本次请求有效,可被该次请求的其他JSP 、Servlet 访问。
page : 仅对当前页面有效,只可被当前页面的 JSP 脚本、声明部分访问。
7.1 application 例如下: (application 不仅可用于两个JSP 页面之间共享数据,还可以用于 Servlet 和 JSP 之间共享数据)
在a.jsp 页面声明一个变量i 并把这个值放入 application 中 命名为"counter"
<%! int i; %>
<%application.setAttribute("counter",String.valueOf(++i));%>
放入application之后,可以在任何页面调用"counter" 的值 i .
<%=application.getAttribute("counter")%>
application 还有一个重要的用处:可用于获得Web 应用(web.xml)的配置参数。
在 web.xml 文件中使用 <context-param> 元素配置,和参数 <param-name> <param-value> 例如下图:
在 JSP 页面中可以用application 取出参数 取下图:
通过这种方式可以将一些信息放在 web.xml 文件中配置,从而提高程序的移植性。
7.2 config 对象 (代表当前 JSP 配置信息,该对象在 JSP 页面中比较少用,但在 Servlet 中则用处相对较大)
下边为config 的一个方法
<!--直接输出 config 的 getServletName 的值jsp-->
<%= config.getServletName() %>
所有的 JSP 页面都有相同的名字: jsp . 所以 上边代码输出为jsp .
下面将 JSP 页面配置成名为config 的 Servlet,并将该 Servlet 映射到 /config 处, 这样就可以用 /config 来访问该页面
在 web.xml 文件中增加配置片段(如下图:)
在 a.jsp页面中获取 JSP 配置参数(代码如下:)
通过 config 可以访问到web.xml 文件中的配置参数(如下图:)
实际上我们也可以直接访问 a.jsp 页面在浏览器中看到如果下图:
注:对比两图可以看出,如果希望 JSP 页面可以获取 web.xml 配置文件中的配置信息,则必须通过该 JSP 配置的路径来访问该页面,只有这样访问 JSP 页面才会让配置参数起作用。
7.3 exception 对象
如下例子:(如下图)
异常页面 a.jsp
处理异常页面 error.jsp
以上页面的 page 指令的 isErrorPage 属性被设为 true, 则可以通过 exception 对象来访问上一个页面所出现的异常信息
在浏览器中打开 a.jsp如果下图
在浏览器中请求页面的地址依然是 a.jsp 但内容已经改变。
注意: 当 JSP 页面 page 指令的 isErrorPage 为 true 时, 该页面才会提供和访问 exception 内置对象。
7.4 out 对象 (页面输出流,一般使用表达式的地方都可以使用 out 对象来达到效果。)
所以使用 out 的地方,都可以使用输出表达式来代替,而且使用表达式更加简洁。<%=...%>表达式的本质就是 out.write(...) ; 。
7.5 pageContext 对象 (页面上下文,该对象主要用于访问 JSP 之间的共享数据。使用 pageContext 可以访问 page、request、session、application 范围的变量。
方法如下:
getAttribute(String name) :取得 page 范围的 name 属性。(默认为 page 范围内)
getAttribute(String name, int scope): 取得指定范围的 name 属性,其中scope 可以是以下4个值。
pageContext.PAGE_SCOPE :对应于 page 范围。
pageContext.REQUEST_SCOPE :对应 request 范围。
pageContext.SESSION_SCOPE :对应 session 范围。
pageContext.APPLICATION_SCOPE :对应 application 范围。
对应还有两个 setAttribute()方法,用于将指定变量放入 page、request、session、application 范围内。
例子如下 :
pageContext.setAttribute("page1" , "hello1"); // 该属性默认为 page 范围内。
//使用 pageContext 设置属性到 request 范围。
pageContext.setAttribute("page2", "hello2" ,pageContext.REQUEST_SCOPE);
//使用 request 设置属性。
request.setAttribute("page2", "hello2");
这两条相等,都是设置 page2 到 request 范围。
还可以获取各属性所在的生存范围,这些范围获取的都是整形变量, 方法为:pageContext.getAttributesScope("page2"); 范围如下:
1 : 对应 page 生存范围。
2 : 对应 request 生存范围。
3 : 对应 session 生存范围。
4 : 对应 application 生存范围。
不仅如此,pageContext 还可用于获取其他内置对象, pageContext 对象包含如下方法:
ServletRequest getRequest() :获取 request 对象 。
ServletResponse getResopnse() :获取 response 对象 。
ServletConfig getServletConfig() :获取 config 对象 。
ServletContext getServletContext() :获取 application 对象 。
HttpSession getSession() : 获取 session 对象 。
注意:一旦在 JSP、Servlet 编程中获取了 pageContext 对象 ,就可以通过它提供的上面方法来获取其他内置对象。
7.6 request 对象(每个 request 对象封装着一次用户请求,并且所有的请求参数都被封装在 request 对象中,所以 request 对象是获取请求参数的重要途径。)
request 是 HttpServletRequest 接口的实例,提供了如下几个方法:
String getParameter(String paramName) :获取 paramName 请求参数值。
Map getParameter() :获取所有请求参数名和参数值所组成的 Map 对象。
Enumeration getParameterNames() :获取所有请求参数名 所组成的Enumeration 对象。
String[] getParameterValues(String name) :获取请求参数有多个值时,该方法将返回多个值 所组成的数组。
---------HttpServletRequest 提供了如下方法来访问请求头信息:-----------
String getHeader(String name) :根据指定请求头的值。
java.util.Enumeration<String> getHeaderNames() :获取所有请求头的名称。
java.util.Enumeration<String> getHeaders(String name) :获取指定请求头的多个值。
int getIntHeader(String name) :获取指定请求头的值,并将该值转为整数值。
客户端发送请求参数通常分两种:
GET 方式的请求 :直接在浏览器地址栏输入访问地址所发送的请求 或 提交表单发送请求(表单设置method="get", 不设置也为get方式) , GET方式的请求会将请求参数的名和值转换成字符串,并附加在原 URL 之后,因此可以在地址栏中看到请求参数名和值。且 GET 请求传送的数据量较小,一般不能大于 2KB 。
POST 方式的请求 :这种方式通常使用提交表单(由form HTML 元素表示)且需要设置 form 元素的 method 属性为 post 。POST 方式请求参数大小不受限制。而且参数和对应的值放在 HTML HEADER 中传输,用户不能在地址栏看到参数值,安全性相对较高。
下面是表单页面例子:POST 方式
form.jsp
request1.jsp
在获取表单域对应的请求参数值之前,先设置 request 编码的字符集 避免非西欧字符出现乱码,所以先执行 request.setCharacterEncoding("gbk2312");
GET 方式发送的请求参数被附加到地址栏的 URL 之后,地址栏的 URL 将变成如下形式:
url?param1=value1¶m2=value2¶m3=value3
例下图:request2.jsp
下面页面示范表单 使用 GET 输送中文字符。
form2.jsp
提交到 request3.jsp 如下图:
为了获取 GET 请求里的中文参数值,必须借助于 java.net.URLDecoder 类 的URLDecoder 和 URLEncoder 来处理。
还有一种方法如下:
先将其转换成字节数组,再将字节数组重新解码成字符串。 代码如下:
<%
// 获取原始的请求参数值
String rawName = request.getParameter("name");
// 将字节数组值使用 ISO-8859-1 字符串分解成字节数组
byte[] rawBytes = rawName.getBytes("ISO-8859-1");
// 将字节数组重新解码成字符串
String name = new String(rawBytes, "gb2312");
%>
输出姓名:<%=name%>
小知识:
1. <jsp: forward page="bbb.jsp">跳转时,请求参数和 request 范围的属性都不会丢失,即 forword 动作来还是原来的上的页面发来的请求参数再次发送到bbb.jsp。
2. request 还有一个功能就是执行 forward 和 incluce ,代码如下:
将 a.jsp 页面 include 到本页面中。
getRequestDispatcher("/a.jsp").include(request,response);
将 a.jsp 页面 forward 到本页面中。
getRequestDispatcher("/a.jsp").forward(request,response);
7.7 response 对象(代表服务器对客户端的响应。out 只可以响应输出字符内容, 假如需要 jsp 页面中动态生成一幅位图、或者输出一个 PDF 文档, 使用 out 作为响应对象将无法完成,此时必须使用 response 作为响应输出。 除此之外,还可以使用 response 来重定向请求,以及用于向客户端增加 Cookie 。)
7.7.1 response 响应生成非字符响应 ,下面的 JSP 页面将在客户端生成一张图片。 response 是HttpServletResponse 接口的实例,该接口提供了一个getOutputStream() 方法, 该方法返回响应输出字节流。
如下 img.jsp
以上页面的粗体字代码设置了服务器响应数据是 image/jpeg, 这表明服务器响应是一张 JPG图片。
这个页面可以在其它页面中使用 img 标签
<img src="img.jsp">
使用这种临时生成图片的方式就可以非常容易地实现网页上的图形验证码功能。还可以直接生成 PDF 文件 、和 Excel 文件,这些文件可以直接作为报表使用。
7.7.2 response 重定向
重定向是 response 的另外一个用处,与 forward 不同的是,重定向会丢失所有请求的参数和 request 范围的属性。
HttpServletResponse 提供了一个 sendRedirect(String path) 方法,用于重定向。
代码如下:
// 执行重定向动作时,地址栏的 URL 会变成重定向的目标 URL。
<% response.sendRedirect("bbb.jsp"); %>
forward(转发) 请求参数不会丢失 ,地址栏不改变。
redirect(重定向) 请求参数丢失, 地址栏改变。
7.7.3 增加 Cookie 重定向
Cookie 与 session 的不同之处:
session 会随着浏览器的关闭而失效。
Cookie 会一直存放在客户端机器上,除非,清理或超出 Cookie 的生命期限。
response 对象提供了增加 Cookie 的方法: void addCookie(Cookie cookie);
在增加 Cookie 之前,必须先创建 Cookie 对象 。方法如下:
1 . 创建 Cookie 实例,Cookie 的构造器为 Cookie(String name, String value) .
2 . 设置 Cookie 生命期限。
3 . 向客户端写 Cookie 。
看例下面代码 addCookie.jsp
在浏览器地址栏中输入:
http://localhost:8080/webDemo/addCookie.jsp?name=hsl执行页面后,网站就会向客户端机器写入一个名为 username 的 Cookie ,生存期限为24小时。
访问客户端 Cookie 使用 request 对象提供的方法 getCookies 方法,该方法返回客户端机器上所有 Cookie 组成的数组,遍历该数组的每个元素,找到希望访问的 Cookie 即可。
代码如下:
注意:使用 Cookies 对象必须设置其生存期限,否则 Cookie 将会随浏览器关闭而自动消失。
Cookie 值不允许出现中文字符,如果要需要,则可以借助于 java.net.URLEncoder 先对中文字符进行编码,将编码后的结果调设为 Cookie 值,当程序读取 Cookie 时,使用 java.net.URLUnDecoder 对其进行解码。
例如下代码:
7.8 session 对象(代表一次用户会话, session 通常用于跟踪用户的会话信息,如判断用户是否登录系统,或者在购物车中购买的商品等。 session 范围内的属性可以在多个页面的中转之间共享。一旦关闭浏览器,即 session 结束, session 范围内的属性将全部丢失。)
session 对象是 HttpSession 的实例,有如下两个方法:
setAttribute(String attName , Object attValue) : 设置 session 范围内 attName 属性的值 attValue 。
getAttribute(String attName) :返回 session 范围内的 attName 属性的值。
如下例子:
shop.jsp
processBuy.jsp
注意: session 的属性值可以是任何可序列化的 Java 对象。便于将状态信息保存到 Web 服务器的硬盘上。