欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

javaee(cookie和session)

程序员文章站 2022-06-23 18:39:35
...

cookie记录最后浏览时间

@WebServlet(urlPatterns = "/demo1")
public class demo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/css; charset=utf-8");
        PrintWriter writer = resp.getWriter();
        //获取客户端最后访问时间
        Cookie[] cookies = req.getCookies();
        for(int i=0;cookies!=null&&i<cookies.length;i++){
            if("last".equals(cookies[i].getName()))
            writer.write("你最后访问的时间是"+new Date().toLocaleString());
        }
        //创建cookie,并把信息写回客户端
       Cookie ck=new Cookie("last",System.currentTimeMillis()+"");
        //写入cookie
        resp.addCookie(ck);
    }
}
默认情况下cookie存续浏览器内存中,用户退出浏览器就删除,若希望浏览器将cookie存储在磁盘中

则需要maxAge,以秒为单位时间,最大值设0则是命令浏览器删除该cookie。

注意!!!

上下文中的不同地址的cookie是可以访问的,但前提是访问的路径以cookie的path开始的路径,浏览器就带,否则不带。

如果想让上下文都可以访问cookie,则使用cookie.setPath("/上下文名称"),来设置为顶层的cookie

        ck.setPath("/上下文名称");//低级
        ck.setPath(req.getContextPath());//中级   上下文名称
        ck.setPath("/");//高级    这个和上面等同,当前上下文的名称

保存用户名

js网页 在jsp获得cookie和在获取cookie后checked保持选择状态

<html>
<head>
    <title>Title</title>
</head>
<body>
    <%Cookie[] c=request.getCookies();
    String name="";
    String checked="";
        for(int i=0;c!=null&&i<c.length;i++){
            if(c[i].getName().equals("user")){
                name=c[i].getValue();
                checked="checked='checked'";
            }
        }
    %>
    <form action="${pageContext.request.contextPath}/cookie1" method="post">
        姓名:<input name="name" type="text" value="<%=name%>">
        密码:<input name="pwd" type="password">
        记住用户名:<input id="remember" type="checkbox" name="remember" <%=checked%>>
        <input type="submit" value="登录">
    </form>
</body>
</html>
servlet注意:path设置全局路径,获得表单文本控件没有输入为空字符串,而单选按钮和button则为null。

@WebServlet(urlPatterns = "/cookie1")
public class CookieDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");
        PrintWriter writer = resp.getWriter();
        String name = req.getParameter("name");
        String pwd = req.getParameter("pwd");
        String remember = req.getParameter("remember");
        Cookie ck=new Cookie("user",name);
        ck.setPath("/");
        if("tom".equals(name)&&"123".equals(pwd)){
            //表单类型不输入是空字符串,但是复选框和单选按钮不选是null
            if(remember!=null){
                ck.setMaxAge(Integer.MAX_VALUE);
            }else{
                ck.setMaxAge(0);
            }
            resp.addCookie(ck);
            writer.write("登录成功!");
        }else{
            writer.write("登录失败");
            //设置两秒跳到重新登录
            resp.setHeader("refresh","2;url="+req.getContextPath()+"/denglu.jsp");
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req,resp);
    }
}
浏览器历史记录

//实体类(书)
public class Book {
    private  String id;
    private String name;
    private String price;
    private String author;
    public Book(String id, String name, String price, String author) {
        this.id = id;
        this.name = name;
        this.price = price;
        this.author = author;
    }
    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 getPrice() {
        return price;
    }
    public void setPrice(String price) {
        this.price = price;
    }
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }
}
数据源(采用map存的数据,返回单个Book和整个map)

public class DBUtil {
    private  static Map<String,Book> books=new HashMap<>();
    static {
        books.put("1",new Book("1","java编程思想","20","小明"));
        books.put("2",new Book("2","java深入虚拟机","25","小明"));
        books.put("3",new Book("3","java设计模式","10","小明"));
        books.put("4",new Book("4","java并发","10","小明"));
        books.put("5",new Book("5","python编程","10","小明"));
    }
    //获取所有的书map类型
    public static Map<String,Book> getBooks(){
        return books;
    }
    //获取指定的书 根据id
    public static Book findBook(String id){
        return books.get(id);
    }
}
主页列出所有书籍(并且查看是否有对应的cookie)

