HTTP协议是一种无状态协议。一个用户向服务器发出请求(request
),然后服务器返回响应( response
),在服务器端不保留连接的有关信息,因此当下一次连接时,服务器已没有以前的连接信息了,无法判断这一次连接和以前的连接是否属于同一用户。当一个用户访问一个Web服务目录时,可能会在这个服务目录的几个页面反复连接、反复刷新一个页面或不断地向一个页面提交信息等,服务器应当通过某种办法知道这是同一个用户。Tomcat服务器可以使用内置 session
对象(会话)记录有关连接的信息。内置对象 session
由 Tomcat服务器负责创建, session
是实现了 Httpsession
接口类的一个实例,可以在Tomcat服务器的 webapps\ tomcat-docs\servletapi
中查找 Httpsession
接口的方法。
1、session对象的id
用户在访问一个Web服务目录期间,服务器为该用户分配一个 session
对象
(称作用户的会话),服务器可以在各个页面使用这个 session
记录当前用户的有关信息。服务器保证不同用户的 session
对象互不相同。 session
对象被分配了一个String
类型的id
号, Tomcat服务器同时将这个id
号发送到用户端,存放在用户的 Cookie
中。这样, session
对象和用户之间就建立起一一对应的关系,即每个用户都对应着一个session
对象(称作用户的会话),不同用户的 session
对象互不相同,具有不同的id
号码。当用户再访问连接该Web服务目录的其他页面时,或从该Web服务目录连接到其他Web服务器再回到该Web服务目录时, Tomcat服务器不再分配给用户的新 session
对象,而是使用完全相同的一个,直到 session
对象达到了最大生存时间或服务器关闭,服务器取消用户的 session
对象,即和用户的会话对应关系消失。当用户重新连接到该Web服务目录时,服务器为该用户再创建一个新的 session
对象。
- 注意:同一个用户在不同的Web服务目录中的
session
是互不相同的。 - 实例
example3_14_a.jsp
<%@ page contentType="text/html;charset=gb2312" %>
<HTML><body bgcolor=cyan>
我是example3_14_a.jsp页面<br>输姓名连接到example3_14_b.jsp
<% String id=session.getId();
out.println("<br>您的session对象的ID是:<br>"+id);
%>
<form action="example3_14_b.jsp" method=post name=form>
<input type="text" name="boy">
<input type="submit" value="送出" name=submit>
</form>
</body></HTML>
example3_14_b.jsp
<%@ page contentType="text/html;charset=gb2312" %>
<HTML><body bgcolor=#EECCFF>
我是example3_14_b.jsp页面
<% String id=session.getId();
out.println("<br>您的session对象的ID是:<br>"+id);
%>
<BR> 连接到example3_14_a.jsp的页面。<br>
<a href="example3_14_a.jsp">example3_14_a.jsp</A>
</body></HTML>
2、session对象与URL重写
session
对象是否能和用户建立起一一对应关系依赖于用户端是否支持 Cookie
。如果用户端不支持 Cookie
,那么用户在不同网页之间的 session
对象可能是互不相同的,因为服务器无法将id
存放到用户端,就不能建立 session
对象和用户的一一对应关系。如果用户端不支持 Cookie
,JSP页面可以通过URL重写来实现 session
对象的唯一性。
URL重写,就是当用户从一个页面重新连接到一个页面时,通过向这个新的URL 添加参数,把 session
对象的id
传带过去,这样就可以保障用户在该网站各个页面中的 session
对象是完全相同的。可以使用 response
对象调用 encodeURL(
)或 encode RedirectURL()
方法实现URL重写。比如,如果从 first.jsp
页面连接到 second.jsp
页面,首先在程序片中实现URL重写:
String str = response.encodeRedirectURL("second.jsp");
然后将连接目标写成<%= str%>
即可。
3、session对象存储数据
session
对象驻留在服务器端,该对象调用某些方法保存用户在访问某个Web服务目录期间的有关数据。 session
对象使用下列方法处理数据。
public void setAttribute( String key, Object obj)
。session
对象可以调用该方法将参数Object
指定的对象obj
添加到session
对象中,并为添加的对象指定一个索引关键字如果添加的两个对象的关键字相同,则先前添加的对象被清除。public Object get Attribute( String key)
。获取session
对象索引关键字是key
的对象。由于任何对象都可以添加到session
对象中,因此用该方法取回对象时,应强制转化为原来的类型。public Enumeration get Attribute Names()
。session
对象调用该方法产生一个枚举对象,该枚举对象使用next Elemets()
遍历session
中的各个对象所对应的关键字。public void remove Attribute( String name)
。session
对象调用该方法移除关键字key
对应的对象。
当 session
对象处理数据时,非常类似一个购物车,一个用户访问一个商场(类似一个Web服务目录)期间,可以把商品放入自己购物车,也可以从自己的购物车移出商品。
实例一:
example3_15_a.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body bgcolor="cyan">
<br/>输入姓名:<a href="example3_15_a.jsp">确定姓名页面</a>
<br/>选择图书:<a href="example3_15_b.jsp">选择图书页面</a>
<br/>结账:<a href="example3_15_c.jsp">结账页面</a>
<p>输入姓名
<form action="" method="post" name="form">
<input type="text" name="name">
<input type="submit" value="确定" name="submit">
</form>
<%
String name = request.getParameter("name");
if(name == null){
name="";
}else{
session.setAttribute("name", name); //将名字存入用户的session中
}
%>
</body>
</html>
example3_15_b.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body bgcolor="cyan">
<br/>输入姓名:<a href="example3_15_a.jsp">确定姓名页面</a>
<br/>选择图书:<a href="example3_15_b.jsp">选择图书页面</a>
<br/>结账:<a href="example3_15_c.jsp">结账页面</a>
<p>请选择购买的书籍:
<form action="" method="post" name="form">
<input type="checkbox" name="choice" value="Java教程32.5元">Java教程32.5元
<input type="checkbox" name="choice" value="数据库原理23元">数据库原理23元<br/>
<input type="checkbox" name="choice" value="操作系统35元">操作系统35元
<input type="checkbox" name="choice" value="C语言教程24.5元">C语言教程24.5元<br/>
<input type="submit" value="提交" name="submit">
</form>
<%
String book[] = request.getParameterValues("choice");
if(book != null){
StringBuffer str = new StringBuffer();
for(int k = 0;k < book.length;k ++){
str.append(book[k] + "<br>");
}
session.setAttribute("book", str); //将书放入用户的session中
}
%>
</body>
</html>
example3_15_c.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import = "java.util.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body bgcolor="#EEEEFF">
<br/>输入姓名:<a href="example3_15_a.jsp">确定姓名页面</a>
<br/>选择图书:<a href="example3_15_b.jsp">选择图书页面</a>
<br/>结账:<a href="example3_15_c.jsp">结账页面</a>
<%!
public String handleStr(String s){
try{
byte bb[] = s.getBytes("ISO-8859-1");
s = new String(bb,"utf-8");
return s;
}catch(Exception exp){
return s;
}
}
%>
<%
String personName = (String)session.getAttribute("name");
StringBuffer bookMess = null;
if(personName == null || personName.length() == 0){
out.println("到输入名字页面输入姓名");
}else{
bookMess = (StringBuffer)session.getAttribute("book");
}
%>
<%
String buyBook = new String(bookMess);
double sum = 0;
String price[] = buyBook.split("[^0123456789.]");
for(String item:price){
try{
sum += Double.parseDouble(item);
}catch(NumberFormatException exp){
}
}
%>
<br/>
<%= handleStr(personName) %> 购书信息:<br/>
<%= handleStr(buyBook) %><br/>
总价格:<%= sum %>
</body>
</html>
实例二:
example3_16_number.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body bgcolor="#EEDDEE">
<p>随机分给了一个1到100之间的数,猜猜!
<%
int number = (int)(Math.random() * 100) + 1;
session.setAttribute("count", new Integer(0));
session.setAttribute("save", new Integer(number));
%>
<br>输入猜测:
<form action="example3_16_result.jsp" method="post" name="form">
<input type="text" name="guess">
<input type="submit" value="送出" name="submit">
</form>
</body>
</html>
example3_16_large.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body bgcolor="cyan">
<%
Integer integer = (Integer)session.getAttribute("guess");
%>
<p><%= integer %>数大了,请重新猜:
<form action="example3_16_result.jsp" method="post" name="form">
<input type="text" name="guess">
<input type="submit" value="送出" name="submit">
</form>
</body>
</html>
example3_16_small.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body bgcolor="cyan">
<%
Integer integer = (Integer)session.getAttribute("guess");
%>
<p><%= integer %>数小了,请重新猜:
<form action="example3_16_result.jsp" method="post" name="form">
<input type="text" name="guess">
<input type="submit" value="送出" name="submit">
</form>
</body>
</html>
example3_16_success.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body bgcolor="pink">
<%
int count = ((Integer)session.getAttribute("count")).intValue();
int num = ((Integer)session.getAttribute("save")).intValue();
%>
<br>恭喜您,猜对了
<br><b>您共猜了<%= count %>次</b>
<br>这个数字就是<%= num %>
</body>
</html>
example3_16_result.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
String str = request.getParameter("guess");
if(str == null || str.length() == 0){
response.sendRedirect("example3_16_number.jsp");
}else{
int guessNumber = Integer.parseInt(str);
session.setAttribute("guess",new Integer(guessNumber));
Integer integer = (Integer)session.getAttribute("save");
int realnumber = integer.intValue();
if(guessNumber == realnumber){
int n = ((Integer)session.getAttribute("count")).intValue();
n = n + 1;
session.setAttribute("count", new Integer(n));
response.sendRedirect("example3_16_success.jsp");
}else if(guessNumber > realnumber){
int n = ((Integer)session.getAttribute("count")).intValue();
n = n + 1;
session.setAttribute("count", new Integer(n));
response.sendRedirect("example3_16_large.jsp");
}else if(guessNumber < realnumber){
int n = ((Integer)session.getAttribute("count")).intValue();
n = n + 1;
session.setAttribute("count", new Integer(n));
response.sendRedirect("example3_16_small.jsp");
}
}
%>
</body>
</html>
4、session对象的生存期限
一个用户在某个Web服务目录的 session
对象的生存期限依赖于 session
对象是否调用 invalidate()
方法使得 session
无效或 session
对象达到了设置的最长的“发呆”状态时间以及是否关闭服务器。如果关闭服务器,那么用户的 session
消失;所谓“发呆”状态时间是指用户对某个Web服务目录发出的两次请求之间的间隔时间(默认的“发呆”时间是30分钟)。
session
对象可以使用下列方法获取或设置与生存时间有关的信息
public long get Creation Time()
获取session
创建的时间,单位是毫秒(GMT时间,1970年7月1日午夜起至session
创建时刻所走过的毫秒数)。public long get Last Accessed Time()
获取session
最后一次被操作的时间,单位是毫秒。public int get MaxInactiveInterval()
获取session
最长的“发呆”时间(单位是秒)public void set MaxInactiveInterval( int interval)
设置session
最长的“发呆”时间
(单位是秒)。public boolean isNew()
判断session
是否是一个新建的对象。invalidate()
使session
无效。- 实例
example3_17.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import = "java.util.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body bgcolor="cyan">
<%
session.setMaxInactiveInterval(5);
boolean boo = session.isNew();
out.println("<br>如果你是第一次访问当前web服务目录,您的会话是新的");
out.println("<br>如果你不是第一次访问当前web服务目录,您的会话不是新的");
out.println("<br>会话是新的嘛?" + boo);
out.println("<br>欢迎您来到本页面,您的session允许的最长发呆时间为" + session.getMaxInactiveInterval() + "秒");
out.println("<br>您的session的创建时间是" + new Date(session.getLastAccessedTime()));
out.println("<br>您的session的id是" + session.getId());
Long lastTime = (Long)session.getAttribute("lastTime");
if(lastTime == null){
long n = session.getLastAccessedTime();
session.setAttribute("lastTime", new Long(n));
}else{
long m = session.getLastAccessedTime();
long n = ((Long)session.getAttribute("lastTime")).longValue();
out.println("<br>您的发呆时间大约是" +(m-n) + "毫秒,大约" + (m-n)/100 +"秒");
session.setAttribute("lastTime", new Long(m));
}
%>
</body>
</html>