JSP 脚本中包含了 9 个内置对象,这 9 个内置对象都是 Servlet API 接口的实例,只是 JSP 规范对它们进行了默认初始化。

这 9 个内置对象如下:

1、application:javax.servlet.ServletContext 的实例,该实例代表 JSP 所属的 Web 应用本身,可用于 JSP 页面,或者在 Servlet 之间交换信息。常用的方法有 getAttribute(String attrName)、setAttribute(String attrName, String attrValue) 和 getInitParameter(String paramName) 等。

2、config:javax.servlet.ServletConfig 的实例,该实例代表该 JSP 的配置信息。常用的方法有 getInitParameter(String paramName) 和 getInitParameternames() 方法。

3、exception:java.lang.Throwable 的实例,该实例代表其他页面中的异常和错误。只有当页面是错误页面,即编译指令 page 的 isErrorPage

属性为 true 时,该对象才可以使用。常用的方法有 getMessage() 和 printStackTrace()。

4、out:javax.servlet.jsp.JspWriter 的实例,该实例代表 JSP 页面的输出流,用于输出内容,形成 HTML 页面。

5、page:代表该页面本身,通常没有太大用处。也就是 Servlet 中的 this,其类型就是生成的 Servlet 类,能用 page 的地方就可用 this。

6、pageContext:javax.servlet.jsp.PageContext 的实例,该对象代表该 JSP 页面上下文,使用该对象可以访问页面中的共享数据。常用的方法有 getServletContext() 和 getServletConfig() 。

7、request:javax.servlet.jsp.HttpServletRequest 的实例,该对象封装了一次请求,客户端的请求参数都被封装在该对象里。这是一个常用的对象,获取客户端请求参数必须使用该对象。常用的方法有 getParameter(String paramName)、getParameterValues(String paramName)、setAttribute(String attrName, Object attrValue)、getAttribute(String attrName) 和 setCharacterEncoding(String encoding)

8、response:javax.servlet.jsp.HttpServletResponse 的实例,代表服务器对客户端的响应。通常很少直接使用该对象,而是使用 out 对象,常用的方法有 getOutputStream()、setRedirect(String location)

9、session:javax.servlet.http.HttpSession 的实例,该对象代表一次会话。常用的方法有 getAttribute(String attrName)、setAttribute(String attrName, Object attrValue)

打开 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;

  

try {
response.setContentType("text/html; charset=UTF-8");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
}

  

上面的声明及定义位于 jspService 方法内

application 对象

通常有如下两个作用:

1、让多个 JSP 、Servlet 共享数据

application 通过 setAttribute(String attrName, Object value) 方法讲一个值设置成 application 的 attrName 属性,该属性的值对整个 Web 应用有效,因此该 web 应用的每个 JSP 页面或 Servlet 都可以访问该属性,访问属性的方法为 getAttribute(String attrName)。

application 不仅可以用于两个 JSP 页面之间共享数据,还可以用于 Servlet 和 JSP 之间共享数据。可以把 application 理解成一个 Map 对象,任何 JSP、Servlet 都可以把某个变量放入 application 中保存,并为之指定一个变量名;而该应用里的其他 Servlet、JSP 就可以根据该属性名来得到这个变量。

2、获得 web 应用配置参数

application 还有一个重要用处,可用于获得 web 应用的配置参数。如下:参数都在 web.xml 中配置了。

如下,在 web.xml 里面设置参数配置(context-param 标签):

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0"
metadata-complete="true"> <servlet>
<servlet-name>get-application</servlet-name>
<servlet-class>com.baiguiren.GetApplication</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>get-application</servlet-name>
<url-pattern>/get-application</url-pattern>
</servlet-mapping> <!-- 配置第一个参数:driver -->
<context-param>
<param-name>driver</param-name>
<param-value>com.mysql.jdbc.Driver</param-value>
</context-param> <!-- 配置第二个参数:url -->
<context-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306/jsp</param-value>
</context-param> <!-- 配置第三个参数:user -->
<context-param>
<param-name>user</param-name>
<param-value>root</param-value>
</context-param> <!-- 配置第四个参数:pass -->
<context-param>
<param-name>pass</param-name>
<param-value>root</param-value>
</context-param> <welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>

  

