日期:2014-05-16  浏览次数:20350 次

tomcat中cookie的设置与jsp中session的设置

????????? 大家都知道,在开发一个互联网应用的时候,为了达到一种服务端和客户端有状态的效果,需要有一个sessionid???? 来对客户端进行标志。很多时候,这是通过在客户端防止session cookie实现的。但是如果客户端禁用了cookie呢?这就需要通过urlrewrite或者其他方式来实现。于是我们可能就在应用里面不需要cookie了。既然不需要了当然是希望我们的应用不对cookie进行处理。很遗憾的是,tomcat默认的是处理cookie的。每次请求过来的时候,都会解析request head里面的cookie信息,试图从中发现sessionid的信息。于是我们就需要从应用服务器层面把这个"无用功"去掉。

tomcat(我读的是tomcat6的源码)可以通过设置来实现:

在conf/context.xml里面:<Context cookies = "false">。那么就禁用了cookie了。

在源码级别的实现则是在CoyoteAdapter里面:

 protected void parseSessionCookiesId(org.apache.coyote.Request req, Request request) {

        // If session tracking via cookies has been disabled for the current
        // context, don't go looking for a session ID in a cookie as a cookie
        // from a parent context with a session ID may be present which would
        // overwrite the valid session ID encoded in the URL
        Context context = (Context) request.getMappingData().context;
        if (context != null && !context.getCookies())
            return; 

? 在这里面做了一个判断,如果context禁用了cookie,那么就不做解析。如果使用cookie,那么试着从cookie里面解析

? sessionid,并且如果存在的话覆盖request里面已有的(从url里面解析出来的)或者还没有的sesssionid.

?这个方法的入口是在CoyoteAdapter的service方法里面,这个方法沿着tomcat6的component 链传递处理request 和response,结构图如下:

?????????????? service--------->EngineValue

??????????????????????????????????????????? |

????????????????????????????????????????HostValue

??????????????????????????????????????????? |

????????????????????????????????????????ContextValue

??????????????????????????????????????????? |

?????????????????????????????????????????WrapperValue

这实际就是一个chain of resposibility模式,负责对request和response进行各自职责范围内的包装和处理。

最后的WrapperValue执行调用servlet处理请求的步骤。

?

好了,上面简单解释了cookie的处理,那么下面就是session了。

?

不管通过什么方式,通过cookie也好,通过urlrewrite也好,session在需要的时候是肯定要产生的.

但是如果我们不需要呢?比如恰好我们要展现给客户的首页就是jsp的,客户不需要登录就能浏览这个页面的内容。

那么这个时候对于客户的请求创建session就是没有必要的了。

?

一种常用的不创建session的方法是在jsp页面头上加一句:

<%@ page session=”false”>

这样在请求这个页面的时候就不产生session了。

这个在tomcat内部是怎么实现的呢?

?

首先明确一点,jsp在本质上是httpservlet,在/tomcat/work目录下面你会发现有跟自己的应用相同目录结构的一些文件,其中的jsp文件都变成了class文件,这实际是被jspcompiler编译过的。上面提到了WrapperValue会最终调用

servlet处理request。有兴趣的同学可以跟踪一下,会发现到了调用jsp对应的servlet(JspServlet)(这个是在tomcat/conf/web.xml里面配置的,对于.jsp,对应的servlet是jspservlet)时,最终会着落在

tomcat下面实现了PageContext接口的特定于jsp specification的实现类:PageContextImpl。

在这个类的initialize里面有这么一句:

if (request instanceof HttpServletRequest && needsSession)
			this.session = ((HttpServletRequest) request).getSession();

?这句的意思就是,有session获取session,没session新建一个。而通常,这个地方也是客户端与tomcat下面的应用交互时产生session的入口。

这句里面的needsSession就是之前提到的jsp页面上配置的值,默认是true.所以如果想在访问某个页面时不产生session,只需要设置成false就可以了。