什么是会话
会话可以简单理解为:用户开一个浏览器访问某个网站,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话。
会话过程中需要解决的一些问题
每个用户在使用浏览器与服务器进行会话的过程中,不可避免的各自会产生一些数据,服务器要想办法为每个用户保存这些数据。例如:多个用户点击超链接通过一个servlet各自购买了一个商品,服务器应该想办法把每一个用户购买的商品保存在各自的地方,以便于这些用户点击结账servlet时,结账servlet可以得到用户各自购买的商品为用户各自购买的商品结账。
为什么需要会话技术
1.如何保存用户上次登录时间
2.如何显示用户浏览历史
3.如何把登录的用户名和密码保存电脑,下次登录无需从新输入。
保存用户名:
public class CreateCookie extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); //创建保存用户名的cookie,cookie是在服务端创建的 Cookie cookie = new Cookie("name", "zhangsan"); //设置cookie的生命周期,有效时间 cookie.setMaxAge(3600); //把cookie信息回写给浏览器 response.addCookie(cookie); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } }
第一次访问CreateCookie的http响应
HTTP/1.1 200 OK Server: Apache-Coyote/1.1 Set-Cookie: name=zhangsan; Expires=Mon, 18-Apr-2016 12:33:18 GMT Content-Length: 0 Date: Mon, 18 Apr 2016 11:33:18 GMT
cookie文件内容
name zhangsan localhost/cookie/ //web应用 1536 2084092672 30513518 452421040 30513510 *
cookie保存在客户端浏览器的缓存目录下
那么怎么读取cookie文件呢
public class ReadCookie extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); response.setCharacterEncoding("utf-8"); PrintWriter out = response.getWriter(); //读取所有的cookie信息,选取你需要的cookie Cookie[] cookies = request.getCookies(); //遍历cookies for (int i = 0; i < cookies.length; i++) { Cookie cookie = cookies[i]; out.println("cookie 的信息 name = "+cookie.getName()+" value = "+cookie.getValue()); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request,response); } }
访问ReadCookie的http请求
GET /cookie/ReadCookie HTTP/1.1 Accept: */* Accept-Language: zh-CN User-Agent: Mozilla/4.0 Accept-Encoding: gzip, deflate Host: localhost:8080 Connection: Keep-Alive Cookie: name=zhangsan
request.getCookies()可以从http请求中获取所有的cookie Cookie的原理图
Cookie的小结
①Cookie是在服务器端创建的。
②Cookie是保存在浏览器这一端的。
③Cookie的生命周期可以通过cookie.setMaxAge(2000); 设置。
如果不设置,该cookie的生命周期当浏览器关闭时就消亡。
④Cookie是可以被多个浏览器共享的。
⑤怎么理解
我们可以把cookie想成一张表:
如果cookie重名会有什么问题?
重名会替换原来的值。
⑥一个站点可以保存多个cookie
⑦Cookie存放时是以明文方式存放的,因此安全性比较低。我们可以通过加密后在保存。
记录用户上次登录时间
public class Servlet1 extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); response.setCharacterEncoding("utf-8"); PrintWriter out = response.getWriter(); //读取cookie Cookie[] cookies = request.getCookies(); //假设记录上次登录时间的cookie的形式是"lasttime"="2011-11-11 11:11:11" //这里需要考虑一种情况,就是第一次登录 boolean flag = false;//没有找到 if (cookies != null) { for (Cookie cookie : cookies) { String name = cookie.getName(); if ("lasttime".equals(name)) { out.println("您上次登录时间是" + cookie.getValue()); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String nowTime = simpleDateFormat.format(new Date()); cookie.setValue(nowTime); cookie.setMaxAge(7 * 3600 * 24); response.addCookie(cookie); flag = true; break; } } } if (!flag) { //没有找到,用户是第一次登录 out.println("欢迎您第一次登录"); //创建cookie SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String nowTime = simpleDateFormat.format(new Date()); Cookie cookie = new Cookie("lasttime", nowTime); cookie.setMaxAge(7 * 3600 * 24); response.addCookie(cookie); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
记住用户名和密码:
Login.java
public class Login extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); response.setCharacterEncoding("utf-8"); PrintWriter out = response.getWriter(); String name = ""; Cookie[] cookies = request.getCookies(); if (cookies != null) { for (Cookie cookie : cookies) { if (cookie.getName().equals("name")) { name = cookie.getValue(); } } } out.println("<form action='/cookie/LoginCl' method='post'>"); out.println("name:<input type='text' name='name' value='"+name+"'><br/>"); out.println("pwd:<input type='password' name='passwd'><br/>"); out.println("<input type='checkbox' name='iskeepinfo' value='keep'>在此电脑上保存用户名<br/>"); out.println("<input type='submit' value='submit'>"); out.println(" </form>"); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
LoginCl.java
public class LoginCl extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); response.setCharacterEncoding("utf-8"); PrintWriter out = response.getWriter(); //用户是否勾选保存用户名 String name = request.getParameter("name"); String pwd = request.getParameter("passwd"); String val = request.getParameter("iskeepinfo"); if (val != null && "keep".equals(val)) { //需要保存用户名 //创建Cookie保存用户名 Cookie cookie = new Cookie("name", name); cookie.setMaxAge(2 * 7 * 24 * 3600); response.addCookie(cookie); } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doPost(request, response); } }
Cookie深入讨论:
1.一个cookie只能保存字符串信息,其结构是
Cookie(java.lang.String name,java.lang.String value)
2.一个浏览器最多放入300个cookie,一个站点最多20个cookie 每个cookie大小限制在4K以内。
3.Cookie生命周期
--Cookie默认生命周期是会话级别的,用户退出浏览器之后就被删除。
--通过setMaxAge()可以设置生命周期
----setMaxAge(正数) 即多少秒后该cookie失效
----setMaxAge(0) 删除该cookie
Cookie[] cookies = request.getCookies(); for(Cookie cookie:cookies){ if("id".equals(cookie.getName())){ cookie.setMaxAge(0);//删除 response.addCookie(cookie);//回写浏览器,否则不生效 break; } }
如果该web应用中只有一个cookie 则该cookie删除后,浏览器的临时文件夹下就没有了该cookie文件。如果一个web应用中有多个cookie,该cookie被删除文件还在。
setMaxAge(负数),相当于该cookie的生命周期是会话级的。
3.Cookie存放中文怎么处理
存放时: String val = java.net.URLEncoder.encode("张三","UTF-8"); Cookie cookie = new Cookie("uname",val); 取出时: String val = java.net.URLEncoder.decode(cookie.getValue(),"UTF-8"); Out.println("uname="+val);