• 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>
  • 相关阅读:
    java代码,继承。。。主要是传值,赋值。
    java代码继承。。。找出不能继承父类方法的问题
    java代码继承super
    HDU 6114 Chess
    #113. 【UER #2】手机的生产
    uoj 118 赴京赶考
    戏game
    序sort
    迷enc
    Jupyter 同时支持python2、python3 kernel
  • 原文地址:https://www.cnblogs.com/EvanLiu/p/3711318.html
Copyright © 2020-2023  润新知