`
liuwei_blog
  • 浏览: 94389 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Tomcat之Session和Cookie大揭密

    博客分类:
  • j2ee
阅读更多

关键字: tomcat之session和cookie大揭密

转载自
http://tech.it168.com/j/2007-09-29/200709291005796.shtml
作者:IT168 极地圣火  2007-09-29


一、JSP和Servlet中的Cookie

    由于HTTP协议是无状态协议(虽然Socket连接是有状态的,但每次用HTTP协议进行数据传输后就关闭的Socket连接,因此,HTTP协议并不会保存上一次的状态),因此,如果要保存某些HTTP请求过程中所产生的数据,就必须要有一种类似全局变量的机制保证数据在不同的HTTP请求之间共享。这就是下面要讲的Session和Cookie。

    Cookie是通过将数据保存在客户端的硬盘(永久Cookie)或内存(临时Cookie)中来实现数据共享的一种机制。在Windows下,保存在这些Cookie数据的目录一般是C:\Documents and Settings\Administrator\Cookies。每一个Cookie有一个超时时间,如果超过了这个时间,Cookie将自动失效。可按如下方法来设置Cookie的超时时间:
Java代码 复制代码
  1. Cookie cookie =  new  Cookie( "key" , "value" );   
  2. cookie.setMaxAge( 3600 );   // Cookie的超时间为3600秒,也就是1小时   
  3. response.addCookie(cookie);  
Cookie cookie = new Cookie("key","value");
cookie.setMaxAge(3600);  // Cookie的超时间为3600秒,也就是1小时
response.addCookie(cookie);

如果不使用setMaxAge方法,Cookie的超时时间为-1,在这种情况下,Cookie就是临时Cookie,也就是说这种Cookie实际上并不保存在客户端硬盘上,而是保存在客户端内存中的。读者可以在JSP中运行如下代码,看看是否会在上面提到的保存cookie的目录中生成cookie文件:
Java代码 复制代码
  1. Cookie cookie =  new  Cookie( "key" , "value" );   
  2. esponse.addCookie(cookie);  
 Cookie cookie = new Cookie("key","value");
response.addCookie(cookie);


实际上使用setMaxAge将超时时间设为任意的负数都会被客户端浏览器认为是临时
Cookie,如下面的代码将在客户端内存中保存一个临时Cookie:

Java代码 复制代码
  1. Cookie cookie =  new  Cookie( "key" , "value" );   
  2. cookie.setMaxAge(- 100 );   // 将cookie设为临时Cookie   
  3. response.addCookie(cookie);  
Cookie cookie = new Cookie("key","value");
cookie.setMaxAge(-100);  // 将cookie设为临时Cookie
response.addCookie(cookie);


如果第一次将Cookie写入客户端(不管是硬盘还是内存),在同一台机器上第二次访问
该网站的jsp页面时,会自动将客户端的cookie作为HTTP请求头的Cookie字段值传给服务端,如果有多个Cookie,中间用";"隔开。如下面的HTTP请求头所示:
Java代码 复制代码
  1. GET /test/First.jsp HTTP/ 1.1   
  2. HOST:localhost   
  3. ...   
  4. Cookie:key1=value1;key2=value2   
  5. ...   
  6. ...  
GET /test/First.jsp HTTP/1.1
HOST:localhost
...
Cookie:key1=value1;key2=value2
...
...

我们可以在JSP中使用如下的Java代码来输出Cookie字段的值:
Java代码 复制代码
  1. out.println(request.getHeader( "Cookie" ));  
     out.println(request.getHeader("Cookie"));

如果在Servlet中输出,必须得使用如下语句得到out,才能向客户端浏览器输出数据:
Java代码 复制代码
  1. PrintWriter out = response.getWriter();  
       PrintWriter out = response.getWriter();

    虽然永久Cookie和临时Cookie在第二次向服务端发出HTTP请求时生成Cookie字段,但它们还是有一定的区别的。永久Cookie在任意新开启的IE窗口都可以生成Cookie。而临时Cookie由于只保存在当前IE窗口,因此,在新开启的IE窗口,是不能生成Cookie字段的,也就是说,新窗口和旧窗口是不能共享临时Cookie的。使用重定向机制弹出的新窗口也无法和旧窗口共享临时Cookie。但在同一个窗口可以。如在一个IE窗口输入http://localhost:8080/test/first.jsp,向内存写入一个临时Cookie后,在同一个IE窗口输入http://localhost:8080/test/second.jsp ,浏览器在向服务端发送HTTP请求时,自动将当前浏览器的临时Cookie(也就是first.jsp所创建的Cookie)和永久Cookie作为HTTP请求头的Cookie字段值发送给服务端。但是如果新启一个IE窗口,由于新IE窗口没有这个临时Cookie,因此,second.jsp只发送了保存在硬盘上的永久Cookie。
二、Tomcat中的Servlet和Session

    由于Cookie数存在保存在客户端,这样对于一些敏感数据会带来一些风险。而且Cookie一般只能保存字符串等简单数据。并且大小限制在4KB。如果要保存比较复杂的数据,Cookie可能显得有些不合适。基于这些原因,我们自然会想到在服务端采用这种类似Cookie的机制来存储数据。这就是我们这节要讲的会话(Session)。而在一个客户端和服务端的会话中所有的页面可以共享为这个会话所建立的Session。

    那么什么是会话呢?有很多人认为会话就是在一台机器上客户端浏览器访问某个域名所指向的服务端程序,就建立了一个客户端到服务端的会话。然后关闭客户端浏览器,会话就结束。其实这并不准确。

    首先让我们先来看看Session的原理。Session和Cookie类似。所不同的是它是建立在服务端的对象。每一个Session对象一个会话。也许很多读者看到这会有一个疑问。Session是如何同客户端联系在一起的呢?很多人在使用Session时并没有感觉到这一点。其实这一切都是Web服务器,如Tomcat一手包办的。那么Web服务器又是如何识别通过HTTP协议进行连接的客户端的呢?这就要用到第一节中所讲的Cookie。在一般情况下,Session使用了临时Cookie来识别某一个Session是否属于某一个会话。在本文中以Tomcat为例来说明Session是如何工作的。

    让我们先假设某一个客户端第一次访问一个Servlet,在这个Servlet中使用了getSession来得到一个Session对象,也就是建立了一个会话,这个Servlet的代码如下:

Java代码 复制代码
  1. import  java.io.*;   
  2. import  javax.servlet.ServletException;   
  3. import  javax.servlet.http.*;   
  4. public   class  First  extends  HttpServlet   
  5. {   
  6.    public   void  doGet(HttpServletRequest request, HttpServletResponse response)   
  7. throws  ServletException, IOException   
  8.   {   
  9.      response.setContentType( "text/html" );   
  10.      HttpSession session = request.getSession();   
  11.      session.setAttribute( "key" "mySessionValue" );   
  12.      PrintWriter out = response.getWriter();   
  13.      out.println( "The session has been generated!" );   
  14.      out.flush();   
  15.      out.close();   
  16.   }   
  17. }  
import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class First extends HttpServlet
{
  public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
  {
     response.setContentType("text/html");
     HttpSession session = request.getSession();
     session.setAttribute("key", "mySessionValue");
     PrintWriter out = response.getWriter();
     out.println("The session has been generated!");
     out.flush();
     out.close();
  }
}


对于服务端的First来说,getSession方法主要做了两件事:
    1. 从客户端的HTTP请求头的Cookie字段中获得一个寻找一个JSESSIONID的key,这个key的值是一个唯一字符串,类似于D5A5C79F3C8E8653BC8B4F0860BFDBCD 。
   
2. 如果Cookie中包含这个JSESSIONID,将key的值取出,在Tomcat的Session Map(用于保存Tomcat自启动以来的所有创建的Session)中查找,如果找到,将这个Session取出,如果未找到,创建一个HttpSession对象,并保存在Session Map中,以便下一次使用这个Key来获得这个Session。

在服务器向客户端发送响应信息时,如果是新创建的HttpSession对象,在响应HTTP
头中加了一个Set-Cookie字段,并将JSESSIONID和相应的值反回给客户端。如下面的HTTP响应头:
Java代码 复制代码
  1. HTTP/ 1.1   200  OK   
  2. ...   
  3. Set-Cookie: JSESSIONID=D5A5C79F3C8E8653BC8B4F0860BFDBCD   
  4. ...  
HTTP/1.1 200 OK
...
Set-Cookie: JSESSIONID=D5A5C79F3C8E8653BC8B4F0860BFDBCD
...


    对于客户端浏览器来说,并不认识哪个Cookie是用于Session的,它只是将相应的临时Cookie和永久Cookie原封不动地放到请求HTTP头的Cookie字段中,发送给服务器。如果在IE中首次访问服务端的First,这时在当前IE窗口并没有临时Cookie,因此,在请求HTTP头中就没有Cookie字段,所以First在调用getSession方法时就未找到JSESSIONID,因此,就会新建一个HttpSession对象。并在Set-Cookie中将这个JSESSIONID返回。接下来我们使用另外一个Servlet:Second来获得在First中所设置的Session数据。Second的代码如下:
Java代码 复制代码
  1. import  java.io.*;   
  2. import  javax.servlet.ServletException;   
  3. import  javax.servlet.http.*;   
  4. public   class  Second  extends  HttpServlet   
  5. {   
  6.      public   void  doGet(HttpServletRequest request, HttpServletResponse response) throws  ServletException, IOException   
  7.     {   
  8.         response.setContentType( "text/html" );   
  9.         HttpSession session = request.getSession();   
  10.         PrintWriter out = response.getWriter();   
  11.         out.println(session.getAttribute( "key" ));   
  12.         out.flush();   
  13.         out.close();   
  14.     }   
  15. }  
import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class Second extends HttpServlet
{
    public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException
    {
        response.setContentType("text/html");
        HttpSession session = request.getSession();
        PrintWriter out = response.getWriter();
        out.println(session.getAttribute("key"));
        out.flush();
        out.close();
    }
}


     如果在同一个窗口来调用Second。这时客户端已经有了一个临时Cookie,就是JSESSIONID,因此,会将这个Cookie放到HTTP头的Cookie字段中发送给服务端。服务端在收到这个HTTP请求时就可以从Cookie中得到JSESSIONID的值,并从Session Map中找到这个Session对象,也就是getSession方法的返回值。因此,从技术层面上来说,所有拥有同一个Session ID的页面都应该属于同一个会话。

    如果我们在一个新的IE窗口调用Second,并不会得到mySessionValue。因为这时Second和First拥有了不同的Session ID,因此,它们并不属于同一个会话。讲到这,也许很多读者眼前一亮。既然拥有同一个Session ID,就可以共享Session对象,那么我们可不可以使用永久Cookie将这个Session ID保存在Cookie文件中,这样就算在新的IE窗口,也可以共享Session对象了。答案是肯定的。下面是新的First代码:

Java代码 复制代码
  1. import  java.io.*;   
  2. import  javax.servlet.ServletException;   
  3. import  javax.servlet.http.*;   
  4. public   class  First  extends  HttpServlet   
  5. {   
  6.      public   void  doGet(HttpServletRequest request, HttpServletResponse response) throws  ServletException, IOException   
  7.     {   
  8.         response.setContentType( "text/html" );   
  9.         HttpSession session = request.getSession();   
  10.         session.setMaxInactiveInterval( 3600 );   
  11.         Cookie cookie =  new  Cookie( "JSESSIONID" , session.getId());   
  12.         cookie.setMaxAge( 3600 );   
  13.         response.addCookie(cookie);   
  14.         session.setAttribute( "key" "mySessionValue" );   
  15.         PrintWriter out = response.getWriter();   
  16.         out.println( "The session has been generated!" );   
  17.         out.flush();   
  18.         out.close();   
  19.      }   
  20. }  
import java.io.*;
import javax.servlet.ServletException;
import javax.servlet.http.*;
public class First extends HttpServlet
{
    public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException
    {
        response.setContentType("text/html");
        HttpSession session = request.getSession();
        session.setMaxInactiveInterval(3600);
        Cookie cookie = new Cookie("JSESSIONID", session.getId());
        cookie.setMaxAge(3600);
        response.addCookie(cookie);
        session.setAttribute("key", "mySessionValue");
        PrintWriter out = response.getWriter();
        out.println("The session has been generated!");
        out.flush();
        out.close();
     }
}

    在上面的代码中使用了Cookie对象将JSESSIONID写入了Cookie文件,并使用setMaxAge方法将Cookie超时时间设为3600秒(1小时)。这样只要访问过First,从访问时间算起,在1小时之内,在本机的任何IE窗口调用Second都会得到"mySessionValue"字符串。

三、Tomcat中的JSP和Session

从本质上讲,JSP在运行时已经被编译成相应的Servlet了,因此,在JSP和Servlet中Session的使用方法应该差不多。但还是有一些细小的差别。

如果我们使用过JSP就会发现,在JSP中很多对象是不需要创建的,如out、session等。它们可以直接使用。如下面的JSP代码所示
<!-- MyJSP.jsp -->

Java代码 复制代码
  1. <%@ page language= "java"  contentType= "text/html; charset=GB18030"   
  2.     pageEncoding= "GB18030" %>   
  3. <!DOCTYPE html PUBLIC  "-//W3C//DTD HTML 4.01 Transitional//EN"   "http://www.w3.org/TR/html4/loose.dtd" >   
  4. <html>   
  5.     <head>   
  6.         <meta http-equiv= "Content-Type"  content= "text/html; charset=GB18030" >   
  7.         <title>Insert title here</title>   
  8.     </head>   
  9.     <body>   
  10.         <%   
  11. out.println(session.getId());   
  12. %>   
  13.     </body>   
  14. </html>  
<%@ page language="java" contentType="text/html; charset=GB18030"
    pageEncoding="GB18030"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=GB18030">
        <title>Insert title here</title>
    </head>
    <body>
        <%
out.println(session.getId());
%>
    </body>
</html>


在上面的JSP代码中直接使用了out和session。而并不象Servlet里一样用get方法来获得相应的对象实例。那么这是为什么呢?

由于JSP在第一次运行时是被编译成Servlet的,我们自然就会想到有可能是在编译JSP时自动创建了session和out对象。下面我们就来验证这一点。首先需要查看一下JSP被编译成Servlet后的源代码。这非常简单,如果我们使用的是Tomcat,只需要在Tomcat的安装目录中的work中找相应的源程序即可。如一个名为MyJSP.jsp的文件首先被编译成MyJSP_jsp.java(这就是由JSP生成的Servlet源程序文件),然后再由java将MyJSP_jsp.java编译成MyJSP_jsp.class,最后Tomcat运行的就是MyJSP_jsp.class。如上面的JSP程序被编译成Servlet的部分源代码如下:

Java代码 复制代码
  1. package  org.apache.jsp;   
  2. import  javax.servlet.*;   
  3. import  javax.servlet.http.*;   
  4. import  javax.servlet.jsp.*;   
  5. public   final   class  MyJSP_jsp  extends  org.apache.jasper.runtime.HttpJspBase   
  6. {   
  7. ... ...   
  8. ... ...   
  9. public   void  _jspService(HttpServletRequest request, HttpServletResponse response)   
  10. throws  java.io.IOException, ServletException {   
  11. PageContext pageContext =  null ;   
  12. HttpSession session =  null ;   
  13. ServletContext application =  null ;   
  14. ServletConfig config =  null ;   
  15. JspWriter out =  null ;   
  16. Object page =  this ;   
  17. JspWriter _jspx_out =  null ;   
  18. PageContext _jspx_page_context =  null ;   
  19. try  {   
  20. response.setContentType( "text/html; charset=GB18030" );   
  21. pageContext = _jspxFactory.getPageContext( this , request, response,   
  22. null true 8192 true );   
  23. _jspx_page_context = pageContext;   
  24. application = pageContext.getServletContext();   
  25. config = pageContext.getServletConfig();   
  26. session = pageContext.getSession();   
  27. out = pageContext.getOut();   
  28. _jspx_out = out;   
  29. out.write( "\r\n" );   
  30. out.write( "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n" );   
  31. out.write( "<html>\r\n" );   
  32. out.write( "\t<head>\r\n" );   
  33. out.write( "\t\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=GB18030\">\r\n" );   
  34. out.write( "\t\t<title>Insert title here</title>\r\n" );   
  35. out.write( "\t</head>\r\n" );   
  36. out.write( "\t<body>\r\n" );   
  37. out.write( "\t\t" );   
  38. out.println(session.getId());   
  39. out.write( "\r\n" );   
  40. out.write( "\r\n" );   
  41. out.write( "\t</body>\r\n" );   
  42. out.write( "</html>" );   
  43. catch  (Throwable t) {   
  44. if  (!(t  instanceof  SkipPageException)){   
  45. out = _jspx_out;   
  46. if  (out !=  null  && out.getBufferSize() !=  0 )   
  47. try  { out.clearBuffer(); }  catch  (java.io.IOException e) {}   
  48. if  (_jspx_page_context !=  null ) _jspx_page_context.handlePageException(t);   
  49. }   
  50. finally  {   
  51. _jspxFactory.releasePageContext(_jspx_page_context);   
  52. }   
  53. }   
  54. }  
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class MyJSP_jsp extends org.apache.jasper.runtime.HttpJspBase
{
... ...
... ...
public void _jspService(HttpServletRequest request, HttpServletResponse response)
throws java.io.IOException, ServletException {
PageContext pageContext = null;
HttpSession session = null;
ServletContext application = null;
ServletConfig config = null;
JspWriter out = null;
Object page = this;
JspWriter _jspx_out = null;
PageContext _jspx_page_context = null;
try {
response.setContentType("text/html; charset=GB18030");
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write("\r\n");
out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\r\n");
out.write("<html>\r\n");
out.write("\t<head>\r\n");
out.write("\t\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=GB18030\">\r\n");
out.write("\t\t<title>Insert title here</title>\r\n");
out.write("\t</head>\r\n");
out.write("\t<body>\r\n");
out.write("\t\t");
out.println(session.getId());
out.write("\r\n");
out.write("\r\n");
out.write("\t</body>\r\n");
out.write("</html>");
} catch (Throwable t) {
if (!(t instanceof SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try { out.clearBuffer(); } catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}


我们可以看到上面的代码中的_jspService方法类似于HttpServlet中的service方法,在方法的开始部分首先建立了session、application、out等对象实例。然后将MyJSP.jsp中的HTML通过out输出到客户端。我们要注意上面的黑体字的语句:out.println(session.getId());,JSP编译器自动将JSP中的<% ... %>中包含的Java代码原封不动地插入到_jspService中。由于是在创建对象实例后插入,因此,就可以直接使用session、out等对象了。

如果我们想做进一步的实验,可以直接使用javac来编译MyJSP_jsp.java,为了方便其间,首先建立一个c.cmd文件,它的内容如下:

javac -classpath
D:\tools\apache-tomcat-6.0.13\lib\servlet-api.jar;D:\tools\apache-tomcat-6.0.13\lib\jsp-api.jar;D:\tools\apache-tomcat-6.0.13\lib\annotations-api.jar;D:\tools\apache-tomcat-6.0.13\lib\catalina.jar;D:\tools\apache-tomcat-6.0.13\lib\jasper.jar;D:\tools\apache-tomcat-6.0.13\lib\el-api.jar %1

其中D:\tools\apache-tomcat-6.0.13是tomcat的安装目录,读者可以将其设为自己的机器上的tomcat安装目录

在编译时可直接使用c MyJSP_jsp.java进行编译,这时tomcat就直接运行我们编译生成的MyJSP_jsp.class了。

从上面的代码我们还可以了解一点,在JSP无论使用还是不使用session,都会使用getSession方法创建一个Session对象,而Servlet必须显式地调用才会建立Session对象。

注:通过直接编译java文件运行jsp,需要清除一下tomcat的缓存,一般需要重启一下tomcat。

 

四、随心所欲使用Session

(1) 使用url传递session id

    在上面讲过,在默认情况下session是依靠客户端的cookie来实现的。但如果客户端浏览器不支持cookie或将cookie功能关闭,那就就意味着无法通过cookie来实现session了。在这种情况下,我们还可以有另一种选择,就是通过url来传递session id。

    对于Tomcat来说,需要使用jsessionid作为key来传递session id。但具体如何传呢?可能有很多人认为会是如下的格式:

http://localhost:8080/test/MyJSP.jsp?jsessionid= D5A5C79F3C8E8653BC8B4F0860BFDBCD

    但实验上面的url并不好使。其实最直接的方法我们可以看一下Tomcat的源程序是如何写的,首先下载tomcat的源程序,然后找到CoyoteAdapter.java文件,并打开。在其中找到parseSessionId方法,这个方法是用来从url中提取Session id的。我们可以不必了解这个方法的全部代码,只看一下开头就可以。代码片段如下:

Java代码 复制代码
  1. ByteChunk uriBC = req.requestURI().getByteChunk();   
  2.      int  semicolon = uriBC.indexOf(match,  0 , match.length(),  0 );   
  3.      if  (semicolon >  0 ) {...}  
 ByteChunk uriBC = req.requestURI().getByteChunk();
     int semicolon = uriBC.indexOf(match, 0, match.length(), 0);
     if (semicolon > 0) {...}



    上面代码中的uriBC就是请求的url,第二行在这个url中查找match字符串,再在CoyoteAdapter.java中查找一个match字符串,match变量的初值如下:

Java代码 复制代码
  1. private   static   final  String match =  ";"  + Globals.SESSION_PARAMETER_NAME +  "=" ;  
private static final String match = ";" + Globals.SESSION_PARAMETER_NAME + "=";



    从上面代码可以看出,match开头是一个";"字符,而SESSION_PARAMETER_NAME是一个常量,值就是"jsessionid",因此可以断定,MyJSP.jsp后跟的是";",并不是"?",因此,正确的url如下:

http://localhost:8080/test/MyJSP.jsp;jsessionid= D5A5C79F3C8E8653BC8B4F0860BFDBCD

    通过使用上述方法甚至可以在不同的机器上获得同一个session对象。

    在CoyoteAdapter.java文件中还有一个parseSessionCookiesId方法,这个方法将从HTTP请求头中提取session id。我们中postParseRequest方法中可以看到将调用的parseSessionId方法,在最后调用了parseSessionCookiesId方法,因此,我们可以断定,tomcat将考虑url中的session id,然后再读取Cookie字段中的session id。还有就是在postParseRequest方法的最后部分有一个response.sendRedirect(redirectPath);,在调完它后,就直接return了。而没有执行到parseSessionCookiesId,因此,使用重定向并不能通过HTTP头的cookie字段共享session。只能通过url来传递session id。

(2) 将tomcat的cookie支持关闭

如果我们只想使用url来支持session,可以直接将tomcat的cookie功能关闭。我们可
以修改conf中的context.xml文件,加入一个cookies="false"即可,内容如下:

Java代码 复制代码
  1. <!-- The contents of  this  file will be loaded  for  each web application -->   
  2. <Context cookies =  "false" >   
  3. ... ...   
  4. ... ...   
  5. </Context>  
<!-- The contents of this file will be loaded for each web application -->
<Context cookies = "false">
... ...
... ...
</Context>



    重启tomcat后,就算客户端支持cookie,tomcat也不会考虑HTTP请求头的cookie字段。

(3) 在IE中控制Cookie

    在IE中也可以将Cookie关闭,启动IE,在工具->Internet选项->稳私->高级中选中"覆盖自动cookie处理"选项。并按图1选择:






对于下面的选项"总是允许会话cookie",如果不选,在本机将允许会话cookie,也就是通过localhost访问,在远程将不允许会话cookie。我们也可以通过在工具->Internet选项->稳私->站点来对某个网站来允许和拒绝cookie。

  • Cecb0536-a3fa-3eeb-bdaf-8a2ec0884053-thumb
  • 大小: 21.7 KB
分享到:
评论
1 楼 assasszt 2016-06-12  
写的很透彻,厉害!

能不能问个 问题:
cookie 应该是浏览器判断是否提交的吧?
所有 提交到服务器的 cookie 都可以认为是有效的吧。

那为什么我 设置了一个 10秒钟的 cookie,10秒以后 再刷新,那个cookie还是被提交了?

相关推荐

    tomcat修改sessionId

    tomcat修改sessionId,同一台服务器部署多个tomcat需要修改sessionId,否则会出现session冲突的问题

    tomcat redis session.rar

    综上所述,"Tomcat Redis Session"是一种在分布式环境中保证用户会话一致性的解决方案,通过集成Redis和Nginx,有效地解决了Web应用集群中的Session管理难题。在实际部署中,还需要考虑系统整体架构、性能优化和运维...

    设定tomcat中session过期时间.txt

    在Web开发中,Session管理是确保用户状态跟踪的重要机制之一。Tomcat作为一款广泛使用的Java应用服务器及Servlet容器,提供了多种方式来设定Session的有效时长。这有助于开发者根据具体业务需求灵活调整Session的...

    TOMCAT中SESSION与COOKIE的深度探索.pdf

    TOMCAT中SESSION与COOKIE的深度探索.pdf

    Tomcat_Session的持久化

    Tomcat_Session 的持久...Tomcat 提供了 StandardManager 和 PersistentManager 两个实现类来管理 Session,其中 PersistentManager 能够把 Session 对象保存到 Session Store 中,提供了更为灵活的 Session 管理功能。

    tomcat修改jsessionid在cookie中的名称

    在Tomcat 5.x 版本中,可以通过设置系统属性 `org.apache.catalina.SESSION_COOKIE_NAME` 来更改JSessionID在Cookie中的名称。具体操作步骤如下: 1. **Linux环境:** ```bash JAVA_OPTS="-Dorg.apache.catalina....

    tomcat实现session共享

    在IT行业中,尤其是在Web...总的来说,通过使用Tomcat和Redis,我们可以构建一个高效且可扩展的session共享方案,为大型Web应用提供稳定的服务。同时,这也体现了IT行业对高并发、分布式处理能力的需求以及应对策略。

    Tomcat memcached Session依赖jar包

    6. **性能优化**:通过调整memcached客户端和Tomcat的Session Manager配置,可以优化Session的读写性能,如设置合适的超时时间、连接池大小和并发控制等。 7. **故障转移和一致性**:由于memcached是无状态的,所以...

    tomcat-session共享

    标题“tomcat-session共享”和描述中提到的问题,主要是指如何在多台Tomcat服务器之间以及通过Nginx进行Session的高效、安全共享。以下是对这个主题的详细阐述: **1. Session的概念** Session是Web应用程序中用于...

    Tomcat7+Redis+Session 负载之后session 共享 tomcat jar包

    标题 "Tomcat7+Redis+Session 负载之后session 共享 tomcat jar包" 涉及的是在使用Nginx做负载均衡时,如何通过集成Redis来实现Tomcat7服务器之间的Session共享,从而确保用户在不同服务器之间切换时仍然能够保持...

    tomcat集群session共享解决方案

    在学习这些解决方案时,可以参考“Tomcat集群资料”中的文档,它们通常包含配置示例、最佳实践和常见问题解答,帮助你更好地理解和实施session共享策略。同时,理解负载均衡原理、分布式系统设计以及安全性问题也是...

    tomcat集群session共享

    综上所述,实现Tomcat集群session共享主要涉及Tomcat的session管理机制、Redis的集成以及相应的配置和优化。通过合理配置,可以确保在高并发环境下提供无缝的用户体验,同时提升系统的可扩展性和可靠性。

    tomcat8+memcached session共享

    这些JAR包将集成到Tomcat的运行环境中,使Tomcat能够与Memcached通信并处理session的存储和检索。 以下是这些JAR包的作用: 1. `spymemcached-2.8.4.jar`:这是一个基于Java的Memcached客户端库,用于连接和操作...

    Tomcat8(Tomcat9)+redis实现Session共享(支持Redis集群)

    Tomcat作为最常用的Java Servlet容器,其Session管理能力直接影响到应用的性能和可扩展性。本教程将详细介绍如何利用Tomcat 8或9以及Redis实现Session共享,支持Redis集群,以提高系统的可伸缩性和数据一致性。 ...

    tomcat5 session 复制

    总结起来,Tomcat5 的 Session 复制通过集群配置和 Web 应用配置两方面实现,确保了分布式环境下的会话一致性。配置过程中需注意端口冲突、网络可达性以及正确设置复制策略,以达到高效且稳定的 Session 同步效果。

    redis tomcat7 session共享

    通过以上步骤,我们可以成功地在`Tomcat7`中利用`Redis`实现Session共享,提高了系统的可扩展性和可用性。这种方法不仅适用于`Tomcat7`,还可以应用于其他支持自定义Session管理的Servlet容器。

    tomcat-redis-session-manager的jar包-包含Tomcat7和Tomcat8

    《深入理解Tomcat-Redis-Session-Manager:在Tomcat7和Tomcat8中的应用》 在现代Web应用程序开发中,session管理是一个至关重要的环节,它涉及到用户会话的持久化和跨请求的数据共享。传统的session管理方式在高...

    tomcat-redis-session-manager包集合下载(tomcat8)

    【标题】"tomcat-redis-session-manager包集合下载(tomcat8)"涉及的主要知识点是将Redis集成到Tomcat中管理会话(session),以提高Web应用的性能和可扩展性。 【描述】中提到的"所需的tomcat-redis-session-...

    tomcat-session-manager环境构建资源

    这种方式对于处理大量并发请求和大容量Session数据非常有效。 5. **Nginx配置**:Nginx作为反向代理服务器,需要配置负载均衡策略,比如轮询、最少连接数等,同时还需要配置Session黏滞(Sticky Sessions)以确保...

    Tomcat8 session同步测试,配置好的Tomcat

    总的来说,Tomcat8的session同步是通过集群配置实现的,涉及通道、管理器、部署器和阀门等多个组件。理解并正确配置这些部分对于构建高可用性和高扩展性的分布式Web服务至关重要。在测试过程中,要确保所有节点都能...

Global site tag (gtag.js) - Google Analytics