cookie、session、sessionid 与jsessionid

阅读:326 2019-03-19 14:43:11 来源:新网

问题:向某银行发送支付请求时,如果客户端cookie开启,第一次请求时,请求地址会自动增加一jsessionid,第二次没有问题。如果客户端cookie关闭,无论如何请求地址会自动添加一jsessionid,从而导致支付页面不能显示。

查了网上的一些解决办法,找到原因,如下:

在你的程序第一次访问服务器的时候,服务端并不知道你的客户端浏览器是否支持cookie,因此,当你第一次请求发起的时候,服务端会默认url重写,也就是将sessionid写到url中传递在请求过后,服务器会根据你提交的客户端浏览器信息自动检查客户端是否启用了cookie,如果启用,将不再进行url重写。如果没有,则还是进行url重写因为互联网协议本身是不维护状态的,因此引进了cookie来协助完成这项功能,sessionid其实也是对状态的一种维持。

解决办法:可在过滤器中加入如下代码

if(!(requestinstanceofhttpservletrequest)){chain.dofilter(request,response);return;}httpservletrequesthttprequest=(httpservletrequest)request;httpservletresponsehttpresponse=(httpservletresponse)response;//clearsessionifsessionidinurlif(httprequest.isrequestedsessionidfromurl()){httpsessionsession=httprequest.getsession();if(session!=null)session.invalidate();}//wrapresponsetoremoveurlencodinghttpservletresponsewrapperwrappedresponse=newhttpservletresponsewrapper(httpresponse){@overridepublicstringencoderedirecturl(stringurl){returnurl;}@overridepublicstringencoderedirecturl(stringurl){returnurl;}@overridepublicstringencodeurl(stringurl){returnurl;}@overridepublicstringencodeurl(stringurl){returnurl;}};

关于url重写:

url重写,在用户浏览器禁止cookie的情况下,保持用户回话....response的encodeurl()及encoderedirectedurl()方法首先判断cookies是否被浏览器支持;如果支持,则参数url被原样返回,sessionid将通过cookies来维持.url重写实际上就是把sessionid放在url里面,一般上如果browser开启cookie那么sessionid就存放在cookie里面,但如果cookie被禁用那么sessionid就会放在url里面,这就是url重写.

url重写是保证一个会话操作的方法之一比如当你登陆http://host/path/file.html表单时进行某些操作,那些url额外的数据就附加到表示该会话的每个url上,并且服务器把这个标识符与关于会话所有储存的数据相关联.重写后为http://host/path/file?jsessionid=12345附加会话信息为jsessionid=12345即使浏览器不支持cookie或用户禁用cookie时,这种方法也能起作用.其他还有隐藏表单字段,还有就是现在最常用的cookie另外

关于session与cookie,网上有一文章不错,如下:

