jsessionid是一个cookie,可以通过在url后面加上“;jsessionid=xxx”来传递“session id”;其中servlet容器用来记录用户session,当我们创建回话时会自动创建,用来记录用户的访问记录。
首先,jsessionid是一个cookie,servlet容器(tomcat,jetty)用来记录用户session。
什么时候种下jsessionid
创建会话时,即调用request.getsession()的时候,关于getsession就不说了。补充几点是,访问html是不会创建session的,jsp页面默认是会创建session的,可以在jsp页面里面关掉自动创建session.
jsessionid工作原理:
url重写
服务端在内存里创建session,需要种cookie,除了在request header里面设置set-cookie以外,tomcat等容器有一个url重写机制。这个机制是客户端cookie不可用时的一个兜底策略,通过在url后面加上;jsessionid=xxx来传递session id,这样即使cookie不可用时,也可以保证session的可用性,但是session暴露在url里,本身是不安全的,到这里基本网上说法都是一致的
但是最关键的问题,tomcat怎么知道客户端cookie不可用。我在idea导入tomcat的源码调试跟踪,不同版本有些出入,大致应该还是一样的
tomcat有一个org.apache.catalina.connector.response是response的落地类,有两个方法会进行url重写,分别是encoderedirecturl和encodeurl,encoderedirecturl是重定向时会被调用,encodeurl貌似是手动调用,所以默认情况,重定向时才会出现url重写。两个方法代码类似,下面只关注encoderedirecturl
/** * encode the session identifier associated with this response * into the specified redirect url, if necessary. * * @param url url to be encoded * @return <code>true</code> if the url was encoded */ @override public string encoderedirecturl(string url) { if (isencodeable(toabsolute(url))) { return (toencoded(url, request.getsessioninternal().getidinternal())); } else { return (url); } }
方法注释写得很清楚了,如果有必要的话,把session id塞到重定向的url里面。再看一下isencodeable方法,关键地方我加了中文注释
/** * return <code>true</code> if the specified url should be encoded with * a session identifier. this will be true if all of the following * conditions are met: * <ul> * <li>the request we are responding to asked for a valid session * <li>the requested session id was not received via a cookie * <li>the specified url points back to somewhere within the web * application that is responding to this request * </ul> * * @param location absolute url to be validated * @return <code>true</code> if the url should be encoded */ protected boolean isencodeable(final string location) { if (location == null) { return false; } // is this an intra-document reference? if (location.startswith("#")) { return false; } // are we in a valid session that is not using cookies? final request hreq = request; final session session = hreq.getsessioninternal(false); if (session == null) { return false; } //这里其实就是网上说的客户端禁用cookie if (hreq.isrequestedsessionidfromcookie()) { return false; } // is url encoding permitted // servlet3.0后可以在项目web.xml里关掉url重写,对应tomat7之后 if (!hreq.getservletcontext().geteffectivesessiontrackingmodes(). contains(sessiontrackingmode.url)) { return false; } if (securityutil.ispackageprotectionenabled()) { return ( accesscontroller.doprivileged(new privilegedaction<boolean>() { @override public boolean run(){ return boolean.valueof(doisencodeable(hreq, session, location)); } })).booleanvalue(); } else { //这个方法会重写url return doisencodeable(hreq, session, location); } }
其中调用request对象的isrequestedsessionidfromcookie判断客户端cookie是否可用,里面逻辑也很简单,就是读取request里面有没有传jsessionid这个cookie。所以网上有些人说第一次访问,其实只要客户端没有传jsessionid,tomcat都假定cookie不可用
以上就是jsessionid是什么的详细内容。