1、什么是会话?
会话可简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话。类似打电话一样。
2、会话过程中要解决的一些问题?
每个用户在使用浏览器与服务器进行会话的过程中,不可避免各自会产生一些数据,服务器要想办法为每个用户保存这些数据。
例如:多个用户点击超链接通过一个servlet各自购买了一个商品,服务器应该想办法把每一个用户购买的商品保存在各自的地方,以便于这些用户点结帐servlet时,结帐servlet可以得到用户各自购买的商品为用户结帐。
提问:这些数据保存在request或servletContext中行不行?
1、Cookie
Cookie是客户端技术,服务器把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了。
2、Session
Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的session对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其它web资源时,其它web资源再从用户各自的session中取出数据为用户服务。
1、Cookie API
javax.servlet.http.Cookie类用于创建一个Cookie,response接口也中定义了一个addCookie方法,它用于在其响应头中增加一个相应的Set-Cookie头字段。 同样,request接口中也定义了一个getCookies方法,它用于获取客户端提交的Cookie。Cookie类的方法:
Cookie(String name,String value) //唯一的构造方法,cookie中只能存字符串
setValue与getValue方法
setMaxAge与getMaxAge方法 //设置cookie的有效时间,秒为单位
setPath与getPath方法 //设置cookie的有效路径,在该路径下访问会带cookie
setDomain与getDomain方法 //第三方cooie,不使用
getName方法
2、Cookie应用
1>显示用户上次访问时间
public class ServletTest extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //注意:resp写的时候是先写给自己,所以相当于可以组装后再输出 //先读取到当前cookie response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); out.print("上次访问时间:"); Cookie cookies[]=request.getCookies(); for(int i=0;cookies!=null && i<cookies.length;i++){ if(cookies[i].getName().equals("lastAccessTime")){ long cookieValue=Long.parseLong(cookies[i].getValue()); Date date=new Date(cookieValue); out.print(date.toLocaleString()); } } //cookie中只能存字符串 //再将最新的时间返回给客户端 Cookie cookie=new Cookie("lastAccessTime",System.currentTimeMillis()+""); cookie.setMaxAge(3600);// 以秒为单位 cookie.setPath("/CNMServlet");//默认是个cookie只能由创建它的web应用获得 response.addCookie(cookie); } }
2>通过setMaxAge置为0来删除当前Cookie
public class CookieTest extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //cookie的value可以随意设置 Cookie cookie=new Cookie("lastAccessTime",System.currentTimeMillis()+"");
//setMaxAge如果不设置,那么保存时间和Session效果一样,浏览器进程关闭时消失,也就是会话级别。 cookie.setMaxAge(0);// 以秒为单位 cookie.setPath("/CNMServlet");//路径也要一样才能删除 resp.addCookie(cookie); } }
3、Cookie细节
1.一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)。
2.一个WEB站点可以给一个WEB浏览器发送多个Cookie,一个WEB浏览器也可以存储多个WEB站点提供的Cookie。
3.浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。
4.如果创建了一个cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie(即存储在浏览器的内存中),用户退出浏览器之后即被删除。若希望浏览器将该cookie存储在磁盘上,则需要使用maxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。
5.注意,删除cookie时,path必须一致,否则不会删除。
4、cookie的经典案例:电商网站显示用户上次浏览过的商品
//首页显示最近浏览的商品
public class CookieDemo3 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); //输出所有商品 out.write("本站有如下商品:<br/>"); Map<String,Book>map=Db.getAll(); for(Map.Entry<String, Book> entry:map.entrySet()){ Book book=entry.getValue(); out.print("<a target=\"_blank\" href=‘/day07/servlet/cookieDemo4?id=" +book.getId()+"‘>"+book.getName()+"</a><br/>"); } //显示用户看过的商品 out.print("<br/>你曾经看过的商品<br/>"); Cookie cookies[]=request.getCookies(); for(int i=0;cookies!=null && i<cookies.length;i++){ if(cookies[i].getName().equals("bookHistory")){ //全部+//转义,这样不用判断符号在正则中是否已经转义 String ids[]=cookies[i].getValue().split("\\,");//2,3,1 for(String id:ids){ Book book=(Book) Db.getAll().get(id);//这里进行了检索 out.print("<a target=\"_blank\" href=‘/day07/servlet/cookieDemo4?id=" +book.getId()+"‘>"+book.getName()+"</a><br/>"); } } } } } //模拟数据库,因为有序且要检索,所以采用LinkedHashMap class Db{ private static Map<String,Book> map=new LinkedHashMap<String,Book>(); static { map.put("1", new Book("1","JavaWeb开发","老k","一本好书")); map.put("2", new Book("2","jdbc开发","老张","一本好书")); map.put("3", new Book("3","spring开发","老li","一本好书")); map.put("4", new Book("4","struts开发","老张","一本好书")); map.put("5", new Book("5","android开发","老bi","一本好书")); } public static Map getAll(){ return map; } } class Book{ private String id; private String name; private String author; private String description; public Book() { super(); } public Book(String id, String name, String author, String description) { this.id = id; this.name = name; this.author = author; this.description = description; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } }
//商品详情页,在这里添加商品到Cookie
public class CookieDemo4 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //根据用户带过来的id,显示相应的详细信息 response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); String id=request.getParameter("id"); Book book=(Book)Db.getAll().get(id); out.write(book.getId()+"<br/>"); out.write(book.getName()+"<br/>"); out.write(book.getAuthor()+"<br/>"); out.write(book.getDescription()+"<br/>"); //2.构建cookie,回写给浏览器; String cookieValue=buildCookie(id,request); Cookie cookie=new Cookie("bookHistory",cookieValue); cookie.setMaxAge(1*30*24*3600);//1 个月 cookie.setPath("/day07"); response.addCookie(cookie); } private String buildCookie(String id, HttpServletRequest request) { //可能出现的4种情况 //bookHistory =null 1 1 //bookHistory=2,5,1 1 1,2,5 //bookHistory=2,5,4 1 1,2,5 //bookHistroy=2,5 1 1,2,5 // 假如列表最多3个 String bookHistroy=null; Cookie cookies[]=request.getCookies(); for(int i=0;cookies!=null && i<cookies.length;i++){ if(cookies[i].getName().equals("bookHistory")){ bookHistroy=cookies[i].getValue(); } } if(bookHistroy==null) return id; //if(bookHistroy.contains(id))不能这样 21,23 也包括1 List<String> list=Arrays.asList(bookHistroy.split("\\,")); LinkedList <String>linkedlist=new LinkedList<String>(list); if(list.contains(id)){ linkedlist.remove(id); linkedlist.addFirst(id); }else{ if(list.size()>=3){ linkedlist.removeLast(); linkedlist.addFirst(id); }else linkedlist.addFirst(id); } StringBuffer sb=new StringBuffer(); for(String bid : linkedlist){ sb.append(bid+","); } return sb.deleteCharAt(sb.length()-1).toString(); } }
ps:Cookie可以使用在最近浏览商品、购物车可以存在Cookie中、最近登录时间、多长时间自动登录、等。
1、在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),注意:一个浏览器独占一个session对象(默认情况下)。因此,在需要保存用户数据时,服务器程序可以把用户数据写到用户浏览器独占的session中,当用户使用浏览器访问其它程序时,其它程序可以从用户的session中取出该用户的数据,为用户服务。
2、Session和Cookie的主要区别在于:Cookie是把用户的数据写给用户的浏览器。Session技术把用户的数据写到用户独占的session中。
3、Session对象由服务器创建,开发人员可以调用request对象的getSession方法得到session对象。
4、最简单session实现一个购物
//用户买了一个洗衣机
public class SessionDemo1 extends HttpServlet{ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp){ //如果有session则拿到,没有则创建 HttpSession session=req.getSession(); session.setAttribute("name", "洗衣机"); //session.setMaxInactiveInterval(3600);//设置session的有效时间,还可以在web.xml中设置 //session.invalidate();//手动摧毁session
} }
//再来一个请求完成结账
public class SessionDemo2 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); //加false,只会获取不会创建,性能更好,在用户直接访问的情况下不会创建session
HttpSession session=request.getSession(false); //HttpSession session=request.getSession(); String name=(String) session.getAttribute("name"); PrintWriter out = response.getWriter(); if(name!=null) out.write(name); else out.write("no buy"); } }
session实现原理:用户首先访问getSession方法时,创建一个session,这时服务器会通过Cookie的形式回写给客户端一个sessionId,客户端再访问服务器时,会带着这个Cookie过来,服务器根据这个ID可以找到客户端的session。这种情况下session默认的时间也就是和cookie一样,会话级别,如果想在浏览器关闭以后再次打开还能找到之前的Session,可以自己回写Cookie,设置Cookie的MaxAge,精测这种方式也只能在同种浏览器才能实现,如果在不同浏览器之间,即使设置了MaxAge也无法找到之前的Session。
5、实现多个浏览器共享同一session,也就是关闭后再打开,Session还能找到。
public class SessionDemo1 extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { HttpSession session=request.getSession(); session.setAttribute("name", "aaa"); String id=session.getId(); Cookie cookie=new Cookie("JSESSIONID",id);//必须和浏览器返回的那么一样 cookie.setPath("/CNMServlet/");//这个也必须和浏览器返回的一样 cookie.setMaxAge(30*60);//30 minutes response.addCookie(cookie); } }
6、浏览器禁用Cookie后的session处理。解决方案:URL重写。将sessionId通过URL的方式传递,略。
response. encodeRedirectURL(java.lang.String url) 用于对sendRedirect方法后的url地址进行重写。
response. encodeURL(java.lang.String url) 用于对表单action和超链接的url地址进行重写
原文:http://www.cnblogs.com/wangweiNB/p/4909226.html