会话技术
什么是一次会话
用户通过浏览器访问一个网站,间接访问了多条超链接,直到他关闭浏览器的这个过程 称为一次会话。
通过会话技术,可以实现 下次免登陆功能,商品推荐功能,购物车功能等。
Cookie
简介
Cookie的提出
HTTP协议是无状态的,一旦双方的数据提交完,连接就会断开,再次交互时需要重新建立新连接。而有些应用需要服务器掌握客户端状态,因此便有了Cookie。
Cookie的流程
当浏览器访问服务器时,若服务器需要记录用户状态,就可以在 返回给客户端的响应中放入Set-cookie。浏览器收到后会保存Cookie,当它再次访问服务器时,就会顺带把Cookie放入请求中。
Cookie不可跨域名性
每个域名都有对应的Cookie,服务器只会发送它对应域名的Cookie。
Cookie的相关类和方法
(1)Cookie类可以创一个Cookie对象。该类的部分代码如下所示:
public class Cookie implements Cloneable, Serializable {
private final String name;
private String value;
private String path;
/*
cookie最大生存时间,单位是秒。默认值为-1,
表示仅在本浏览器有效,一旦关闭浏览器cookie就会失效,不会写到硬盘中。
若其值为0,表示删除该cookie(Cookie机制没有提供删除Cookie对应的方法)。
*/
private int maxAge = -1;
/*
Cookie是不可跨域名的,即便是同一级域名,不同二级域名也是不能交接的。
比如www.goole.com和www.image.goole.com的cookie是不能访问的。
但通过domain变量可以设置可访问域名级别,例如cookie.setDomain(".goole.com");
这样只要一级域名是.goole.com的都可以访问
*/
private String domain;
public Cookie(String name,String value);
//省略
(2)response对象的addCookie()方法可以在响应头中加入一个Set-Cookie;
(3)request对象的getCookies()方法可以获取客户端提交的Cookie
示例
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=UTF-8");
Cookie cookie = new Cookie("key", "C2y");
cookie.setMaxAge(1000);
resp.addCookie(cookie);
}
如果放入的value值是中文,则需要对中文进行编码。
String value = "中文";
Cookie cookie = new Cookie("key", URLEncoder.encode(value, "UTF-8"));
取出cookie值时需要进行解码
Cookie[] cookies = req.getCookies();
for (int i = 0; cookies != null && i < cookies.length; i++) {
String key = cookies[i].getName();
String value = URLDecoder.decode(cookies[i].getValue(), "UTF-8");
}
Cookie的路径
一般情况下所有Servlet都可以使用Cookie,Cookie类的成员变量path表示允许访问Cookie的路径。
Cookie cookie = new Cookie("key", "value");
cookie.setPath("/AS");
cookie.setMaxAge(1000);
res.addCookie(cookie);
printWriter.write("该Cookie只有AS可以获取");
Session
简介
Session是另一种记录浏览器状态的机制,前面介绍的Cookie是保存在浏览器,而Session是保存在服务器中。
生命周期和有效期
(1)当用户第一次访问Tomcat里的Servlet,jsp等动态资源时,Session就会自动创建,它保存在内存里。每当用户继续访问,服务器都会更新Session的最后访问时间。
(2)Session的超时时间可以防止Session过多导致内存溢出,服务器会把长时间没有活跃的Session从内存中删除,默认为30分钟。
超时时间可以在单个web.xml文件中设置,这对作用于单个web应用
<session-config>
<session-timeout>20</session-timeout>
</session-config>
此外还可以通过setMaxInactiveInterval()方法设置,单位是秒。
(3)session周期是指不活动的时间,每当用户访问一次session,则会重新计时。而cookie是按累计时间来算,不管用户有没有访问过cookie。
实现原理
(1)当浏览器第一次请求服务器时,服务器会创建对应的session,然后将此session的唯一标识信息 SessionID 返回给浏览器。
(2)浏览器接收到服务器返回的SessionID 信息后,放入Cookie 中。当浏览器第二次访问服务器时,服务器会从cookie中取出sessionID,根据ID查找对应Session 信息,根据该信息判断是哪个用户,执行操作。
常用方法
long getCreationTime();//获取Session被创建时间
long getLastAccessedTime();//返回Session最后活跃的时间
ServletContext getServletContext();
void setMaxInactiveInterval(int var1);//设置Session超时时间
void setAttribute(String var1, Object var2);
Object getAttribute(String var1);
void invalidate(); //销毁该Session对象
示例
@WebServlet("/MS")
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession httpSession = req.getSession();
httpSession.setAttribute("name", "C2y");
httpSession.setAttribute("age", 18);
System.out.println(httpSession.getId());
resp.sendRedirect("/AS");
}
}
@WebServlet("/AS")
public class AnoServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession httpSession = req.getSession();
System.out.println(httpSession.getId());
System.out.println("name: "+ httpSession.getAttribute("name"));
System.out.println("age:" + httpSession.getAttribute("age"));
}
}
此时从session取出的值是正常的,且两次输出的sessionID是相同的。
此外还可以发现,服务器向浏览器还发送了一个名为JESSIONID的Cookie,它的值是Session的id值。Session通过这个cookie来判断是否是同一个用户。这个cookie仅供当前浏览器使用,不会存放在硬盘中。
当浏览器禁用了Cookie
当浏览器禁用了cookie,同样运行上面的程序,那么两个servlet输出的sessionID是不同,且取出的两个值是不正常的。
但我们可以通过URL地址重写,HttpServletResponse类提供了两个URL地址重写的方法:
- encodeURL(String url)
- encodeRedirectURL(String url)
@WebServlet("/MS")
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//此部分代码不变
resp.sendRedirect(resp.encodeURL("/AS"));
}
}
这样如果浏览器不支持Cookie,那么重写的URL地址后带有sessionID。

此时取出的两个值和两个Servlet的SessionID都和预期一样。
Session和Cookie的区别
(1)存储的值
Cookie只能存储字符串,对于非ASCII字符串还要对其编码;
Session可以存储任何类型的数据。
(2)隐私安全
Cookie存储在浏览器中,对客户端是可见的。信息容易泄露出去;Session存储在服务器上,不存在敏感信息泄露问题。
(3)有效期
只要maxAge属性为正数,则Cookie保存在硬盘中,即便关闭浏览器,Cookie还是存在的;而Session的保存在服务器中,不过Session依赖于名为JSESSIONID的Cookie,该Cookie默认的maxAge属性为-1。如果关闭了浏览器,该Session虽然没有从服务器中消亡,但会失效。
(4)浏览器支持
若浏览器禁用了Cookie,则Cookie是无用的;但Session可以通过URL地址重写来进行会话跟踪。
(5)跨域名
Cookie可以设置domain属性来实现跨域名;而Session只在当前的域名内有效,不可夸域名