cookie使用-实现登录时间的记录,和浏览历史的显示

cookie的作用

每次学习一个技术的时候首先要搞明白它的作用是么?首先要明确一点,http的连接是无状态的,它不会保存你之前发送的所有请求,不会知道两次访问服务器的人是不是同一个.cookie的本质是一段文体数据,储存在客户端,可能是硬盘可能是内存

实现每次登录时间的记录

两个步骤:

  • 拿到cookie,读出存在cookie中的值
  • 写cookie,将每次的新访问时间写进cookie里面
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        test1(request, response);
    }

    private void test1(HttpServletRequest request, HttpServletResponse response) throws IOException {

        // 拿到了cookie了,写在页面上
        // 解决编码问题
        response.setCharacterEncoding("UTF-8");
        response.setHeader("content-type", "text/html;charset=UTF-8");
        PrintWriter writer = response.getWriter();

        //读值
        Cookie[] cookies = request.getCookies();
        for (int i = 0; cookies != null && i < cookies.length; i++) {
            Cookie cookie = cookies[i];
            String name = cookie.getName();
            if (name.equals("lastAccessTime")) {
                String lastTime = cookie.getValue();
                writer.write("您上次访问的时间是" + URLDecoder.decode(lastTime, "UTF-8"));
            }
        }

        // 获取本地最新时间,设置cookie
        Date now = new Date();
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        String currentTime = format.format(now);
        Cookie cookie = new Cookie("lastAccessTime", URLEncoder.encode(currentTime, "UTF-8"));
        response.addCookie(cookie);

注意点:

  • 编码问题
  • cookie为空的判断,如果对方是第一次访问,则没有这个值,也就不用显示上次访问时间了
  • 日期格式化一下,这样符合咱中国人的阅读顺序
  • cookie中的值不能为空值,如果有的话,就用URLEncoder进行编码,再解码,不然会报错An invalid character [32] was present in the Cookie value,意思是存在了空值

实现浏览历史

思路:

  • cookie设置浏览记录id_id_id的形式,避免占用多个cookie
  • 两个页面
    • 一个页面作为主页,显示有哪些书,显示历史记录
    • 一个页面作为详情页面,同时设置cookie.

代码:

主页面:
DB用来存入数据,容器是Map,直接静态代码块赋值即可
Book是抽象化的书对象

package cookie;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

@WebServlet(name = "ServletCookieDemo2")
public class ServletCookieDemo2 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // 显示所有的书及其链接
        response.setCharacterEncoding("UTF-8");
        response.setHeader("content-type", "text/html;charset=UTF-8");
        PrintWriter writer = response.getWriter();

        writer.write("一共有如下书:<br>");
        Map<String, Book> map = DB.getAll();
        for (Map.Entry<String, Book> entry : map.entrySet()) {
            Book book = entry.getValue();
            writer.write("<a href='/jsp/ServletCookieDemo3?id=" + book.getId() + "' target='_blank'>" + book.getName() + "</a><br>");
        }
        writer.write("<br>");

        writer.write("浏览历史为:<br>");
        // 写上访问历史
        Cookie[] cookies = request.getCookies();
        for (int i = 0; cookies != null && i < cookies.length; i++) {
            Cookie cookie = cookies[i];
            if (cookie.getName().equals("bookHistory")) {
                String value = cookie.getValue();
                String[] ids = value.split("_");
                for (String id : ids) {
                    writer.write(DB.getAll().get(id).getName()+"<br>");
                }
            }
        }
    }
}

class DB {
    private static Map<String, Book> map = new LinkedHashMap<>();

    static {
        map.put("1", new Book("1", "java", "a", "12"));
        map.put("2", new Book("2", "php", "a", "12"));
        map.put("3", new Book("3", "python", "a", "12"));
        map.put("4", new Book("4", "js", "a", "12"));
        map.put("5", new Book("5", "html", "a", "12"));
    }

    public static Map<String, Book> getAll() {
        return map;
    }
}

class Book {

    private String id;
    private String name;
    private String auther;
    private String price;

    public Book(String id, String name, String auther, String price) {
        this.id = id;
        this.name = name;
        this.auther = auther;
        this.price = price;
    }

    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 getAuther() {
        return auther;
    }

    public void setAuther(String auther) {
        this.auther = auther;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Book{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", auther='" + auther + '\'' +
                ", price='" + price + '\'' +
                '}';
    }
}

详情页面:

  • 将cookie的字符串数组分割然后装进linkedHashMap中,因为LinkedHashMap是有序的,不会乱了访问顺序.
  • 用StringBuilder对添加后的LinkedHashMap进行重组,得到最后的Cookie的字符串
  • 给cookie加上期限
package cookie;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

@WebServlet(name = "ServletCookieDemo3")
public class ServletCookieDemo3 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //显示书的详情
        response.setCharacterEncoding("UTF-8");
        response.setHeader("content-type", "text/html;charset=UTF-8");
        PrintWriter writer = response.getWriter();

        String id = request.getParameter("id");
        Book book = DB.getAll().get(id);
        writer.write(book.toString());

        String bookHistory = makeHistory(request, id);
        Cookie cookie = new Cookie("bookHistory", bookHistory);
        cookie.setMaxAge(1*30*24*3600);
        response.addCookie(cookie);

    }

    private String makeHistory(HttpServletRequest request, String id) {
        /*
         写cookie,新访问的是1

         -----以前没有1(不包含1)----超过最大数3个:删除最后一个再头插
           |                   |
           |                   |
           |                   |--不超过:直接头插
           |
           |--以前有1(包含1):去除,重新添加进头部

         old   new
         null  1
         3_1   1_3
         3_1_2 1_3_2
         3_2   1_3_1
         */
        String bookHistory = null;
        Cookie[] cookies = request.getCookies();
        for (int i = 0; cookies != null && i < cookies.length; i++) {
            Cookie cookie = cookies[i];
            if (cookie.getName().equals("bookHistory")) {
                bookHistory = cookie.getValue();
                System.out.println(bookHistory);
            }
        }

        if (bookHistory == null) {
            return id;
        }
        List<String> list = Arrays.asList(bookHistory.split("_"));
        LinkedList<String> linkedList = new LinkedList<>(list);
        // 包含
        if (linkedList.contains(id)) {
            System.out.println("包含"+id);
            linkedList.remove(id);
            linkedList.addFirst(id);
        } else {
            // 超过最大数3个:删除最后一个再头插
            if (linkedList.size() >= 3) {
                linkedList.removeLast();
                linkedList.addFirst(id);
            } else {
                // 不超过:直接头插
                linkedList.addFirst(id);
                System.out.println("头插成功");
            }
        }

        StringBuilder builder = new StringBuilder();
        for (String value : linkedList) {
            builder.append(value+"_");
        }

        System.out.println(builder.toString());
        return builder.deleteCharAt(builder.length() - 1).toString();
    }
}

总结要点

关键就在于历史记录如何构成的问题,一共分了几块去写它,保证最新的排在最前面,这个顺序很重要.其它小细节有LinkedHashMap保证有序性,id_id_id的历史记录写法,字符串数组到list的转换,cookie的遍历获得指定的那个.

纸上得来终觉浅,绝知此事要躬行.

猜你喜欢

转载自blog.csdn.net/qq_41376740/article/details/81072659
今日推荐