在 JSP 中获取参数:

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ page import="java.sql.*" %> <html>
<head>
<title>通过application获取web.xml中的参数</title>
</head>
<body>
<%
// 从配置中获取参数
String driver = application.getInitParameter("driver");
// 从配置参数中获取数据库 url
String url = application.getInitParameter("url");
// 从配置参数中获取用户名
String user = application.getInitParameter("user");
// 从配置参数中获取密码
String pass = application.getInitParameter("pass"); // 注册驱动
Class.forName(driver);
// 获取数据库连接
Connection connection = DriverManager.getConnection(url, user, pass);
// 创建 Statement 对象
Statement stmt = connection.createStatement();
// 执行查询
ResultSet rs = stmt.executeQuery("select * from person");
%> // 输出
<table bgcolor="#9999dd" border="1" width="480">
<%
// 遍历结果集
while(rs.next())
{
%>
<tr>
<td><%=rs.getString(1)%></td>
<td><%=rs.getString(2)%></td>
<td><%=rs.getString(3)%></td>
</tr>
<%
}
%>
</table>
</body>
</html>

  

config 对象:

config对象代表当前 JSP 配置信息,但 JSP 通常无需配置,因此也就不存在配置信息。所以 JSP 页面比较少用该对象。

但在 Servlet 中则用处较大,因为 Servlet 需要在 web.xml 文件中进行配置,可以指定配置参数。

如:

web.xml 里面配置:

<servlet>
<!-- 指定Servlet名字 -->
<servlet-name>config</servlet-name>
<!-- 指定将哪个 JSP 页面配置成Servlet -->
<jsp-file>/config.jsp</jsp-file>
<!-- 配置名为 name 的参数,值为 ruby -->
<init-param>
<param-name>name</param-name>
<param-value>ruby</param-value>
</init-param>
<!-- 配置名为 age 的参数,值为 24 -->
<init-param>
<param-name>age</param-name>
<param-value>24</param-value>
</init-param>
</servlet>
<servlet-mapping>
<!-- 指定将 config Servlet 配置到 /config 路径 -->
<servlet-name>config</servlet-name>
<url-pattern>/config</url-pattern>
</servlet-mapping>

  

jsp 文件:

<%@ page contentType="text/html; charset=UTF-8" %>

<html>
<head>
<title>config内置对象</title>
</head>
<body>
<!-- 输出该 JSP 名为 name 的配置参数 -->
name 配置参数的值为:<%=config.getInitParameter("name")%>
<!-- 输出该 JSP 名为 age 的配置参数 -->
age 配置参数的值为:<%=config.getInitParameter("age")%>
</body>
</html>

  

exception 对象

exception 对象是 Throwable 的实例,代表 JSP 脚本中产生的错误和异常,是 JSP 页面异常机制的一部分。

JSP 中的异常都可交给错误处理页面处理。

如:

首先需要在其他出现异常的页面的 page 指令中指定 errorPage 是下面的页面:

<%@ page contentType="text/html; charset=UTF-8" language="java" errorPage="error.jsp" %>

又或者在 web.xml 中配置如下内容:

error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/error.jsp</location>
</error-page>

error.jsp

<%@ page contentType="text/html; charset=UTF-8" isErrorPage="true" %>

<html>
<head>
<title>error</title>
<link href="assets/prism/prism.css" rel="stylesheet" />
</head> <body>
异常类型:<pre><code class="language-java"></code><%=exception.getClass()%></code></pre><br/>
异常信息:<pre><code class="language-java"><%=exception.getMessage()%></code></pre><br/>
错误堆栈:<pre><code class="language-java"></code><%=exception.getStackTrace()%></code></pre><br/> <script src="assets/prism/prism.js"></script>
</body>
</html>

  

out 对象:

out 对象代表一个页面输出流,通常用于在页面上输出变量值及常量。一般在使用输出表达式的地方,都可以用 out 对象来达到同样效果。

