Cookie和Session

什麼是會話?javascript

會話能夠簡單理解爲:用戶開一個瀏覽器,點擊多個超連接,訪問服務器多個web資源,而後關閉瀏覽器,整個過程稱之爲一個會話。html

保存會話數據的兩種技術:Cookie和HttpSessionhtml5

Cookie:java

Cookie是客戶端技術,程序把每一個用戶的數據以cookie的形式寫給用戶各自的瀏覽器。當用戶使用瀏覽器再去訪問服務器中的web資源時,就會帶着各自的數據去。這樣,web資源處理的就是用戶各自的數據了。ios

1.Cookie入門案例(上次訪問時間)web

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>
相關文章
相關標籤/搜索