http 是无状态的,session与cookie是为了保持访问用户与后端服务器的交互状态。java
具体来讲cookie机制采用的是在客户端保持状态的方案,而session机制采用的是在服务器端保持状态的方案。因为采用服务器端保持状态的方案在客户端也须要保存一个标识,因此session机制可能须要借助于cookie机制来达到保存标识的目的,session经过cookie,在客户端保存session id,而将用户的其余会话消息保存在服务端的session对象中,与此相对的,cookie须要将全部信息都保存在客户端。所以cookie存在着必定的安全隐患.web
cookie机制。正统的cookie分发是经过扩展HTTP协议来实现的,服务器经过在HTTP的响应头中加上一行特殊的指示以提示浏览器按照指示生成相应的cookie。而cookie的使用是由浏览器按照必定的原则在后台自动发送给服务器的。浏览器检查全部存储的cookie,若是某个cookie所声明的做用范围大于等于将要请求的资源所在的位置,则把该cookie附在请求资源的HTTP请求头上发送给服务器。后端
要说cookie的生命周期,首先得理解一次会话,会话可简单理解为:用户开一个浏览器,点击多个超连接,访问服务器多个web资源,而后关闭浏览器,整个过程称之为一个会话。跨域
cookie在不设置有效期时,默认为一次会话,关闭浏览器窗口,cookie就消失。会话cookie通常不存储在硬盘上而是保存在内存里,固然这种行为并非规范规定的 , 若设置了过时时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie仍然有效直到超过设定的过时时间。存储在硬盘上的cookie能够在不一样的浏览器进程间共享。浏览器
要想在cookie中存储中文,那么必须使用URLEncoder类里面的encode(String s, String enc)方法进行中文转码,例如:安全
1 Cookie cookie = new Cookie("userName", URLEncoder.encode("孤傲苍狼", "UTF-8")); 2 response.addCookie(cookie);
在获取cookie中的中文数据时,再使用URLDecoder类里面的decode(String s, String enc)进行解码,例如:服务器
1 URLDecoder.decode(cookies[i].getValue(), "UTF-8")
session机制是一种服务器端的机制,服务器使用一种相似于散列表的结构(也可能就是使用散列表)来保存信息。但程序须要为某个客户端的请求建立一个session的时候,服务器首先检查这个客户端的请求里是否包含了一个session标识-称为session id,若是已经包含一个session id则说明之前已经为此客户建立过session,服务器就按照session id把这个session检索出来使用(若是检索不到,可能会新建一个,这种状况可能出如今服务端已经删除了该用户对应的session对象,但用户人为地在请求的URL后面附加上一个JSESSION的参数)。若是客户请求不包含session id,则为此客户建立一个session而且同时生成一个与此session相关联的session id,这个session id将在本次响应中返回给客户端保存,保存这个session id的方式能够采用cookie,这样在交互过程当中浏览器能够自动的按照规则把这个标识发挥给服务器。通常这个cookie的名字都是相似于SEEESIONID。但cookie能够被人为的禁止,则必须有其余机制以便在cookie被禁止时仍然可以把session id传递回服务器。
常常被使用的一种技术叫作URL重写,就是把session id直接附加在URL路径的后面。还有一种技术叫作表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时可以把session id传递回服务器。cookie
在程序中第一次调用request.getSession()方法时就会建立一个新的Session,能够用isNew()方法来判断Session是否是新建立的。session
//使用request对象的getSession()获取session,若是session不存在则建立一个 HttpSession session = request.getSession(); //获取session的Id String sessionId = session.getId(); //判断session是否是新建立的 if (session.isNew()) { // }else { // }
<!-- 设置Session的有效时间:以分钟为单位--> <session-config> <session-timeout>15</session-timeout> </session-config>
当须要在程序中手动设置Session失效时,能够手工调用session.invalidate方法,摧毁session。jsp
1 HttpSession session = request.getSession(); 2 //手工调用session.invalidate方法,摧毁session 3 session.invalidate();
4.3 禁用Cookie后servlet共享Session中的数据 -URL 重写
response.encodeRedirectURL(java.lang.String url) 用于对sendRedirect方法后的url地址进行重写。
response.encodeURL(java.lang.String url)用于对表单action和超连接的url地址进行重写
在使用URL重写几只的时候要注意,为了保证会话跟踪的正确性,全部的连接和重定向语句中的URL都须要调用encodeURL()或encodeRedirectURL()方法进行编码。另外,因为附加在URL中的session ID是动态产生的,对每个用户是不一样的,因此对于静态页面的相互跳转,URL重写机制无能为力。固然能够经过将静态页面转换为动态页面解决。
方法的执行:首先判断当前的Servlet是否执行了HttpSession对象的invalidate()方法,若是已经执行返回参数URL。接下来判断客户端是否禁用了Cookie,没有禁用直接返回参数URL,若是禁用,则在参数URL中附加session ID,返回编码后的URL。
若是要使用URL重写的方式来发送Session ID,则可使用HttpServletRequest的encodeURL()协助产生所需的URL重写。当容器尝试取得HttpSession实例时,若能够从HTTP请求中取得带有Session ID的Cookie,encodeURL()会将设置给它的URL原封不动的输出;若没法从HTTP请求中取得带有Session ID的Cookie(一般是浏览器禁用Cookie的状况),encodeURL()会自动产生带有Session ID的URL重写。
若是有执行encdeURL(),在浏览器第一次请求网站时,容器并不知道浏览器是否禁用Cookie,因此容器的作法是Cookie(发送set-cookie标头)与URL重写都作,所以若Servlet有如下语句,不管浏览器是否禁用Cookie,第一次请求时,都会显示编上Session ID的URL。
当再次请求时,若是浏览器没有禁用Cookie,则容器能够从Cookie(从cookie标头)中取得Session ID,此时encodeURL()就只会输出index.jsp。若是浏览器禁用Cookie,则encodeURL()就会继续在URL上编上Session ID
HttpServletResponse的另外一个方法encodeRedirectURL()方法,能够在要去浏览器重定向时,在URL上编上Session ID。