如:

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ page import="java.sql.*" %> <html>
<head>
<title>out 测试</title>
</head>
<body>
<%
// 注册数据库驱动
Class.forName("com.mysql.jdbc.Driver");
// 获取数据库连接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jsp", "root", "root");
// 创建 Statement 对象
Statement stmt = conn.createStatement();
// 执行查询,获得 ResultSet 对象
ResultSet rs = stmt.executeQuery("select * from person");
%>
<table border="1" width="400">
<%
// 遍历结果集
while(rs.next()) {
// 输出表格行
out.println("<tr>");
// 输出表格列
out.println("<td>");
// 输出结果集第一列的值
out.println(rs.getString(1));
// 关闭表格列
out.println("</td>");
// 开始表格列
out.println("<td>");
// 输出结果集第二列的值
out.println(rs.getString(2));
// 关闭表格列
out.println("</td>");
// 关闭表格行
out.println("</tr>");
}
%>
</table>
</body>
</html>

所有使用 out 的地方,都可使用输出表达式来代替,而且使用输出表达式更加简洁。

我们把上面的写法换成输出表达式:

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ page import="java.sql.*" %> <html>
<head>
<title>out 测试</title>
</head>
<body>
<%
// 注册数据库驱动
Class.forName("com.mysql.jdbc.Driver");
// 获取数据库连接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jsp", "root", "root");
// 创建 Statement 对象
Statement stmt = conn.createStatement();
// 执行查询,获得 ResultSet 对象
ResultSet rs = stmt.executeQuery("select * from person");
%>
<table border="1" width="400">
<%
// 遍历结果集
while(rs.next()) {
%>
<tr>
<td><%=rs.getString(1)%></td>
<td><%=rs.getString(2)%></td>
</tr>
<%
}
%>
</table>
</body>
</html>

我们可以明显看到,输出结果集的代码量更少了,并且结构也更加的清晰。

pageContext 对象

这个对象代表页面上下文,该对象主要用于访问 JSP 之间的共享数据。使用 pageContext 可以访问 page、request、session、application 范围的变量。

pageContext 是 PageContext 类的实例,它提供了如下两个方法来访问 page、request、session、application 范围的变量。

1、getAttribute(String name):取得 page 范围内的 name 属性。

2、getAttribute(String name, int scope):取得指定范围内的 name 属性,其中 scope 可以是如下 4 个值。

 PageContext.PAGE_SCOPE:对应于 page 范围

 PageContext.REQUEST_SCOPE:对应于 request 范围

 PageContext.SESSION_SCOPE:对应于 session 范围

 PageContext.APPLICATION_SCOPE:对应于 application 范围

与 getAttribute() 方法对应,PageContext 也提供了两个对应的 setAttribute() 方法,用于将指定变量放入 page、request、session、application 范围内。

<%@ page contentType="text/html; charset=UTF-8" %>

<html>
<head>
<title>pageContext</title>
</head>
<body>
<%
// 使用 pageContext 设置属性,该属性默认在 page 范围内
pageContext.setAttribute("page", "hello");
// 使用 request 设置属性,该属性默认在 request 范围内
request.setAttribute("request", "hello");
// 使用 pageContext 将属性设置在 request 范围内
pageContext.setAttribute("request2", "hello", pageContext.REQUEST_SCOPE);
// 使用 session 将属性设置在 session 范围内
session.setAttribute("session", "hello");
// 使用 pageContext 将属性设置在 session 范围内
pageContext.setAttribute("session2", "hello", pageContext.SESSION_SCOPE);
// 使用 application 将属性设置在 application 范围内
application.setAttribute("application", "hello");
// 使用 pageContext 将属性设置在 application 范围内
pageContext.setAttribute("application2", "hello", pageContext.APPLICATION_SCOPE);
%>
<h3>获取各属性的值</h3>
<p>page 范围的 page 属性值:<%=pageContext.getAttribute("page")%></p>
<p>request 范围的 request 属性值:<%=request.getAttribute("request")%></p>
<p>request 范围的 request2 属性值:<%=request.getAttribute("request2")%></p>
<p>session 范围的 session 属性值:<%=session.getAttribute("session")%></p>
<p>session 范围的 session2 属性值:<%=session.getAttribute("session2")%></p>
<p>application 范围的 application 属性值:<%=application.getAttribute("application")%></p>
<p>application 范围的 application2 属性值:<%=application.getAttribute("application2")%></p>
</body>
</html>

  

