简单地说,用户打开浏览器,发送多次请求并接受到来自服务器的响应,而后关闭浏览器,整个过程称之为一次会话。在多次请求中,为了共享数据,浏览器端采用cookie技术来保存与使用数据,而服务器端则是session技术(相对于一次会话的多次请求)。cookie技术不局限java,其他语言也支持。例如:php、javascript等。Javaweb中提供了javax.servlet.http.Cookie类提供了相关操作,对于服务器端的程序而言,使用cookie相关的api,只需要关注几个点:
怎么创建cookie,如何将cookie发送给浏览器,接收到请求时又如何取得其中的cookie。这里创建一个servlet,在doGet方法中实现,获取请求的cookie,如果有,将其删除;如果没有,创建cookie:
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); Cookie[] cookies = request.getCookies(); if (null != cookies) { for (int i = 0; i < cookies.length; i++) { System.out.println("取得cookie: "+cookies[i].getName() + " " + cookies[i].getValue()); cookies[i].setPath("/"); cookies[i].setMaxAge(0); response.addCookie(cookies[i]); } } else { System.out.println("没有cookie"); Cookie resCookie = new Cookie("testCookie", "testCookieValue"); resCookie.setMaxAge(60 * 60 * 24); resCookie.setPath("/"); response.addCookie(resCookie); } PrintWriter pw = response.getWriter(); pw.write("中文字符"); }
代码部署好之后,重复地请求该servlet,会出现如下效果(IE, Firefox, Chrome)
没有cookie 取得cookie: testCookie testCookieValue 没有cookie 取得cookie: testCookie testCookieValue 没有cookie
这段代码已经举例给出了如何创建cookie,如何获取cookie(注意要做非空判断)以及如何在响应中加入cookie。cookie的默认路径(一般设置resCookie.setPath("/");以此保证tomcat下可以共享相同的cookie),另外,设置cookie的有效时间,参数单位为‘秒’,想要删除该cookie,可将其时间设置为0。
cookie的消息内容是放置在http的请求头和响应头里的,所以不支持中文:
Cookie resCookie = new Cookie("testCookie", "中文库克益"); resCookie.setMaxAge(60 * 60 * 24); resCookie.setPath("/"); response.addCookie(resCookie); ====> java.lang.IllegalArgumentException: Control character in cookie value or attribute.
如果需要放入中文,就需要用到JDK提供的编码和解码工具: URLEncoder,URLDecoder:
@SuppressWarnings("deprecation") protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.setCharacterEncoding("UTF-8"); response.setContentType("text/html;charset=UTF-8"); Cookie[] cookies = request.getCookies(); if (null != cookies) { for (int i = 0; i < cookies.length; i++) { System.out.println("取得cookie: "+cookies[i].getName() + " " + cookies[i].getValue()); System.out.println(URLDecoder.decode(cookies[i].getValue())); cookies[i].setPath("/"); cookies[i].setMaxAge(0); response.addCookie(cookies[i]); } } else { System.out.println("没有cookie"); String cookieMsg = URLEncoder.encode("中文库克益"); Cookie resCookie = new Cookie("testCookie", cookieMsg); resCookie.setMaxAge(60 * 60 * 24); resCookie.setPath("/"); response.addCookie(resCookie); } PrintWriter pw = response.getWriter(); pw.write("中文字符"); }
-------------------------------------------------------------------------------->
写过用户登录的话,一定会对session不会陌生。JavaEE规范提供接口:javax.servlet.http.HttpSession 用于描述session对象,它是一次会话中,对共享数据进行管理的服务器端技术。
获取一个session:
request.getSession() 获得session,如果没有将创建一个新的。等效request.getSession(true);
request.getSession(boolean) 获得session,true:没有将创建,false:没有将返回null.
也可以进行属性相关的操作:session.xxxAttribute().
基于cookie,也就是说,如果浏览器禁用cookie,那么默认情况下,session将会失效。这里用一副图来说明session与cookie的关系:
当第一次调用 request.getSession() ,tomcat将创建一个session对象,并将session对象id值,以cookie方式发送给浏览器,之后浏览器再次请求时,将session id 发送服务器,服务器通过request.getSession() 就可以获取之前已经创建好的session对象。如果此时浏览器禁用cookie,那么在返回的请求中就不会包含cookie,服务器找不到JSESSIONID,无法获取到先前的session内容,于是会重新创建一个session id。
对于一个session,它的创建就是从第一次调用request.getSession()时创建。而它的消亡,除了服务器非正常关闭(正常关闭时持久化,写入到文件中),可能是超时--可以在web.xml中设置它的最大时限(单位:分钟):
... <session-config> <session-timeout>30</session-timeout> </session-config> </web-app>
另外,可以调用api,将其销毁:
invalidate() 将session对象销毁了。
setMaxInactiveInterval(int interval) 设置有效时间,单位秒
那么,如果浏览器真的禁用了cookie,我们怎么将session id传递给服务器呢?
通过URL将session id 传递给服务器:URL重写
手动方式: url;jsessionid=....
api方式:
encodeURL(java.lang.String url) 进行所有URL重写
encodeRedirectURL(java.lang.String url) 进行重定向 URL重写
如果参数url为空字符不同,其他都一样。
如果浏览器禁用cooke,api将自动追加session id ,如果没有禁用,api将不进行任何修改。
注意:如果浏览器禁用cookie,web项目的所有url都需手动重写。否则session将不能正常工作。