@WebServlet(urlPatterns = "/showBook")
public class ShowAllBookServlet extends HttpServlet {
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req,resp);
    }
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.setContentType("text/html;charset=UTF-8");
        Map<String, Book> books = DBUtil.getBooks();
        PrintWriter writer = resp.getWriter();
        writer.write("本网站的有以下的好书:<br/>");
        for (Map.Entry<String,Book> book:books.entrySet()) {
            writer.write("<a href='"+req.getContextPath()+"/findBook?id="+book.getValue().getId()+"' target='_blank'>"+book.getValue().getName()+"</a><br>");
        }
        writer.write("<hr/>你最近浏览过的书有:<br/>");
        Cookie[] ck = req.getCookies();
        for(int i=0;i<ck.length;i++){
            //cookie带historyBookId的是浏览记录的id序列,进行切割获取id队友的Book(队列)
            if("historyBookId".equals(ck[i].getName())){
                String value=ck[i].getValue();
                String[] valuess = value.split("-");
                for (String s:valuess) {
                    Book book = DBUtil.findBook(s);
                    writer.print(""+book.getName());
                }
            }
        }
    }
}
点击查看单个书籍,并且添加到cookie中

@WebServlet(urlPatterns = "/findBook")
public class findBook extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=UTF-8");
        //获取get提交id参数
        String id = request.getParameter("id");
        Book book = DBUtil.findBook(id);
        PrintWriter writer = response.getWriter();
        writer.write("书籍名称:" + book.getName() + "<br>");
        writer.write("书籍价格:" + book.getPrice() + "<br>");
        writer.write("书籍作者:" + book.getAuthor() + "<br>");
        //把当前浏览过的书写会回到客户端
        String historyBook = organzeId(id, request);
        Cookie ck = new Cookie("historyBookId", historyBook);
        ck.setPath("/");
        ck.setMaxAge(Integer.MAX_VALUE);
        response.addCookie(ck);
    }

    /**
     * 没有cookie                             把当前的id给添加进去
     * 有cookie,但是没有historyBookId       把当前的id给添加进去
     * historyBookId                              2
     */
    private String organzeId(String id, HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        if (cookies == null) {
            //如果没有cookies就直接返回当前id
            return id;
        }
        //查找cookies名字是historyBookId的
        Cookie historyBookId = null;
        for (int i = 0; i < cookies.length; i++) {
            if("historyBookId".equals(cookies[i].getName())){
                historyBookId=cookies[i];
            }
        }
        if(historyBookId==null){
            return id;
        }
        //不管存储几个
        String value = historyBookId.getValue();
        String[] values = value.split("-");
        LinkedList<String> ls = new LinkedList<>(Arrays.asList(values));

        //历史记录最多保持3个(队列    先进先出)
        if(ls.size()<3){
            //如果浏览记录里面有重复的id就删除掉。
            if(ls.contains(id)){
                ls.remove(id);
            }
        }else{
            //超过3个就浏览记录就删除最后一个或者包含的id
            if(ls.contains(id)){
                ls.remove(id);
            }else{
                ls.removeLast();
            }
        }
        ls.addFirst(id);//添加到最前面
        StringBuffer sb = new StringBuffer();
        for (int i=0;i<ls.size();i++){
            if(i>0){
                sb.append("-");
            }
            sb.append(ls.get(i));
        }
        return sb.toString();
    }
}



HttpSession对象原理

1.获取名称为JSESSIONID的cookie的值

2.没有这样的cookie,创建一个新的session对象,分配唯一的SessionId,并且向客户端写一个名字叫JSESSION=sessionID的cookie

3.有这个样的Cookie,获取cookie的值,从服务器内存中根据ID找那个session对象。

HttpSession对象状态

出生request.getSession();

活着:应用运行时

搁置:内存溢出,服务器重启,会在tomcat目录的work下持久化,等启动服务器后,session就自动的回调进内存(放心大胆的重启服务器,不用担心session的丢失)

持久化:存盘,IO实现serializable

死亡:超时,默认30分钟,setMaxInactiveInterval(int);

   Session,invalidate();强制销毁

 在xml中配置<session-config>单位分钟


session是一个域对象,可以存储对象

getId()获取对象,setMaxInactiveInterval(int )设置session存活时间,秒做单位

invalidate()使得会话无效

cookie客户端技术,只能存取字符串


客户端禁用Cookie后回话数据保存问题

解决方案:

1.在主页上给出提示,请不要禁用cookie。

2.URL重写。必需对网站的所有地址都重写。(刷新会有问题)

http://url -->http://url;JSESSIONID=111

response.encodeURL(String url);//前提写上request.getSession()不然没用作用

看到浏览有没有发送cookie请求的消息头,没有就重写URL,有就不重写。