request 对象:

request 对象是 JSP 中重要的对象,每个 request 对象封装着一次用户请求,并且所有的请求参数都被封装在 request 对象中,因此 request 对象是获取请求参数的重要途径。

1、获取请求头/请求参数

String getParameter(String paramName):获取 paramName 请求参数的值。

Map getParameterMap(): 获取所有请求参数名和参数值组成的 Map 对象。

Enumeration getParameterNames():获取所有请求参数名所组成的 Enumeration 对象。

String[] getParameterValues(String name):name 请求参数的值,当该请求参数有多个值时,该方法将返回多个值所组成的数组。

HttpServletRequest 提供了如下方法来访问请求头:

String getHeader(String name):获取指定请求头的值。

java.util.Enumeration<String> getHeaderNames():获取所欲请求头的名称。

java.util.Enumeration<String> getHeaders(String name):获取指定请求头的多个值。

int getIntHeader(String name):获取指定请求头的值,并将该值转为整数值。

并不是每个表单域都会生成请求参数,而是有 name 属性的表单域才生成请求参数。关于表单域和请求参数的关系遵循如下四点:

a、每个有 name 属性的表单域对应一个请求参数。

b、如果多个表单域有相同的 name 属性,则多个表单域只生成一个请求参数,只是该参数有多个值。

c、表单域的 name 属性指定请求参数名,value 指定请求参数值。

d、如果某个表单域设置了 disabled="disabled" 属性,则该表单域不再生成请求参数。

request示例:

form.jsp

<%@ page contentType="text/html; charset=UTF-8" %>

<html>
<head>
<title>form</title>
</head>
<body>
<form method="POST" action="request1.jsp">
用户名:<br /><input type="text" name="name"><hr/> 性别:<br />
男:<input type="radio" name="gender" value="男">
女:<input type="radio" name="gender" value="女"><hr/> 喜欢的颜色:<br />
红:<input type="checkbox" name="color" value="红">
蓝:<input type="checkbox" name="color" value="蓝">
绿:<input type="checkbox" name="color" value="绿"><hr/> 来自的国家:<br />
<select name="country">
<option value="中国">中国</option>
<option value="美国">美国</option>
<option value="俄罗斯">俄罗斯</option>
</select><hr/> <input type="submit" value="提交">
<input type="reset" value="重置">
</form>
</body>
</html>

  

request1.jsp

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ page import="java.util.*" %> <html>
<head>
<title>获取请求头/请求参数</title>
</head>
<body>
<%
// 获取所有请求头的名称
Enumeration<String> headerNames = request.getHeaderNames();
while(headerNames.hasMoreElements())
{
String headerName = headerNames.nextElement();
// 获取每个请求、及其对应的值
out.println(headerName + "-->" + request.getHeader(headerName) + "<br />");
}
out.println("<hr/>"); // 设置解码方式
request.setCharacterEncoding("UTF-8");
// 下面依次获取表单域的值
String name = request.getParameter("name");
String gender = request.getParameter("gender");
// 如果某个请求参数有多个值,将使用该方法获取多个值
String[] colors = request.getParameterValues("color");
String nation1 = request.getParameter("country");
%> <!-- 下面依次输出表单域的值 -->
你的名字:<%=name%><hr/>
你的性别:<%=gender%><hr/>
<!-- 输出复选框获取的数组值 -->
你喜欢的颜色:<% for(String c: colors)
out.println(c + " ");%><hr/>
你来自的国家:<%=nation1%><hr/>
</body>
</html>

  

获取包含非西欧字符的 GET 请求参数:

<%@ page contentType="text/html; charset=UTF-8" %>

