Cookie和Session

什么是会话?

会话可以简单理解为:用户开一个浏览器,点击多个超链接,访问服务器多个web资源,然后关闭浏览器,整个过程称之为一个会话。

保存会话数据的两种技术:Cookie和HttpSession

Cookie:

Cookie是客户端技术,程序把每个用户的数据以cookie的形式写给用户各自的浏览器。当用户使用浏览器再去访问服务器中的web资源时,就会带着各自的数据去。这样,web资源处理的就是用户各自的数据了。

1.Cookie入门案例(上次访问时间)

package cn.lsl.cookie;

import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LastVisit extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setDateHeader("Expires", -1);
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Pragma", "no-cache");
        response.setContentType("text/html;charset=utf-8");
        // 如果用户第一次访问 --- 判断请求中有没有cookie信息
        Cookie[] cookies = request.getCookies();
        if (cookies == null) {
            // 第一次访问,没有cookie,将当前时间以cookie写回客户端
            long now = System.currentTimeMillis();
            // 向客户端写cookie
            Cookie cookie = new Cookie("last", now + "");
            cookie.setPath("/Cookie");
            // 设置cookie有效时间
            cookie.setMaxAge(60 * 60 * 24 * 2);
            // 写cookie回到客户端
            response.addCookie(cookie);
            response.getWriter().println("欢迎你第一次访问本网站!");
        } else {
            // cookie存在
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals("last")) {
                    long lasttime = Long.parseLong(cookie.getValue());
                    // 显示给用户
                    Date date = new Date(lasttime);
                    DateFormat dateFormat = new SimpleDateFormat(
                            "yyyy年MM月dd日 HH时mm分ss秒");
                    response.getWriter().println(
                            "上次访问时间:" + dateFormat.format(date));
                }
            }
            // 更新最后访问时间
            long now = System.currentTimeMillis();
            Cookie cookie = new Cookie("last", now + "");
            cookie.setPath("/Cookie");
            cookie.setMaxAge(60 * 60 * 24 * 2);
            response.addCookie(cookie);
        }
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }
}

解析:

1)通过服务器向客户端cookie

Cookie cookie = new Cookie(name,value);

response.addCookie(cookie);

* 在HTTP协议响应头信息中 Set-Cookie: last=1339556457609

2)当客户端存在cookie之后,以后每次请求自动携带HTTP协议请求头信息

  Cookie: last=1339556456859

服务端获得需要cookie数据

Cookie[] cookie = request.getCookie();

遍历cookie获取需要信息

for(Cookie cookie : cookie){

         if(cookie.getName().equals("last")){

                  

         }

}

2.会话cookie,持久cookie?

1)cookie信息默认情况保存在浏览器内存中 --- 会话cookie

会话cookie会在关闭浏览器时清除

2)持久cookie,cookie数据保存客户端硬盘上

通过setMaxAge设置Cookie为持久Cookie

3.访问cookie有效路径

默认情况下,生成cookie时,产生默认有效访问路径 (默认生成cookie程序路径)

http://localhost:8080/Cookie/lastvisit  --- 生成cookie  --- path 默认值: /Cookie

http://localhost:8080/Cookie/servlet/path ---- 生成cookie ---- path 默认值:/Cookie/servlet

第二次访问程序携带cookie信息,如果访问路径与path不一致,不会携带cookie 信息

* 以后程序开发,尽量设置path ---- setPath方法

4.第一方cookie 和 第三方cookie

通过setDomain 设置cookie 有效域名

访问google时,生成cookie过程中 cookie.setDomain(".baidu.com") ---- 生成百度cookie ------ 第三方cookie

* 第三方cookie 属于不安全  ----- 一般浏览器不接受第三方cookie

 

访问google时,生成cookie,cookie.setDomain(.google.con) ---- 生成google的cookie ------ 第一方cookie

5.删除cookie

原理:设置cookie MaxAge为0

*删除cookie时,必须设置path与cookie的path一致

eg:

package cn.lsl.cookie;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class DeleteCookie extends HttpServlet {

    
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        Cookie cookie = new Cookie("last","");
        cookie.setMaxAge(0);
        cookie.setPath("/Cookie");
        response.addCookie(cookie);
    }
    
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request,response);
    }
}

6.显示上次浏览的商品

Book.java(实体类)

package cn.lsl.domain;