一、cookie机制和session机制的区别具体来说cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。同时我们也看到,由于在服务器端保持状态的方案在客户端也需要保存一个标识,所以session机制可能需要借助于cookie机制来达到保存标识的目的,但实际上还有其他选择。二、会话cookie和持久cookie的区别如果不设置过期时间,则表示这个cookie生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。这种生命期为浏览会话期的cookie被称为会话cookie。会话cookie一般不保存在硬盘上而是保存在内存里。如果设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie依然有效直到超过设定的过期时间。存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个ie窗口。而对于保存在内存的cookie,不同的浏览器有不同的处理方式。三、如何利用实现自动登录当用户在某个网站注册后,就会收到一个惟一用户id的cookie。客户后来重新连接时,这个用户id会自动返回,服务器对它进行检查,确定它是否为注册用户且选择了自动登录,从而使用户无需给出明确的用户名和密码,就可以访问服务器上的资源。四、如何根据用户的爱好定制站点网站可以使用cookie记录用户的意愿。对于简单的设置,网站可以直接将页面的设置存储在cookie中完成定制。然而对于更复杂的定制,网站只需仅将一个惟一的标识符发送给用户,由服务器端的数据库存储每个标识符对应的页面设置。五、cookie的发送1.创建cookie对象2.设置最大时效3.将cookie放入到http响应报头如果你创建了一个cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie:存储在浏览器的内存中,用户退出浏览器之后被删除。如果你希望浏览器将该cookie存储在磁盘上,则需要使用maxage,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。发送cookie需要使用httpservletresponse的addcookie方法,将cookie插入到一个set-cookiehttp请求报头中。由于这个方法并不修改任何之前指定的set-cookie报头,而是创建新的报头,因此我们将这个方法称为是addcookie,而非setcookie。同样要记住响应报头必须在任何文档内容发送到客户端之前设置。六、cookie的读取1.调用request.getcookie要获取有浏览器发送来的cookie,需要调用httpservletrequest的getcookies方法,这个调用返回cookie对象的数组,对应由http请求中cookie报头输入的值。2.对数组进行循环,调用每个cookie的getname方法,直到找到感兴趣的cookie为止cookie与你的主机(域)相关,而非你的servlet或jsp页面。因而,尽管你的servlet可能只发送了单个cookie,你也可能会得到许多不相关的cookie。例如:stringcookiename=“userid”;cookiecookies[]=request.getcookies();if(cookies!=null){for(inti=0;i超文本链接并不产生表单提交,因此隐藏的表单域不能支持通常的会话跟踪,只能用于一系列特定的操作中,比如在线商店的结账过程十八、会话跟踪的基本步骤1.访问与当前请求相关的会话对象2.查找与会话相关的信息3.存储会话信息4.废弃会话数据十九、getsession()/getsession(true)、getsession(false)的区别getsession()/getsession(true):当session存在时返回该session,否则新建一个session并返回该对象getsession(false):当session存在时返回该session,否则不会新建session,返回null二十、如何将信息与会话关联起来setattribute会替换任何之前设定的值;如果想要在不提供任何代替的情况下移除某个值,则应使用removeattribute。这个方法会触发所有实现了httpsessionbindinglistener接口的值的valueunbound方法。二十一、会话属性的类型有什么限制吗通常会话属性的类型只要是object就可以了。除了null或基本类型,如int,double,boolean。如果要使用基本类型的值作为属性,必须将其转换为相应的封装类对象二十二、如何废弃会话数据a.只移除自己编写的servlet创建的数据:调用removeattribute(“key”)将指定键关联的值废弃b.删除整个会话(在当前web应用中):调用invalidate,将整个会话废弃掉。这样做会丢失该用户的所有会话数据,而非仅仅由我们servlet或jsp页面创建的会话数据c.将用户从系统中注销并删除所有属于他(或她)的会话调用logout,将客户从web服务器中注销,同时废弃所有与该用户相关联的会话(每个web应用至多一个)。这个操作有可能影响到服务器上多个不同的web应用。二十三、使用isnew来判断用户是否为新旧用户的错误做法publicbooleanisnew()方法如果会话尚未和客户程序(浏览器)发生任何联系,则这个方法返回true,这一般是因为会话是新建的,不是由输入的客户请求所引起的。但如果isnew返回false,只不过是说明他之前曾经访问该web应用,并不代表他们曾访问过我们的servlet或jsp页面。因为session是与用户相关的,在用户之前访问的每一个页面都有可能创建了会话。因此isnew为false只能说用户之前访问过该web应用,session可以是当前页面创建,也可能是由用户之前访问过的页面创建的。正确的做法是判断某个session中是否存在某个特定的key且其value是否正确二十四、cookie的过期和session的超时有什么区别会话的超时由服务器来维护,它不同于cookie的失效日期。首先,会话一般基于驻留内存的cookie不是持续性的cookie,因而也就没有截至日期。即使截取到jsessionidcookie,并为它设定一个失效日期发送出去。浏览器会话和服务器会话也会截然不同。二十五、sessioncookie和session对象的生命周期是一样的吗当用户关闭了浏览器虽然sessioncookie已经消失,但session对象仍然保存在服务器端二十六、是否只要关闭浏览器,session就消失了程序一般都是在用户做logoff的时候发个指令去删除session,然而浏览器从来不会主动在关闭之前通知服务器它将要被关闭,因此服务器根本不会有机会知道浏览器已经关闭。服务器会一直保留这个会话对象直到它处于非活动状态超过设定的间隔为止。之所以会有这种错误的认识,是因为大部分session机制都使用会话cookie来保存sessionid,而关闭浏览器后这个sessionid就消失了,再次连接到服务器时也就无法找到原来的session。如果服务器设置的cookie被保存到硬盘上,或者使用某种手段改写浏览器发出的http请求报头,把原来的sessionid发送到服务器,则再次打开浏览器仍然能够找到原来的session。恰恰是由于关闭浏览器不会导致session被删除,迫使服务器为session设置了一个失效时间,当距离客户上一次使用session的时间超过了这个失效时间时,服务器就可以认为客户端已经停止了活动,才会把session删除以节省存储空间。由此我们可以得出如下结论:关闭浏览器,只会是浏览器端内存里的sessioncookie消失,但不会使保存在服务器端的session对象消失,同样也不会使已经保存到硬盘上的持久化cookie消失。二十七、打开两个浏览器窗口访问应用程序会使用同一个session还是不同的session通常sessioncookie是不能跨窗口使用的,当你新开了一个浏览器窗口进入相同页面时,系统会赋予你一个新的sessionid,这样我们信息共享的目的就达不到了。此时我们可以先把sessionid保存在persistentcookie中(通过设置session的最大有效时间),然后在新窗口中读出来,就可以得到上一个窗口的sessionid了,这样通过sessioncookie和persistentcookie的结合我们就可以实现了跨窗口的会话跟踪。二十八、如何使用会话显示每个客户的访问次数由于客户的访问次数是一个整型的变量,但session的属性类型中不能使用int,double,boolean等基本类型的变量,所以我们要用到这些基本类型的封装类型对象作为session对象中属性的值但像integer是一种不可修改(immutable)的数据结构:构建后就不能更改。这意味着每个请求都必须创建新的integer对象,之后使用setattribute来代替之前存在的老的属性的值。例如:httpsessionsession=request.getsession();someimmutalbeclassvalue=(someimmutableclass)session.getattribute(“someidentifier”);if(value==null){value=newsomeimmutableclass(…);//新创建一个不可更改对象}else{value=newsomeimmutableclass(calculatedfrom(value));//对value重新计算后创建新的对象}session.setattribute(“someidentifier”,value);//使用新创建的对象覆盖原来的老的对象二十九、如何使用会话累计用户的数据使用可变的数据结构,比如数组、list、map或含有可写字段的应用程序专有的数据结构。通过这种方式,除非首次分配对象,否则不需要调用setattribute。例如httpsessionsession=request.getsession();somemutableclassvalue=(somemutableclass)session.getattribute(“someidentifier”);if(value==null){value=newsomemutableclass(…);session.setattribute(“someidentifier”,value);}else{value.updateinternalattribute(…);//如果已经存在该对象则更新其属性而不需重新设置属性}三十、不可更改对象和可更改对象在会话数据更新时的不同处理不可更改对象因为一旦创建之后就不能更改,所以每次要修改会话中属性的值的时候,都需要调用setattribute(“someidentifier”,newvalue)来代替原有的属性的值,否则属性的值不会被更新可更改对象因为其自身一般提供了修改自身属性的方法,所以每次要修改会话中属性的值的时候,只要调用该可更改对象的相关修改自身属性的方法就可以了。这意味着我们就不需要调用setattribute方法了。

sso相关:

1、域名

www.a.com和sub.a.com具有相同的父域:.a.com;

response可以在www.a.com域中把cookie设置到sub.a.com下。这种情况是:父域相同。但是在.a.com域中无法把cookie设置到.b.com下,这种情况属于父域不同(同源策略)

2、跨域写cookie

在每个域下的应用中提供一个/setcookie接口:

packagecom.app2.controller;importjava.io.ioexception;importjavax.servlet.servletexception;importjavax.servlet.annotation.webservlet;importjavax.servlet.http.cookie;importjavax.servlet.http.httpservlet;importjavax.servlet.http.httpservletrequest;importjavax.servlet.http.httpservletresponse;@webservlet(urlpatterns="/setcookie")publicclasscookiecontrollerextendshttpservlet{@overrideprotectedvoiddoget(httpservletrequestreq,httpservletresponseresp)throwsservletexception,ioexception{httpservletrequestrequest=(httpservletrequest)req;httpservletresponseresponse=(httpservletresponse)resp;//p3p协议。ie浏览器如果不加这句话,就无法把cookie设置成功。response.addheader("p3p","cp=curaadmadevapsaopsdoourbusunipurintdemstaprecomnavotcnoidspcor");response.setcontenttype("text/javascript");stringcookiekey=request.getparameter("cookiekey");stringcookievalue=request.getparameter("cookievalue");cookiecookie=newcookie(cookiekey,cookievalue);cookie.setpath("/");response.addcookie(cookie);}@overrideprotectedvoiddopost(httpservletrequestreq,httpservletresponseresp)throwsservletexception,ioexception{this.doget(req,resp);}}

通过

上一篇: 常用正则表达式
相关文章
{{ v.title }}
{{ v.description||(cleanHtml(v.content)).substr(0,100)+'···' }}
你可能感兴趣
推荐阅读 更多>
推荐商标

{{ v.name }}

{{ v.cls }}类

立即购买 联系客服