<html>
<head>
<title>request2</title>
</head>
<body>
<%
// 获取请求里包含的查询字符串
String rawQueryStr = request.getQueryString();
out.println("原始查询字符串为:" + rawQueryStr + "<hr/>");
// 使用 URLDecoder 解码字符串
String queryStr = java.net.URLDecoder.decode(rawQueryStr, "UTF-8");
out.println("解码后的查询字符串为:" + queryStr + "<hr/>");
// 以 & 号分解查询字符串
String[] parameterPairs = queryStr.split("&");
for(String parameterPair : parameterPairs)
{
out.println("每个请求参数名、值为:" + parameterPair + "<br />");
// 以 = 来分解请求参数名和值
String[] nameValue = parameterPair.split("=");
out.println(nameValue[0] + "参数的值是:" + nameValue[1] + "<hr>");
}
%>
</body>
</html>

  

也可以在获取请求参数之后对请求参数值重新编码,也就是先将其转换成字节数组,再将字节数组重新解码成字符串。如:

// 获取原始的请求参数值
String rawName = request.getParameter("name");
// 将请求参数值使用 ISO-8859-1 字符串分解成字节数组
byte[] rawBytes = rawName.getBytes("ISO-8859-1");
// 将字节数组重新解码成字符串
String name = new String(rawBytes, "UTF-8");

  

2、操作 request 范围的属性

HttpServletRequest 还包含如下两个方法,用于设置和获取 request 范围的属性。

setAttribute(String attrName, Object attrValue):将 attrValue 设置成 request 范围的属性。

Object getAttribute(String attrName):获取 request 范围属性。

当 forward 用户请求时,请求的参数和请求属性都不会丢失。

3、执行 forward 或 include

request 还有一个功能就是执行 forward 和 include,也就是代替 JSP 所提供的 forward 和 include 动作指令。前面需要 forward 时都是使用 JSP 的 forward 指令,实际上 request 对象也可以执行 forward。

HttpServletRequest 类提供了一个 getRequestDispatcher(String path) 方法,其中 path 就是希望 forward 或者 include 的目标路径,该方法返回 RequestDispatcher,该对象提供了如下两个方法:

a、forward(ServletRequest request, ServletResponse response):执行 forward。

b、include(ServletRequest request, ServletResponse response):执行 include。

如下代码可以将 a.jsp 页面 include 到本页面中:

request.getRequestDispatcher("/a.jsp").forward(request, response);

如下代码可以将请求 forward 到 a.jsp 页面:

request.getRequestDispatcher("/a,jsp").forward(request, response);

注意:使用 request 的 getRequestDispatcher(String path) 方法时,该 path 字符串必须以斜线开头。

response 对象:

response 代表服务器对客户端的响应。大部分时候,程序无须使用 response 来响应客户端请求,因为有个更简单的响应对象 -- out,它代表页面输出流,直接使用 out 生成响应更简单。

但 out 是 JspWriter 的实例,JspWriter 是 Writer 的子类,Writer 是字符流,无法输出非字符内容,假如需要在页面中动态生成一副位图、或者输出一个 PDF 文档,使用 out 作为响应对象将无法完成,此时必须使用 response 作为响应输出。

1、response 响应生成非字符响应

对于需要生成非字符响应的情况,就应该使用 response 来响应客户端请求。下面的 JSP 页面将在客户端生成一张图片。response 是 HttpServletResponse 接口的实例,该接口提供了一个 getOutputStream() 方法,该方法返回响应输出字节流。

如下,输出一张图片:

img.jsp

<!-- 通过 contentType 指定响应数据是图片 -->
<%@ page contentType="image/png" %>
<%@ page import="java.awt.image.*,javax.imageio.*,java.io.*,java.awt.*" %> <%
// 创建 BufferedImage 对象
BufferedImage image = new BufferedImage(340, 160, BufferedImage.TYPE_INT_RGB);
// 以 Image 对象获取 Graphics 对象
Graphics g = image.getGraphics();
// 使用 Graphics 画图,所画的图将会出现在 image 对象中
g.fillRect(0, 0, 400, 400);
// 设置颜色:红
g.setColor(new Color(255, 0, 0));
// 画出一段弧
g.fillArc(20, 20, 100, 100, 30, 120);
// 设置颜色:绿
g.setColor(new Color(0, 255, 0));
// 画出一段弧
g.fillArc(20, 20, 100, 100, 150, 120);
// 设置颜色:蓝
g.setColor(new Color(0, 0, 255));
// 画出一段弧
g.fillArc(20, 20, 100, 100, 270, 120);
// 设置颜色:黑
g.setColor(new Color(0, 0, 0));
g.setFont(new Font("Arial Black", Font.PLAIN, 16));
// 画出三个字符串
g.drawString("red:climb", 200, 60);
g.drawString("green:swim", 200, 100);
g.drawString("blue:jump", 200, 140);
g.dispose();
// 将图像输出到页面响应
ImageIO.write(image, "png", response.getOutputStream());
%>

  