public class Book {
    private String id;
    private String name;
    private String author;
    private Double price;
    private String description;
    public Book(){}
    public Book(String id, String name, String author, Double price,
            String description) {
        super();
        this.id = id;
        this.name = name;
        this.author = author;
        this.price = price;
        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 Double getPrice() {
        return price;
    }
    public void setPrice(Double price) {
        this.price = price;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    @Override
    public String toString() {
        return "Book [author=" + author + ", description=" + description
                + ", id=" + id + ", name=" + name + ", price=" + price + "]";
    }
}

BookDB.java(模拟数据库)

package cn.lsl.db;
import java.util.LinkedHashMap;
import java.util.Map;
import cn.lsl.domain.Book;

public class BookDB {
    private static Map<String, Book> books = new LinkedHashMap<String, Book>();
    static{
        books.put("1", new Book("1", "Java", "张三", 35.00, "Java入门"));
        books.put("2", new Book("2", "JavaEE", "李四", 45.00, "JavaEE入门"));
        books.put("3", new Book("3", "Android", "王五", 45.00, "Android入门"));
        books.put("4", new Book("4", "ios", "小舒", 55.00, "ios入门"));
        books.put("5", new Book("5", "html5", "小五", 35.00, "html5入门"));
    }
    //根据id查询书本
    public static Book findBookById(String bookId){
        return books.get(bookId);
    }
    //查询所有的书本
    public static Map<String, Book> findAllBooks(){
        return books;
    }
}

ShowBookServlet.java(显示所有书籍)

 

package cn.lsl.cookie;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.lsl.db.BookDB;
import cn.lsl.domain.Book;

public class ShowBookServlet 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("<h1>本站有以下书籍</h1>");
        Map<String, Book> books = BookDB.findAllBooks();
        for (Map.Entry<String, Book> me : books.entrySet()) {
            out.write(me.getValue().getName()+"&nbsp;&nbsp;<a href='/Cookie/servlet/ShowBookDetailServlet?id="+me.getKey()+"'>查看详情</a><br/>");
        }
        //显示用户最近的浏览记录
        out.write("<hr/>");
        out.write("<a href='/Cookie/servlet/CleanHistoryServlet'>清空浏览记录</a>");
        out.write("<h3>您最近的商品浏览记录</h3>");
        Cookie[] cs = request.getCookies();
        for(int i=0; cs!=null&&i<cs.length; i++){
            if("bookHistory".equals(cs[i].getName())){
                String value = cs[i].getValue();
                String ids[] = value.split("\\-");
                for (String id : ids) {
                    out.write(BookDB.findBookById(id).getName()+"<br/>");
                }
                break;
            }
        }
    }
    
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request,response);
    }

}

 

ShowBookDetailServlet.java(查看详细信息)

package cn.lsl.cookie;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.LinkedList;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import cn.lsl.db.BookDB;
import cn.lsl.domain.Book;

public class ShowBookDetailServlet extends HttpServlet {
    
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        String id = request.getParameter("id");
        Book book = BookDB.findBookById(id);
        out.write(book.toString());
        //向客户端写Cookie
        String ids = makeIds(request, id);
        Cookie c = new Cookie("bookHistory",ids);
        c.setMaxAge(Integer.MAX_VALUE);
        c.setPath(request.getContextPath());
        response.addCookie(c);
    }
    
    
    private String makeIds(HttpServletRequest request, String id) {
        // TODO Auto-generated method stub
        //a
        Cookie cs[] = request.getCookies();
        if(cs == null)
            return id;
        //b
        Cookie cookie = null;
        for (Cookie c : cs) {
            if("bookHistory".equals(c.getName())){
                cookie = c;
                break;
            }
        }
        if(cookie == null)
            return id;
        //cdefg
        String ids[] = cookie.getValue().split("\\-");
        LinkedList<String> list = new LinkedList<String>(Arrays.asList(ids));
        if(list.size()<3){
            if(list.contains(id)){
                list.remove(id);
            }
            list.addFirst(id);    
        }else{
            if(list.contains(id)){
                list.remove(id);
            }else{
                list.removeLast();
            }
            list.addFirst(id);
        }
        
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < list.size(); i++) {
            if(i>0)
                sb.append("-");
            sb.append(list.get(i));
        }
        return sb.toString();
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request,response);
    }

}

CleanHistoryServlet.java

package cn.lsl.cookie;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CleanHistoryServlet extends HttpServlet {

    
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        Cookie cookie = new Cookie("bookHistory","");
        cookie.setMaxAge(0);
        cookie.setPath(request.getContextPath());
        response.addCookie(cookie);
        response.sendRedirect("/Cookie/servlet/ShowBookServlet");
    }
    
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request,response);
    }
}

