zoukankan      html  css  js  c++  java
  • Servlet 之会话cookie与session

      简单地说,用户打开浏览器,发送多次请求并接受到来自服务器的响应,而后关闭浏览器,整个过程称之为一次会话。在多次请求中,为了共享数据,浏览器端采用cookie技术来保存与使用数据,而服务器端则是session技术(相对于一次会话的多次请求)。cookie技术不局限java,其他语言也支持。例如:php、javascript等。Javaweb中提供了javax.servlet.http.Cookie类提供了相关操作,对于服务器端的程序而言,使用cookie相关的api,只需要关注几个点:

      怎么创建cookie,如何将cookie发送给浏览器,接收到请求时又如何取得其中的cookie。这里创建一个servlet,在doGet方法中实现,获取请求的cookie,如果有,将其删除;如果没有,创建cookie:

        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            response.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=UTF-8");
            
            Cookie[] cookies = request.getCookies();
            if (null != cookies) {
                for (int i = 0; i < cookies.length; i++) {
                    System.out.println("取得cookie: "+cookies[i].getName() + " " + cookies[i].getValue());
                    cookies[i].setPath("/");
                    cookies[i].setMaxAge(0);
                    response.addCookie(cookies[i]);
                }
            } else {
                System.out.println("没有cookie");
                Cookie resCookie = new Cookie("testCookie", "testCookieValue");
                resCookie.setMaxAge(60 * 60 * 24);
                resCookie.setPath("/");
                response.addCookie(resCookie);
            }
            PrintWriter pw = response.getWriter();
            pw.write("中文字符");
        }

    代码部署好之后,重复地请求该servlet,会出现如下效果(IE, Firefox, Chrome)

    没有cookie
    取得cookie: testCookie testCookieValue
    没有cookie
    取得cookie: testCookie testCookieValue
    没有cookie

      这段代码已经举例给出了如何创建cookie,如何获取cookie(注意要做非空判断)以及如何在响应中加入cookie。cookie的默认路径(一般设置resCookie.setPath("/");以此保证tomcat下可以共享相同的cookie),另外,设置cookie的有效时间,参数单位为‘秒’,想要删除该cookie,可将其时间设置为0。

      cookie的消息内容是放置在http的请求头和响应头里的,所以不支持中文:

    Cookie resCookie = new Cookie("testCookie", "中文库克益");
    resCookie.setMaxAge(60 * 60 * 24);
    resCookie.setPath("/");
    response.addCookie(resCookie);
    
    ====>
    
    java.lang.IllegalArgumentException: Control character in cookie value or attribute.

    如果需要放入中文,就需要用到JDK提供的编码和解码工具: URLEncoder,URLDecoder:

    @SuppressWarnings("deprecation")
        protected void doGet(HttpServletRequest request, HttpServletResponse response)
                throws ServletException, IOException {
            // TODO Auto-generated method stub
            response.setCharacterEncoding("UTF-8");
            response.setContentType("text/html;charset=UTF-8");
            
            Cookie[] cookies = request.getCookies();
            if (null != cookies) {
                for (int i = 0; i < cookies.length; i++) {
                    System.out.println("取得cookie: "+cookies[i].getName() + " " + cookies[i].getValue());
                    System.out.println(URLDecoder.decode(cookies[i].getValue()));
                    cookies[i].setPath("/");
                    cookies[i].setMaxAge(0);
                    response.addCookie(cookies[i]);
                }
            } else {
                System.out.println("没有cookie");
                String cookieMsg = URLEncoder.encode("中文库克益");
                Cookie resCookie = new Cookie("testCookie", cookieMsg);
                resCookie.setMaxAge(60 * 60 * 24);
                resCookie.setPath("/");
                response.addCookie(resCookie);
            }
            PrintWriter pw = response.getWriter();
            pw.write("中文字符");
        }

    -------------------------------------------------------------------------------->

      写过用户登录的话,一定会对session不会陌生。JavaEE规范提供接口:javax.servlet.http.HttpSession 用于描述session对象,它是一次会话中,对共享数据进行管理的服务器端技术。

      获取一个session:

        request.getSession()  获得session,如果没有将创建一个新的。等效request.getSession(true);

        request.getSession(boolean) 获得session,true:没有将创建,false:没有将返回null.

      也可以进行属性相关的操作:session.xxxAttribute().

      基于cookie,也就是说,如果浏览器禁用cookie,那么默认情况下,session将会失效。这里用一副图来说明session与cookie的关系:

     

      当第一次调用 request.getSession() ,tomcat将创建一个session对象,并将session对象id值,以cookie方式发送给浏览器,之后浏览器再次请求时,将session id 发送服务器,服务器通过request.getSession() 就可以获取之前已经创建好的session对象。如果此时浏览器禁用cookie,那么在返回的请求中就不会包含cookie,服务器找不到JSESSIONID,无法获取到先前的session内容,于是会重新创建一个session id。

      对于一个session,它的创建就是从第一次调用request.getSession()时创建。而它的消亡,除了服务器非正常关闭(正常关闭时持久化,写入到文件中),可能是超时--可以在web.xml中设置它的最大时限(单位:分钟):

      ...
      <session-config>
          <session-timeout>30</session-timeout>
      </session-config>
    </web-app>

    另外,可以调用api,将其销毁:

      invalidate() 将session对象销毁了。

      setMaxInactiveInterval(int interval) 设置有效时间,单位秒

      那么,如果浏览器真的禁用了cookie,我们怎么将session id传递给服务器呢?

        通过URL将session id 传递给服务器:URL重写

             手动方式: url;jsessionid=....

             api方式:

                    encodeURL(java.lang.String url) 进行所有URL重写

                    encodeRedirectURL(java.lang.String url) 进行重定向 URL重写

                           如果参数url为空字符不同,其他都一样。

                           如果浏览器禁用cooke,api将自动追加session id ,如果没有禁用,api将不进行任何修改。

      注意:如果浏览器禁用cookie,web项目的所有url都需手动重写。否则session将不能正常工作。

  • 相关阅读:
    关于'selffilter' is not a registered tag library. Must be one of:
    关于Django报错django.core.exceptions.ImproperlyConfigured: Requested setting DEBUG, but settings are not configure
    大杂烩
    PyQt5多个GUI界面设计
    OpenCV读取图像问题:OpenCV(3.4.3) D:BuildOpenCVopencv-size.width0 && size.height0 in function 'cvimshow'
    MOOC课程信息D3.js动态可视化
    详解教务系统模拟登录与爬取二
    教务系统模拟登录与成绩爬取一
    pyecharts各省人口GDP可视化分析
    python爬虫伪装技术应用
  • 原文地址:https://www.cnblogs.com/bruceChan0018/p/5888617.html
Copyright © 2011-2022 走看看