使用方法 <img src="/img.jsp">

以上页面的 contentType 指定为 image/png,这表明服务器响应是一张 PNG 图片。接着创建了一个 BufferedImage 对象(代表图像),并获取该 BufferedImage 的 Graphics 对象(代表画笔),然后通过 Graphics 向 BufferedImage 中绘制图形,最后一行代码直接将 BufferedImage 作为响应发送给客户端。

2、重定向

重定向是 response 的另外一个用处,与 forward 不同的是,重定向会丢失所有的请求参数和 request 范围属性,因为重定向将生成第二次请求,与前一次请求不在同一个 request 范围内,所以发送一次清的请求参数和 request 范围属性都会丢失。

HttpServletResponse 提供了一个 sendRedirect(String path) 方法,该方法用于重定向到 path 资源,即重新向 path 资源发送请求。

如:

redirect.jsp

<%@ page contentType="text/html; charset=UTF-8" %>

<%
// 生成页面响应
out.println("====");
// 重定向到 redirect-result.jsp 页面
response.sendRedirect("redirect-result.jsp");
%>

  

redirect-result.jsp

<%@ page contentType="text/html; charset=UTF-8" %>

<html>
<head>
<title>redirect result</title>
</head>
<body>
被重定向的页面<br/>
name 请求参数的值: <%=request.getParameter("name")%>
</body>
</html>

  

我们在第一个页面的链接后面加上一个get请求参数:http://localhost:8080/jsp/redirect.jsp?name=awk,然后我们在重定向的页面会发现获取到的参数却是 null。

这就说明,我们的 request 里面的参数已经丢失了。

forward 与 redirect 的三个区别:

a、执行 forward 后依然是上一次请求,执行 redirect 后生成第二次请求

b、forward 的目标页面可以访问原请求的参数,因为依然是同一次请求,所有原请求的请求参数、request 范围属性全部存在。redirect 的目标页面不能访问原请求的请求参数、request 范围属性,因为 redirect 产生了一个新的请求。

c、forward 的时候地址栏 URL 不会发生变化。redirect 的时候地址栏 URL 是 redirect 的时候 sendRedirect 参数的值。

3、增加 Cookie

response 对象提供了如下方法:

void addCookie(Cookie cookie):增加cookie

增加 cookie 请按如下步骤进行。

a、创建 Cookie 实例,Cookie 的构造器为 Cookie(String name, String value)

b、设置 Cookie 的生命期限,即该 Cookie 在多长时间内有效。

c、向客户端写 Cookie

<%@ page contentType="text/html; charset=UTF-8" %>

<html>
<head>
<title>cookie</title>
</head>
<body>
<%
// 获取请求参数
String name = request.getParameter("name");
// 以获取到的请求参数为值,创建一个 Cookie 对象
Cookie c = new Cookie("username", name);
// 设置 Cookie 对象的生存期限(这里是 24 小时)
c.setMaxAge(24 * 3600);
// 向客户端增加 Cookie 对象
response.addCookie(c);
%>
</body>
</html>

  

访问客户端的 cookie,request 对象提供了 getCookies 方法,该方法返回客户端机器上所有 Cookie 组成的数组。

<%@ page contentType="text/html; charset=UTF-8" %>

<html>
<head>
<title>读取 cookie</title>
</head>
<body>
<%
// 获取本站在客户端上保留的所有 cookie
Cookie[] cookies = request.getCookies();
// 遍历客户端上的每个 Cookie
for (Cookie c : cookies) {
// 如果 Cookie 的名为 username,表明该 Cookie 是需要访问的 Cookie
if (c.getName().equals("username")) {
out.println(c.getValue());
}
}
%>
</body>
</html>

  

