Cookie和Session_会话技术

当用户第一次访问服务器时,服务器会在响应消息中增加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中保存的验证码是否一样
posted @ 2022-07-25 23:08  独游空想家  阅读(80)  评论(0编辑  收藏  举报