7.Cookie细节

1)一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称和设置值。

2)一个WEB站点可以给一个WEB浏览器发送多个Cookie,一个WEB浏览器可以存储多个WEB站点提供的Cookie。

3)浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,,每个Cookie的大小限制为4KB.

4)如果创建了一个Cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie(即存储在浏览器的内存中),用户推出浏览器之后即被删除。若希望浏览器将还cookie存储在磁盘上,则需要使用maxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。

4)删除cookie时,path必须一致,否则不会删除。

 

HttpSession

Session是服务器端技术,利用这个技术,服务器在运行时可以为每一个用户的浏览器创建一个其独享的HttpSession对象,由于session为用户浏览器独享,所以用户在访问服务器的web资源时,可以把各自的数据放在各自的session中,当用户再去访问服务器中的其他web资源时,其他web资源再从个各自用户的session中取出数据为用户服务。

Session和Cookie的主要区别:

1)Cookie是把用户的数据写给用户浏览器的。Session技术把用户的数据写到用户独占的session中,

2)Session对象由服务器创建,开发人员可以调用request对象的getSession方法得到session对象。

Session快速入门案例(实现数据共享)

SessionDemo1.java

package cn.lsl.session;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class SessionDemo1 extends HttpServlet {
    
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String name = request.getParameter("name");
        HttpSession session = request.getSession();
        System.out.println(session.getId());
        session.setAttribute("username", name);
        PrintWriter out = response.getWriter();
        out.write("put done!");
        out.write("<a href='/Session/servlet/SessionDemo2'>link</a>");
    }
    
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request,response);
    }
}

SessionDemo2.java

package cn.lsl.session;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class SessionDemo2 extends HttpServlet {
    
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        HttpSession session = request.getSession();
        String value = (String)session.getAttribute("username");
        response.getWriter().write(value);
    }
    
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request,response);
    }
}

注:

HttpServletRequest.getSession():根据特殊Cookie(JSESSIONID=HttpSession对象的id,由服务器生成,唯一的)的取值,在服务器的内存中根据id查找这个HttpSession对象,找到了,取出来继续服务;没有找到,创建一个新的HttpSession对象。

HttpServletRequest.getSession(boolean b):如果b为true,与上面方法功能完全一致。如果为false,只查询。

 

案例:用户的一次性登陆和随机验证码验证

User.java(实体类)

package cn.lsl.domain;

public class User {
    private String username;
    private String password;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}

ImageServlet.java(随机验证码)

package cn.lsl.code;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ImageServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 通知浏览器不要缓存
        response.setHeader("Expires", "-1");
        response.setHeader("Cache-Control", "no-cache");
        response.setHeader("Pragma", "no-cache");

        int width = 120;
        int height = 25;
        // 创建一副内存图像BufferedImage
        BufferedImage image = new BufferedImage(width, height,
                BufferedImage.TYPE_INT_RGB);
        // 得到属于该图片的画笔:Graphics();
        Graphics g = image.getGraphics();
        // 画边框
        g.setColor(Color.BLUE);
        g.drawRect(0, 0, width, height);
        // 填充背景色
        g.setColor(Color.YELLOW);
        g.fillRect(1, 1, width - 2, height - 2);
        // 画干扰线
        g.setColor(Color.GRAY);
        Random r = new Random();
        for (int i = 0; i < 10; i++)
            g.drawLine(r.nextInt(width), r.nextInt(height), r.nextInt(width), r
                    .nextInt(height));
        // 随机数字
        g.setColor(Color.RED);
        g.setFont(new Font("宋体", Font.BOLD | Font.ITALIC, 20));
        int x = 23;
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 4; i++) {
            String code = r.nextInt(10) + "";
            sb.append(code);
            g.drawString(code , x, 20);
            x = x + 20;
        }
        //把验证码放到HttpSession中
        request.getSession().setAttribute("code", sb.toString());
        // 输出到浏览器的页面上:ImageIO
        ImageIO.write(image, "jpg", response.getOutputStream());
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

login.html(登陆页)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>login.html</title>
    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="this is my page">
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  </head>
  
  <body>
    <form action="/Session/servlet/LoginServlet" method="post">
        用户名:<input type="text" name="username" /><br/>
        密码:<input type="password" name="password" /><br/>
        验证码:<input type="text" name="code" /><img src="/Session/servlet/ImageServlet"><br/>
        <input type="submit" value="登陆" />
    </form>
  </body>
