前言
前面的博客说到了servlet的接口和类,这次来说下Servlet的会话跟踪技术。
正文
【会话跟踪】概念 |
Http 协议是一个无状态的协议,当客户端浏览器一次请求到来,服务器端返回响应之后,两者之间的连接就断开了,服务器端并不保存每次的连接信息,如何维系客户端和服务器之间的连接,这就需要会话跟踪技术的支持。会话跟踪技术主要用来web服务器端跟踪客户状态,维护客户端和服务器之间的连接。
常见的会话跟踪技术 |
- Cookie
第一次请求时服务器主动发一小段信息给浏览器(即Cookie),下次请求时浏览器会自动附带这一小段信息发送给服务器,服务器读取Cookie 识别用户。 - 隐藏的表单域
将sessionID 隐藏在html表单中提交到服务器,这个sessionID在浏览器页面不显示。
非常适合不需要大量数据存储的会话应用 - URL重写
在url 结尾附加sessionID(sessionID) 标识,服务器通过会话ID 识别不同用户。 - Session
服务器为每个用户创建一个Session对象保存到内存中,生成一个sessionID放入Cookie中发送给浏览器,下次访问时sessionID会随着Cookie传回来,服务器再根据sessionID找到对应Session对象(Java领域特有)。
Cookie |
现在所有主流浏览器都支持Cookie ,以至于HTTP协议为它定义了一些新的HTTP首部Set-cookie 。
Cookie 的规范
- Cookie 通过请求头/响应头 在服务器与客户端之间传输,大小限制为4KB;
- 一台服务器在一个客户端最多保存20个Cookie;
- 一个浏览器最多保存300个Cookie;
Cookie类 及API : 访问链接
Servlet中的Cookie的使用:
package com.dmsd.servlet;
import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class CookieTest extends HttpServlet {
public void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException {
doPost(request,response);
}
public void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException,IOException {
response.setContentType("text/html;charset = gb2312");
request.setCharacterEncoding("gb2312");
PrintWriter out = response.getWriter();
String username = request.getParameter("userName");
//创建cookie实例,需要传入属性名称和属性值,两个都是String类型
Cookie userCookie = new Cookie("userName",userName);
Cookie pwdCookie = new Cookie("pwd",request.getParameter("pwd"));
if(request.getParameter("saveCookie") != null && request.getParameter("saveCookie").equals("Yes")){
userCookie.setMaxAge(7*24*60*60);// 设置Cookie的保存时间
pwdCookie.setMaxAge(7*24*60*60);
out.print("你的信息已经保存在Cookie中");
else{
userCookie.setMaxAge(0);
pwdCookie.setMaxAge(0);
out.print("你的信息已经从Cookie中删除");
}
response.addCookie(userCookie);// 发送Cookie到客户端
response.addCookie(pwdCookie);
}
}
}
局限:
Cookie是键值对存储结构,只能保存String类型的数据;
如果用户在浏览器端设置了禁用Cookie,它就失效了;
Cookie 不支持中文,需要在存储时编码,取出时解码;
因为Cookie将信息保存到客户端,所以会有安全性的问题;
隐藏的表单域 |
<input type="hidden" name="sessionid" value="12345">
属性解释:
type="hidden"定义隐藏域;
name属性定义隐藏域的名称,要保证数据的准确采集,必须定义一个独一无二的名称;
value属性定义隐藏域的值
例如:<input type=”hidden” name=”ExPws” value=”dd”>
局限:
当客户端点击常规的超文本链接时导致表单不会提交,这时候隐藏的表单域也就失效了。
URL重写 |
上面提到,用户可能关闭浏览器的Cookie功能,这样基于Cookie的Session 技术就不能用了,Sun公司提供了一种替代性的方案,就是URL重写,将本来保存在Cookie中的用于标识不同客户端的SessionID放在url后面,这样,即使用户关闭了浏览器的Cookie功能,Session还是能正常使用,服务器端通过SESSIONID 关键字来获取会话值。
实现方式:
// 1、手动方式
url;jsessionid = ……
//2、api方式
// 进行所有URL 重写
encodeURL(java.lang.String url)
// 进行重定向URL 重写
encodeRedirectURL(java.lang.String url)
举个例子
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//创建session
HttpSession session = request.getSession();
session.setAttribute("greeting", "hello");
System.out.println("sessionID :" + session.getId());
// 请求url,将浏览器设置cookie 禁用,才会有jsessionid
String url = "/SessionTest/session";
String newUrl = response.encodeRedirectURL(url);
System.out.println("newURL:" + newUrl);
}
运行结果:
Session |
服务器给每个客户端分配一个不重复的ID号用来区分不同的客户端,而对应各个客户需要保存的数据保存在服务器的内存中,这样,每个客户端Cookie 中只保存一个ID号,而将实际需要保存的数据放在服务器内存中,服务器可以存放的对象就突破了String类型的限制,数据不需要写到客户端的文本中。
在所有的会话跟踪技术中, Session是功能最强大,最多的. 每个用户可以没有或者有一个HttpSession对象, 并且只能访问他自己的Session对象。
HttpSession 是Java Servlet API 中提供的对Session机制的实现规范,这是个接口,建立在URL 重写或Cookie 的基础上,由Servlet容器来实现。
HttpSession的常用方法
方法 | 说明 |
---|---|
Object getAttribute(String name) | 从session中返回指定name的属性的值,如果指定的name属性不存在,则返回null |
Enumeration getAttributeNames() | 返回session中所有的属性名称,并且封装在Enumeration对象中返回 |
void setAttribute(String name,Object value) | 在session中设置名称为name的属性,属性值为一个对象value |
void removeAttribute(String name) | 从session中指定名称为name的属性 |
void invalidate() | 废除这个session,并且释放session关联的对象 |
Boolean isNew() | 用于检测此session是否为新创建的 |
void setMaxInactiveInterval(int time) | 设置在没有访问的情况下,会话在服务器端被自动废除的时间,单位是秒 |
举个例子
// 登录操作类
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String userName = request.getParameter("userName");
String password = request.getParameter("password");
//获取session对象
HttpSession session = request.getSession();
//如果用户名和密码都是“admin”就登录成功
if("admin".equals(userName) && "admin".equals(password)) {
//把用户信息保存到session中
session.setAttribute("userName", userName);
session.setAttribute("msg", "登录成功");
request.getRequestDispatcher("/Result").forward(request, response);
}else{
request.getRequestDispatcher("/Login.html").forward(request, response);
}
}
// 登录之后处理类
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取session
HttpSession session = request.getSession();
String userName = (String)session.getAttribute("userName");
if(userName == null){
request.getRequestDispatcher("Login.html").forward(request, response);
return;
}
}
总结
Sevlet 中的会话跟踪机制先介绍到这里,感谢您的阅读!