默认情况下,Cookie 值不允许出现中文字符,如果需要值为中文内容的 Cookie,我们可以借助于 java.net.URLEncoder 先对中文字符串进行编码,将编码后的结果设置为 Cookie 值。当程序要读取 Cookie 时,则应该先读取,然后使用 java.net.URLDecoder 对其进行解码。

<%@ page contentType="text/html; charset=UTF-8" %>

<html>
<head>
<title>中文 Cookie</title>
</head>
<body>
<%
// 以编码后的字符串为值,创建一个 Cookie 对象
Cookie c = new Cookie("cnName", java.net.URLEncoder.encode("李白", "utf-8"));
// 设置 Cookie 对象的生存期限
c.setMaxAge(24 * 3600);
// 向客户端增加 Cookie 对象
response.addCookie(c); // 获取本站在客户端上保留的所有 Cookie
Cookie[] cookies = request.getCookies();
// 遍历客户端上的每个 Cookie
for (Cookie cookie : cookies) {
// 如果 Cookie 的名为 cnName,表明该 Cookie 是需要访问的 Cookie
if (cookie.getName().equals("cnName")) {
// 使用 java.net.URLDecoder 对 Cookie 值进行解码
out.println(java.net.URLDecoder.decode(cookie.getValue()));
}
}
%>
</body>
</html>

  

session 对象

session 对象代表一次用户会话。一次用户会话的含义是:从客户端浏览器连接服务器开始,到客户端浏览器与服务器断开为止,这个过程就是一次会话。

session 范围内的属性可以在多个页面的跳转之间共享。一旦关闭浏览器,即 session 结束,session 范围内的属性将全部丢失。

session 对象是 HttpSession 的实例,HttpSession 有如下两个常用的方法。

setAttribute(String attrName, Object attrValue):设置 session 范围内 attrName 属性的值为 attrValue。

getAttribute(String attrName):返回 session 范围内 attrName 属性的值。

使用 session 示例:

shop.jsp

<%@ page contentType="text/html; charset=UTF-8" %>

<html>
<head>
<title>选择物品购买</title>
</head>
<body>
<form method="POST" action="process-buy.jsp">
书籍:<input type="checkbox" name="item" value="book"/><br/>
电脑:<input type="checkbox" name="item" value="computer"/><br/>
汽车:<input type="checkbox" name="item" value="car"/><br/>
<input type="submit" value="购买" />
</form>
</body>
</html>

  

process-buy.jsp

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ page import="java.util.*" %> <%
// 取出 session 范围的 itemMap 属性
Map<String, Integer> itemMap = (Map<String, Integer>)session.getAttribute("itemMap");
// 如果 Map 对象为空,则初始化 Map 对象
if (itemMap == null)
{
itemMap = new HashMap<String, Integer>();
itemMap.put("书籍", 0);
itemMap.put("电脑", 0);
itemMap.put("汽车", 0);
}
// 获取上一个页面的请求参数
String[] buys = request.getParameterValues("item");
// 遍历数组的各元素
for (String item : buys)
{
// 如果 item 为 book,表示选择购买书籍
if (item.equals("book"))
{
int num1 = itemMap.get("书籍").intValue();
// 将书籍 key 对应的数量加 1
itemMap.put("书籍", num1 + 1);
}
else if (item.equals("computer"))
{
int num2 = itemMap.get("电脑").intValue();
itemMap.put("电脑", num2 + 1);
}
else if (item.equals("car"))
{
int num3 = itemMap.get("汽车").intValue();
itemMap.put("汽车", num3 + 1);
}
} // 将 itemMap 对象放到 session 范围中
session.setAttribute("itemMap", itemMap);
%> <html>
<head>
<title>process buy</title>
</head>
<body>
你购买的物品:<br/>
书籍:<%=itemMap.get("书籍")%>本<br/>
电脑:<%=itemMap.get("电脑")%>台<br/>
汽车:<%=itemMap.get("汽车")%>辆<br/>
<p><a href="shop.jsp">再次购买</a></p>
</body>
</html>

  

