Cookie和Session_会话技术
Cookie
当用户第一次访问服务器时,服务器会在响应消息中增加Set-Cookie头字段,将用户信息以Cookie的形式发送给客户端。客户端接收到Cookie信息后会保存在浏览器的缓冲区中,后续再次访问该服务器时会将用户信息以Cookie形式发送给服务器,使服务器能分辨请求属于哪个用户。
- Cookie类的构造方法:
public Cookie(String name, String value)
- Cookie类中的方法:
setMaxAge(int expiry)
方法:设置Cookie在浏览器上有效的秒数。正整数为有效时间,负整数为关闭浏览器就删除(默认),0为立即删除这个Cookie。
setPath(String url)
方法:Cookie默认只对当前访问所属目录及其子目录有效,设置为"/"可对站点所有目录有效。
setDomain(String pattern)
方法:指定浏览器访问的域,值默认为当前主机名,域为baidu.com时,值应设置为".baidu.com"。 - 显示用户上次访问的时间:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
String lastAccessTime = null;
Cookie[] cookies = req.getCookies();
//遍历cookies数组,查找名为lastAccess的cookie值
for(int i=0;cookies!=null&&i<cookies.length;i++){
if("lastAccess".equals(cookies[i].getName())){
lastAccessTime = cookies[i].getValue();
break;
}
}
//判断是否存在名为lastAccess的cookie
if (lastAccessTime==null){
resp.getWriter().print("您是首次访问本站!");
}else{
resp.getWriter().print("您上次访问的时间是:"+lastAccessTime);
}
//将当前时间作为Cookie的值发送给客户端
String currentTime = new SimpleDateFormat("yyyy-MM-dd/hh:mm:ss").format(new Date());
Cookie cookie = new Cookie("lastAccess", currentTime);
resp.addCookie(cookie);
}
在敲案例的时候出错,书中代码在创建当前时间的时候格式为yyyy-MM-dd hh:mm:ss
,中间是用空格隔开,我使用Chrome浏览器访问报500错误。经过调试发现错误如下:
说Cookie值中存在无效字符[32],32对应Ascll编码的空格,将空格改为其他符号,问题解决了。在百度时看到说cookie值中分号,逗号和空格必须进行编码,我试了下其他两个,果然都不行(逗号[44],分号[59])
我尝试使用编码解码让中间的符号一定显示空格
//在创建cookie的时候,对字符串进行编码`URLEncoder.encode(currentTime,"utf-8")`
Cookie cookie = new Cookie("lastAccess", URLEncoder.encode(currentTime,"utf-8"));
//在输出字符串的时候,对字符串进行解码`URLDecoder.decode(lastAccessTime,"utf-8")`
resp.getWriter().print("您上次访问的时间是:"+ URLDecoder.decode(lastAccessTime,"utf-8"));
成功让中间的符号显示为空格。
总结:如果cookie的值中包含分号,逗号或空格,必须进行编码处理,等用到时在进行解码。
Session
Cookie技术可以将用户的信息保存在各自的浏览器中,但如果传递的信息比较多,会增大服务器程序处理的难度。可以使用Session技术,Session是一种将会话数据保存在服务端的技术。
当浏览器访问Web服务器时,Servlet容器创建一个Session对象和ID属性,类似病历档案和就诊卡号。后续浏览器访问服务器时,只需要将ID传递给服务器,服务器根据ID号得到之前的会话数据。注意,Session是借助Cookie技术来传递ID属性的,例如Cookie(Set-Cookie: JSESSIONID=123)。
- 获取HttpSession对象:
request.getHttpSession()
方法,用于获取HttpSession对象。 - HttpSession接口中的方法:
getID()
方法:获取当前HttpSession对象的会话标识号。
invalidate()
方法:用于强制使Session无效。
setMaxInactiveInterval(int interval)
方法:用于修改当前会话的默认超时间隔。
setAttribute(String name, Object value)
方法:用于将一个对象与名称关联后存储到当前的HttpSession对象中,set换get可以获取,换remove可以删除。 - Session超时管理:如果超出了HttpSession对象的超时间隔,HttpSession对象会被清除。在Tomcat安装目录->conf->web.xml中设置了默认会话超时间隔为30分钟。
<session-config>
<session-timeout>30</session-timeout>
</session-config>
- 利用URL重写实现Session跟踪
当浏览器不支持Cookie或Cookie功能被关闭时,服务器无法获取到Session对象的ID属性,可以使用URL重写机制来保存用户的会话信息。URL重写就是将JSESSIONID关键字作为参数名,会话标识号作为参数值,附加在URL地址后面。
encodeURL(String url)
方法:用于对超链接和Form表单的Action属性中设置的URL进行重写。
encodeRedirectURL(String url)
方法:用于对要传递给sendRedirect()方法的URL进行重写。
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
String newUrl = resp.encodeRedirectURL("/javaweb01/hello");
resp.getWriter().write("<a href='"+newUrl+"'>hello</a>");
}
注意在重写URL之前需要先获取Session对象,搞不好是第一次访问需要创建Session对象及会话标识号。
关闭浏览器的Cookie功能,点击链接后注意观察跳转的路径:http://localhost:8080/javaweb/hello;jsessionid=BE63CDA3FD8133F67EC8E8DF29567E1B
- 利用Session实现一次性验证码:生成随机验证码,保存在Session中,表单填写后提交,对比验证码请求参数和Session中保存的验证码是否一样
本文来自博客园,作者:独游空想家,转载请注明原文链接:https://www.cnblogs.com/linzhikai/p/16517501.html