码迷,mamicode.com
首页 > 其他好文 > 详细

Servlet 之会话cookie与session

时间:2016-09-21 01:39:50      阅读:170      评论:0      收藏:0      [点我收藏+]

标签:

  简单地说,用户打开浏览器,发送多次请求并接受到来自服务器的响应,而后关闭浏览器,整个过程称之为一次会话。在多次请求中,为了共享数据,浏览器端采用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将不能正常工作。

Servlet 之会话cookie与session

标签:

原文地址:http://www.cnblogs.com/bruceChan0018/p/5888617.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!