HTTP无状态特点
HTTP协议的特点是无状态:无法在请求之间实现数据共享,而在实际开发中,我们需要在请求之间的共享数据。因此我们就需要借助其他方式来解决这个问题。
解决方案:
-
cookie 客户端会话跟踪技术
-
session 客服端会话跟踪技术
cookie的基本使用
Cookie:有时也用其复数形式 Cookies,指某些网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据(通常经过加密)。定义于 RFC2109 和 2965 中的都已废弃,最新取代的规范是 RFC6265 [1] 。(可以叫做浏览器缓存)
基本使用
创建cookie
由服务器将共享数据通过Cookie发送到浏览器,将共享数据保存在浏览器中
创建cookie对象:Cookie(String name, String value); name:共享数据的名称。value:共享数据的值。
发送给浏览器: 使用响应对象中的addCookie(cookie对象); 发送给浏览器

代码示例:
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
String username = req.getParameter("username");
// ======== 使用会话跟踪技术 =========
// 创建cookie 存放共享数据
Cookie cookie = new Cookie("username", username);
resp.addCookie(cookie);
req.setAttribute("username", username);
req.getRequestDispatcher("/WEB-INF/view/main.jsp").forward(req, resp);
}
获取cookie
浏览器发请求的时候,会自动的将数据发送到服务器,如果我们需要使用对应的数据,那么直接获取即可。
使用请求对象中的getCookies()方法获取到浏览器中发送过来的所有的Cookie数据,再通过cookie的name属性获取指定名称的value属性的值。

代码示例:
在servlet中获取cookie
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
// 获取浏览器带来的cookie数据
Cookie[] cookies = req.getCookies();
for (Cookie cookie : cookies) {
if ("username".equals(cookie.getName())) {
System.out.println(cookie.getValue());
}
}
}
在JSP总获取cookie
<body>
当前用户:${cookie.username.value}
</body>
cookie的使用细节
创建cookie,共享数据
Cookie cookie = new Cookie(String 共享数据名称,String 共享数据值);
response对象.addCookie(cookie);
值是String类型的,所以在多个数据共享时不方便。而且cookie在浏览器中的数量、大小是有限制的。
一个应用在一个浏览器中最多保存20个左右的Cookie
浏览器中最多保存300个Cookie
一个Cookie的数据大小在4KB左右
获取cookie中的共享数据
Cookie[] cs = req.getCookies();获取所有的cookie所以要用cookie数组接收。
要获取指定名称的Cookie的值,就要用循环遍历取出来
$ {cookie.cookie的name.cookie对象的value属性} 例子:${cookie.username.value}
修改cookie中的共享数据
为当前Cookie重新设置一个数据
cookie对象.setValue(“新值”);
response.addCookie(Cookie对象);
一定记得将修改之后的数据发送到浏览器中进行更新
设置Cookie的存活时间
void setMaxAge(int expiry); expiry指存活的时间,以秒为单位。通常登录用户的信息我们可以使用Cookie来保存一段时间,让后用户在这段时间以后可以不再填写账号密码等信息。
expiry=0:立即删除当前的Cookie。 expiry<0:默认值,当前浏览器进程,关闭浏览器,数据销毁
删除浏览器中指定的Cookie信息
Cookie对象.setMaxAge(0);
response.addCookie(Cookie对象);
cookie的中文问题(了解)
在Tomcat8.5以下存在的问题。cookie中的name和value是不支持中文的,如果有中文会爆出500异常

解决思路:将中文重新编码,转换成另外的一种数据(不是中文)。
创建cookie对象,核心类:URLEncoder
Cookie c = new Cookie(“username”,URLEncoder.encode("小明","utf-8"));
从Cookie中获取数据,核心类:URLDecoder。
URLDecoder.decode(c.getValue(),"UTF-8")
session的基本使用
Session:服务端的技术,将共享数据存在服务器中,实现在多次请求中数据的共享。存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。
基本使用
获取Session对象
request对象.getSession();获取Session对象,如果没有,服务器自动创建一个新的Session对象
request对象.getSession(true);获取Session对象,如果没有,服务器自动创建一个新的Session对象
request对象.getSession(false);获取Session对象,如果没有,返回null
添加共享数据
session对象.setAttribute(String name, Object value); value是object类型的,所以可以存储任何类型的对象。
此时,从服务器发给浏览器一个session的id,作为后面获取对应具体的共享数据的标识在后面的请求中,如果需要得到前共享的数据, 获取共享数据在新的请求头中,会携带session的id

服务器获取到对应的session的id,根据id获取到Session对象,再从session对象中获取到具体的共享数据。
获取共享数据
servlet获取方式
Object value = session对象.getAttribute(String name);
String username = (String)req.getSession().getAttribute("username");
jsp获取方式
${共享数据名称}
<body>
当前用户:${username}
</body>
修改共享数据
重新设置一个同名的共享数据,将前面的覆盖掉
删除共享数据
session对象.removeAttribute(String name)
Session中共享数据的存储
注意:共享数据的name应该要遵循以下格式: USER_IN_SESSION。
session对象.setAttribute(“USER_IN_SESSION”, user对象);
单存入session的数据是有关系的情况下,不直接一个一个的值存,需要封装成对象,在存入session对象中,可以统一管理。
使用Session共享的对象通常需要实现序列化接口。

Session共享数据的超时管理
和浏览器长时间不交互,超过指定时间之后,就自动销毁当前session。
void setMaxInactiveInterval(int interval); interval:指定超时时间,默认值30分钟

session在关闭浏览器的时候会自动销毁(session的底层是用cookie存的session的id,cookie的默认存活时间是一次会话。浏览器关了cookie就没了服务找不到对应的session的id了,就相当于session销毁了。其实session还会等到默认时间到了才会销毁)
可以手动销毁Session对象,在注销功能上使用
void invalidate();
Session的URL重写(了解)
当客户端浏览器的cookie被禁用时,浏览器就无法保存服务端发送过来的sessionid,在后面的请求中,服务器拿不到sessionid,就无法获取到共享数据。
解决方案:
-
手动在请求url后面拼接jsessionid
http://localhost/session/list;jsessionid=6225FDD3988C3B11BD8320899E9B1D2F<a href="/session/list;jsessionid=${pageContext.request.session.id}">url</a> -
自动在请求的URL后面拼接jsessionid
HttpServletResponse:String encodeURL(String url)<a href='${pageContext.response.encodeURL("/session/liset")}'>url</a>

本文深入探讨HTTP协议的无状态特性,介绍如何利用Cookie和Session技术实现客户端和服务端的会话跟踪,包括创建、获取、修改及删除共享数据的方法。
609

被折叠的 条评论
为什么被折叠?