</html>

IndexServlet.java(主页)

package cn.lsl.code;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import cn.lsl.domain.User;

public class IndexServlet extends HttpServlet {
    
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        HttpSession session = request.getSession();
        User user = (User)session.getAttribute("user");
        if(user == null){
            out.write("<a href='/Session/login.html'>登陆</a>");
        }else{
            out.write("欢迎您:"+user.getUsername()+"&nbsp;&nbsp;<a href='/Session/servlet/LogoutServlet'>注销</a>");
        }
    }
    
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request,response);
    }

}

LoginServlet.java(登陆)

package cn.lsl.code;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.lsl.domain.User;

public class LoginServlet extends HttpServlet {
    
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        
        //验证用户名和密码是否正确
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String code = request.getParameter("code");
        String sessionCode = (String)request.getSession().getAttribute("code");
        if(!code.equalsIgnoreCase(sessionCode)){
            out.write("错误的验证码<a href='/Session/login.html'>返回</a>");
            return;
        }
        StringBuffer sb = new StringBuffer(password);
        password = sb.reverse().toString();
        if(username.equals(password)){
            User user = new User();
            user.setUsername(username);
            user.setPassword(password);
            request.getSession().setAttribute("user", user);
            out.write("登陆成功。2秒后自动转回主页");
        }else{
            out.write("错误的用户名或密码。2秒后自动转回主页");
        }
        response.setHeader("Refresh", "2;URL=/Session/servlet/IndexServlet");
    }
    
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request,response);
    }

}

LogoutServlet.java(注销)

package cn.lsl.code;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class LogoutServlet extends HttpServlet {
    
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        request.getSession().removeAttribute("user");
        out.write("注销成功!2秒后将自动跳转向主页");
        response.setHeader("Refresh", "2;URL=/Session/servlet/IndexServlet");
    }
    
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request,response);
    }
}

简单的购物车案例

Book.java(实体类)

package cn.lsl.domain;

import java.io.Serializable;

public class Book implements Serializable {
    private String id;
    private String name;
    private String author;
    private Double price;
    private String description;
    public Book(){}
    public Book(String id, String name, String author, Double price,
            String description) {
        super();
        this.id = id;
        this.name = name;
        this.author = author;
        this.price = price;
        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 Double getPrice() {
        return price;
    }
    public void setPrice(Double price) {
        this.price = price;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    @Override
    public String toString() {
        return "Book [author=" + author + ", description=" + description
                + ", id=" + id + ", name=" + name + ", price=" + price + "]";
    }
}

BookDB.java(模拟数据库)

package cn.lsl.db;

import java.util.LinkedHashMap;
import java.util.Map;

import cn.lsl.domain.Book;

public class BookDB {
    private static Map<String, Book> books = new LinkedHashMap<String, Book>();
    static{
        books.put("1", new Book("1", "Java", "张三", 35.00, "Java入门"));
        books.put("2", new Book("2", "JavaEE", "李四", 45.00, "JavaEE入门"));
        books.put("3", new Book("3", "Android", "王五", 45.00, "Android入门"));
        books.put("4", new Book("4", "ios", "小舒", 55.00, "ios入门"));
        books.put("5", new Book("5", "html5", "小五", 35.00, "html5入门"));
    }
    //根据id查询书本
    public static Book findBookById(String bookId){
        return books.get(bookId);
    }
    //查询所有的书本
    public static Map<String, Book> findAllBooks(){
        return books;
    }
}

ShowAllBooksServlet.java(显示所有书籍)

package cn.lsl.cart;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.lsl.db.BookDB;
import cn.lsl.domain.Book;

public class ShowAllBooksServlet extends HttpServlet {
    
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        request.getSession();
        //显示所有商品
        out.write("<h1>本站有以下商品</h1>");
        Map<String,Book> books = BookDB.findAllBooks();
        for (Map.Entry<String, Book> me : books.entrySet()) {
            String url = "/Session/servlet/BuyServlet?id="+me.getKey();
            url = response.encodeURL(url);
            out.write(me.getValue().getName()+"&nbsp;&nbsp;<a href='"+url+"'>购买</a><br/>");
        }
        //提供出查看购物车的链接
        String url = "/Session/servlet/ShowCartServlet";
        url = response.encodeURL(url);
        out.write("<a href='"+url+"'>查看购物车</a>");
    }
    
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request,response);
    }

}

BuyServlet.java(加入购物车)

package cn.lsl.cart;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import cn.lsl.db.BookDB;
import cn.lsl.domain.Book;

