大可制作:QQ群:31564239(asp|jsp|php|mysql)

JSP/Servlet: session (1)

session隐含对象在转换为Servlet之后,对应于 javax.servlet.http.HttpSession类 型之对象, HttpSession负责管理客户端在浏览网站期间的进程(session)信息,也就是每个操作流程间的状态维护,您无需知道进程追踪的细节,就可以 让使用者在数个页面之间浏览而又能保留相关的进程信息,例如在几个页面之间挑选商品并放入购物车,在最后进行结帐工作。

之前在 Cookie 中介绍过进程追踪的三种作法,其适用与不适用的场合各不相同。您可以将何时使用何种技术这个工作交给session(HttpSession)对象来负责,相关的实现细节并不太需要您来注意(当然您愿意的话,建议您还是了解一下会更好)。

举个例来说,session(HttpSession)会默认使用Cookie来追踪进程,如果不行(例如使用者关闭Cookie的使用),则您可以试着 使用URL rewriting,或许服务器会保留一些信息在服务器的内存或数据库甚至文件中,而只传送session id给客户端,之后浏览器在每个请求中包括这个id,以让服务器取出对应的信息,具体的作法依各家容器的实现而不同。

总而言之,您可以使用session(HttpSession)来协助您作进程追踪,而不用担心信息在伺服端是如何保留的,而session id又是如何产生的。

下面简单的示范session的使用方式,实现一个简单的登入网页,您可以大致了解session的使用方式,首先您必须先制作一个简单的HTML表单,它将用来输入使用者名称与密码:

  • form.htm
<html> 
<head><title>登入页面</title></head>
<body>
输入密码登入:<br>
<form action="login.jsp" method="POST">
名称:<input type="text" name="user"> <br>
密码:<input type="password" name="password"> <br>
<input type="submit" value="登入">
</form>
</body>
</html>

接下来撰写登入验证页面login.jsp:
  • login.jsp
<%@page contentType="text/html;charset=Big5"%> 
<%
String user = request.getParameter("user");
String password = request.getParameter("password");
String memberURL =
"http://localhost:8080/myjsp/member.jsp";
String loginFormURL =
"http://localhost:8080/myjsp/form.html";

if(user == null || password == null) {
response.setHeader("Refresh", "0; " + loginFormURL);
}
else if(user.equals("justin") && password.equals("1234")) {
session.setAttribute("user", user);
response.setHeader("Refresh", "3; " + memberURL);
out.println(user + "欢迎登入!3秒后进入会员页面!");
}
else {
response.setHeader("Refresh", "3; " + loginFormURL);
out.println(
"使用者或密码错误,请重新登入(3秒后回到登入表单)");
}
%>

上面这个页面在验证使用者名称与密码无误之后,使用setAttribute()方法,将使用者名称存入session (HttpSession)对象中,setAttribute()可以存入任何的Java对象,在这边存入的属性名称为"user",存入的对象为 String对象,内容为登入者的名称,也就是"justin",然后将客户端重导至会员页面,如果验证的结果不正确,就将客户端重导至登入表单;接下来 撰写会员页面member.jsp:
  • member.jsp
<%@page contentType="text/html;charset=Big5"%> 
<%
String loginFormURL =
"http://localhost:8080/myjsp/form.html";
String user = (String) session.getAttribute("user");
if(user == null) {
response.setHeader("Refresh", "3; " + loginFormURL);
out.println(
"喔喔!您还没登入!不能偷看喔!3秒后进入登入页面");
}
else {
out.println("嗨!" + user + "!");
out.println("会员好康在这边。。。。");
// 立即登出
session.invalidate();
}
%>

getAttribute()可以指定属性名称取得存在session(HttpSession)中的对象,取回的类型是 Object,为了能够使用,您必须将之转换为相对应的类型,在这边则是String类型,如果之前login.jsp中验证通过的话,在这个 member.jsp中就可以取得储存在session中的属性对象,如果取回的是null,表示之前没有设定过user属性,也就是在 login.jsp中没有通过验证,我们必须将之送回登入页面以重新进行登入;invalidate()可以让目前的session对象失效,我们在 member.jsp中执行这个方法,以实现登出的功能(其实也是为了测试的方便而让使用者立即登出)。

上面这个例子中,完全没有牵涉到进程追踪的实现细节(cookie或是URL rewriting等),一切都是交由session对象来负责,而由于session可以储存对象信息,使得进程追踪所关联的信息更为丰富,但却不用增 加您实现进程追踪的困难,不过上面这个例子是在浏览器的Cookie功能有打开的情况下才能正常运作,如果Cookie没有开启,则我们需要作一些额外的 动作,这在下一个主题中讨论。

要注意的是,session并不是线程安全的,由于session会在客户端对话期间存在,所以当有多个线程会存取session时,必须注意到线程安全问题。