关于 session 还有一点需要注意的,session 保存的信息需要保存到 web 服务器的硬盘上,所以要求 session 里的属性值必须是可序列化的,否则将会引发不可序列化的异常。

session 的属性值可以是任何可序列化的 Java 对象。

JSP 脚本中的 9 个内置对象的更多相关文章

  1. JSP脚本中的9个内置对象

    JSP脚本中包含9个内置对象,这9个内置对象都是Servlet API接口的实例,只是JSP规范对它们进行了默认初始化.也就是说它们已经是对象,可以直接使用. 我们随意打开一个由JSP页面生成的Ser ...

  2. JSP学习(三)JSP中的九个内置对象

    JSP中的九个内置对象 NO. 内置对象 类型 1 pageContext javax.servlet.jsp.PageContext 2 request javax.servlet.http.Htt ...

  3. java web学习总结(二十五) -------------------JSP中的九个内置对象

    一.JSP运行原理 每个JSP 页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理.JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet ...

  4. JavaWeb---总结(十七)JSP中的九个内置对象

    一.JSP运行原理 每个JSP 页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理.JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet ...

  5. JavaWeb学习总结(十七)——JSP中的九个内置对象

    一.JSP运行原理 每个JSP 页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理.JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet ...

  6. javaWeb学习总结(8)- JSP中的九个内置对象(4)

    一.JSP运行原理 每个JSP 页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理.JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet ...

  7. JavaWeb学习 (十六)————JSP中的九个内置对象

    一.JSP运行原理 每个JSP 页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理.JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet ...

  8. JavaWeb(十七)——JSP中的九个内置对象

    一.JSP运行原理 每个JSP 页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理.JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet ...

  9. JavaWeb学习总结(十七)——JSP中的九个内置对象(转)

    一.JSP运行原理 每个JSP 页面在第一次被访问时,WEB容器都会把请求交给JSP引擎(即一个Java程序)去处理.JSP引擎先将JSP翻译成一个_jspServlet(实质上也是一个servlet ...

随机推荐

  1. 420. Count and Say【LintCode java】

    Description The count-and-say sequence is the sequence of integers beginning as follows: 1, 11, 21, ...

  2. 【sed】常用命令

    替换 替换某一整行 sed '1c hello' test #将第一行替换为hello str1替换为str2 sed 's/^str1.*/str2/' filename #以str1开头 sed ...

  3. centos7环境下mysql安装

    1.去官网下载合适的yum源安装包 https://dev.mysql.com/downloads/repo/yum/ 2.yum 本地安装 命令:yum localinstall mysql57-c ...

  4. 团队作业——王者光耀:team

    光耀101  <光耀101>是福州大学数计学院计算机专业推出的中国首部程序猿脱发养成节目.由张栋担任发起人,刘晨瑶.畅畅担任导师.  该节目召集了你猜多少位选手,通过任务.训练.考核,让选 ...

  5. HDU 5391Z ball in Tina Town 数论

    题目链接: hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5391 bc:  http://bestcoder.hdu.edu.cn/contests/c ...

  6. 周总结<5>

    周次 学习时间 新编写代码行数 博客量(篇) 学到知识点 12 10 100 1 路由器的设置(ospf协议):网页设计:哈夫曼树(C语言数构) Html案例: <!DOCTYPE html P ...

  7. [并查集] How Many Tables

    题目描述 Today is Ignatius' birthday. He invites a lot of friends. Now it's dinner time. Ignatius wants ...

  8. OpenLayers 3 入门教程

    OpenLayers 3 入门教程摘要OpenLayers 3对OpenLayers网络地图库进行了根本的重新设计.版本2虽然被广泛使用,但从JavaScript开发的早期发展阶段开始,已日益现实出它 ...

  9. (二)MySQL中级篇

    1.视图view 视图是一个虚拟表,其内容由查询定义.定义视图的筛选可以来自当前或其它数据库的一个或多个表,或者其它视图. 视图的优点: ①简化了操作,把经常使用的数据定义为视图. ②安全性,用户只能 ...

  10. HTMLA内联框架

    <head> <meta charset="utf-8" /> <title>内联框架</title> </head> ...