public class BuyServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        String id = request.getParameter("id");
        Book book = BookDB.findBookById(id);
        //先查看有无购物车,如果有,直接用,没有就创建一个
        HttpSession session = request.getSession();
        List<Book> cart = (List<Book>) session.getAttribute("cart");
        if(cart == null){
            cart = new ArrayList<Book>();
            session.setAttribute("cart", cart);
        }
        cart.add(book);
        out.write(book.getName()+"已经放入购物车<br/>");
        String url = "/Session/servlet/ShowAllBooksServlet";
        url = response.encodeURL(url);
        out.write("<a href='"+url+"'>继续购物</a>");
        
        //自己写Cookie
        Cookie c = new Cookie("JSESSIONID",session.getId());
        c.setPath(request.getContextPath());
        c.setMaxAge(Integer.MAX_VALUE);
        response.addCookie(c);
    }
    
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request,response);
    }
}

ShowCartServlet.java(查看购物车)

package cn.lsl.cart;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import cn.lsl.domain.Book;

public class ShowCartServlet extends HttpServlet {
    
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        HttpSession session = request.getSession(false);
        if(session == null){
            out.write("对不起!您还未曾购物");
        }else{
            List<Book> cart = (List<Book>) session.getAttribute("cart");
            if(cart == null){
                out.write("对不起!您还未曾购物");
            }else{
                out.write("您购买的商品如下:<br/>");
                for (Book book : cart) {
                    out.write(book.getName()+"<br/>");
                }
            }
        }
        String url = "/Session/servlet/ShowAllBooksServlet";
        url = response.encodeURL(url);
        out.write("<a href='"+url+"'>继续购物</a>");
    }
    
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request,response);
    }

}

拓展:重写url

url---->url;JSESSIONID=123:URL重写.必须对网站中的所有URL地址都重写。

HttpServletResponse.encodeURL(url):是一个智能方法。判断用户是否禁用了Cookie,没有禁用,则不重写;禁用了就重写。

 

案例:防止表单重复提交

原理:表单页面由servlet程序生成,servlet为每次产生的表单页面分配一个唯一的随机标识号,并在FROM表单的一个隐藏字段中设置这个标识号,同时在当前用的session域中保存这个标识号。当用户提交FROM表单时,负责处理表单提交的servlet得到表单的标识号,并与session中存储的标识号比较,如果相同则处理表单提交,处理完后清除当前用户的Session域存储的标识号。

在下列情况下,服务器程序将拒绝用户提交的表单请求:

1)存储Session域中的表单标识号与表单提交的标识号不同

2)当前用户的Session中不存在表单标识号

3)用户提交的表单数据中没有标识号字段

原理图:

 

RegistUIServlet.java

package cn.lsl.session;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class RegistUIServlet extends HttpServlet {
    
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        PrintWriter out = response.getWriter();
        //随机生成一个令牌
        String token = UUID.randomUUID().toString();//唯一的一段序列
        //放入HttpSession中
        request.getSession().setAttribute("token", token);
        out.write("<form id='f1' action='"+request.getContextPath()+"/servlet/RegistServlet' method='post'>");
        out.write("姓名:<input type='text' name='name'/><br/>");
        out.write("<input type='hidden' name='token' value='"+token+"'/>");
        out.write("<input id='bt1' type='button' value='注册' onclick='toSubmit()'/></form>");
        out.write("<script type='text/javascript'>function toSubmit(){document.getElementById('f1').submit();document.getElementById('bt1').disabled=true;}</script>");
    }
    
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request,response);
    }

}

RegistServlet.java

package cn.lsl.session;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class RegistServlet extends HttpServlet {
    
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        PrintWriter out = response.getWriter();
        request.setCharacterEncoding("UTF-8");
        String name = request.getParameter("name");
        //判断用户是否重复提交
        String formToken = request.getParameter("token");
        String sessionToken = (String)request.getSession().getAttribute("token");
        if(formToken.equals(sessionToken)){
            //正常提交
            System.out.println("保存了:"+name);
            request.getSession().removeAttribute("token");
        }else{
            out.write("请不要重复提交");
        }
    }
    
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request,response);
    }

}

更改内存中HttpSession对象的超时时间

修改web.xml

<session-config>
    <session-timeout>1</session-timeout><!--自然整数,单位是分钟-->
</session-config>

 

posted @ 2014-05-06 13:20  Evan Liu  阅读(1499)  评论(0编辑  收藏  举报