cookie&session

来源:互联网 发布:侠客风云传优化工具 编辑:程序博客网 时间:2024/06/06 07:49

1. 什么是会话

是指浏览器和服务端之间的数据传输(用户登录,购物车等)

会话管理就是管理浏览器和服务端会话过程产生的会话数据

常用的会话技术:

数据保存在浏览器的Cookie技术

数据保存在服务端的Session技术

2. Cookie技术

1. 什么是Cookie

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

2. Cookie技术核心API

Cookie类:用于存储会话数据,常用方法如下:
- 构造Cookie对象

Cookie(String name,String value)
  • 设置cookie
void setPath(String uri):设置cookie的有效访问路径void setMaxAge(int expiry):设置cookie的有效时间void setValue(String newValue):设置cookie的值
  • 发送cookie到浏览器保存
void response.addCookie(Cookie cookie):发送cookie
  • 服务器端接收cookie
Cookie[] request.getCookies():接收cookie

Demo:

public class CookieDemo extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        // 1.创建Cookie对象        Cookie cookie = new Cookie("name", "value");        // 2.设置Cookie参数        // 2.1设置Cookie的有效路径        cookie.setPath("/hello");// 默认就是web项目的地址        // 2.2设置Cookie的有效时间        cookie.setMaxAge(20);// 此cookie只存活20秒,从最后不调此cookie开始计算        cookie.setMaxAge(-1);// 此cookie保存在浏览器内存中,关闭浏览器则销毁此cookie        cookie.setMaxAge(0);// 删除与此cookie同名的cookie        // 3.把数据发送到浏览器        response.addCookie(cookie);        // 4.服务端接收来自浏览器的cookie        // 方法一:        // String name=request.getHeader("cookie");        // System.out.println(name);        // 方法二:        Cookie[] cookies = request.getCookies();        for (Cookie c : cookies) {            String name = c.getName();            String value = c.getValue();            System.out.println(name + "=" + value);        }    }    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        doGet(request, response);    }}

3. Cookie原理

  1. 服务器创建Cookie对象,把会话数据存储到Cookie对象中
new Cookie("name","value");
  1. 服务器发送cookie信息到浏览器
response.addCookie(cookie);//其实是隐藏发送了一个set-cookie名称的响应头
  1. 浏览器得到服务器发送的cookie,然后保存在浏览器端
  2. 浏览器下次访问服务器时,会带着cookie信息
包含在http的请求头里
  1. 服务器接收到浏览器带来的cookie信息
request.getCookies();

4.Cookie的细节

  1. void setPath(String uri):设置cookie的有效访问路径,有效访问路径指的是Cookie的有效路径保存在哪里,那么浏览器在有效路径下访问服务器时就会带着Cookie信息,否则不带Cookie信息,默认是在当前web项目的路径下
  2. void setMaxAge(int expiry):设置cookie的有效时间

    expiry可以是正整数,负整数和零

    正整数:表示Cookie数据保存浏览器的缓存到硬盘中,数值表示保存的时间

    负整数:表示Cookie数据保存到浏览器的内存中,浏览器关闭Cookie就丢失了

    零:表示删除同名的Cookie数据

  3. Cookie数据类型只能保存非中文字符串类型的。可以保存多个Cookie,但是浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4kb

5. Cookie应用:显示用户上次访问的时间

功能实现逻辑:

把时间保存在Cookie中,每次访问从Cookie里面调用

第一次访问:
1. 获取当前时间,显示到浏览器上
2. 创建Cookie对象,时间作为cookie值,名为:lastTime
3. 把cookie发送到浏览器保存

第n次访问:
1. 获取cookie的数据,取出名为lastTime的cookie
2. 得到cookie的值(上次访问时间)
3. 显示上次访问时间到浏览器上
4. 更新名为lastTime的cookie,值设置为当前时间
5. 把更新后的cookie发送给浏览器保存

代码实现:
public class CookieDemo2 extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        response.setContentType("text/html;charset=UTF-8");        // 获取当前时间        SimpleDateFormat t = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");        String curTime = t.format(new Date());        // 取得cookie        Cookie[] cookies = request.getCookies();        String lastTime = null;        // 第n次访问        if (cookies != null) {            for (Cookie cookie : cookies) {                if (cookie.getName().equals("lastTime")) {                    // 有lastTime的cookie,已经是第n次访问                    lastTime = cookie.getValue();//上次访问的时间                    // 第n次访问                    // 1.把上次访问时间显示到浏览器上                    response.getWriter().write(                            "欢迎回来,你上次访问的时间是: " + lastTime + ",当前时间为: "+ curTime);                    // 2.更新cookie                    cookie.setValue(curTime);                    cookie.setMaxAge(1 * 30 * 24 * 60 * 60);                    // 3.把更新后的cookie发送到浏览器                    response.addCookie(cookie);                    break;                              }            }        }        // 第一次访问 没有cookie 或有cookie但没有名为lastTime的cookie        if (cookies == null || lastTime == null) {            // 1.显示当前时间到浏览器上            response.getWriter().write("你是首次访问本网站,当前时间是: " + curTime);            // 2.创建Cookie对象            Cookie cookie = new Cookie("lastTime", curTime);            cookie.setMaxAge(1 * 30 * 24 * 60 * 60);            // 3.把cookie发送到浏览器保存            response.addCookie(cookie);        }    }    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        doGet(request, response);    }}

6. Cookie应用:查看用户浏览过的商品

功能实现逻辑:

这里写图片描述

代码实现:
import java.io.IOException;import java.io.PrintWriter;import java.util.Map.Entry;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 ListServlet extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        response.setCharacterEncoding("UTF-8");        response.setContentType("text/html; charset=UTF-8");        PrintWriter out = response.getWriter();        // 显示商品列表        out.write("书籍列表: <br/>");        for (Entry<String, Book> b : Db.getBooks().entrySet()) {            out.write("<a href='" + request.getContextPath()                    + "/servlet/detailServlet?id=" + b.getKey()                    + "' target='_blank'>" + b.getValue().getName()                    + "</a><br/>");        }        // 显示浏览过的商品        out.write("<br/>浏览过的 : <br/>");        Cookie[] cookies = request.getCookies();        for (int i = 0; cookies != null && i < cookies.length; i++) {            if (cookies[i].getName().equals("history")) {                String[] ids = cookies[i].getValue().split("\\-");                for (String s : ids) {                    out.write(Db.getBooks().get(s).getName() + "<br/>");                }            }        }    }    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        doGet(request, response);    }}
import java.io.IOException;import java.io.PrintWriter;import java.util.Arrays;import java.util.LinkedList;import java.util.Map.Entry;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 DetailServlet extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        response.setCharacterEncoding("UTF-8");        response.setContentType("text/html; charset=UTF-8");        PrintWriter out = response.getWriter();        // 显示商品详情        out.write("书籍详情: <br/>");        String id = request.getParameter("id");        for (Entry<String, Book> b : Db.getBooks().entrySet()) {            if (id.equals(b.getKey())) {                out.write(b.getValue().getId() + "<br/>");                out.write(b.getValue().getName() + "<br/>");                out.write(b.getValue().getPrice() + "<br/>");                out.write(b.getValue().getAuthor() + "<br/>");            }        }        // 回写cookie,保存最后浏览的商品id        String history = buildIds(id, request);        Cookie cookie = new Cookie("history", history);        cookie.setMaxAge(1 * 30 * 24 * 60 * 60);        cookie.setPath("/cookieTest");        response.addCookie(cookie);    }    private String buildIds(String id, HttpServletRequest request) {        String history = null;        Cookie[] cookies = request.getCookies();        for (int i = 0; cookies != null && i < cookies.length; i++) {            if (cookies[i].getName().equals("history")) {                history = cookies[i].getValue();            }        }        if (history == null) {            System.out.println(id);            return id;        }        LinkedList<String> ids = new LinkedList<String>(Arrays.asList(history                .split("\\-")));        if (ids.contains(id)) {            ids.remove(id);        } else {            if (ids.size() >= 3) { // 最多显示3条浏览历史                ids.removeLast();            }        }        ids.addFirst(id);        StringBuffer sb = new StringBuffer();        for (int j = 0; j < ids.size(); j++) {            if (j != ids.size() - 1) {                sb.append(ids.get(j)).append("-");            } else {                sb.append(ids.get(j));            }        }        System.out.println(sb);        return sb.toString();    }    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        doGet(request, response);    }}
public class Book {    private String id;    private String name;    private double price;    private String author;    public Book(String id, String name, double price, String author) {        super();        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 double getPrice() {        return price;    }    public void setPrice(double price) {        this.price = price;    }    public String getAuthor() {        return author;    }    public void setAuthor(String author) {        this.author = author;    }}
import java.util.LinkedHashMap;import java.util.Map;class Db {    private static Map<String, Book> books = new LinkedHashMap<String, Book>();    static {        books.put("1", new Book("1", "红楼梦", 15, "曹雪芹"));        books.put("2", new Book("2", "大漠谣", 20, "桐华"));        books.put("3", new Book("3", "诛仙", 15, "萧鼎"));        books.put("4", new Book("4", "朝花夕拾", 25, "鲁迅"));    }    public static Map<String, Book> getBooks() {        return books;    }}

3. Session技术

1. 什么是Session

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

2. Session的核心技术

HttpSession类:用于保存会话数据,常用方法如下:
- 创建或得到session对象

HttpSession getSession():直接创建一个Session对象HttpSession getSession():接收布尔值,设置为true时,在没有找到匹配Session编号的对象时新建一个Session对象如果设置为false,则当找不到匹配的Session时,返回null
  • 设置session对象
void setMaxInactiveInterval(int interval):设置session的有效时间默认30分钟自动回收session对象String getId():得到session编号void invalidate():销毁session对象
  • 保存会话数据到session对象
void setAttribute(String name,object value):保存数据Object getAttribute(String name):获取数据void removeAttribute(String name):清除数据
  • 如何避免浏览器的JSESSIONID的cookie随着浏览器关闭而丢失的问题
解决方法是手动发送一个硬盘保护的cookie给浏览器

Demo:

public class SessionServletDemo extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        // 1.创建Session对象        HttpSession session = request.getSession();        // 2.保存会话数据        session.setAttribute("name", "eric");        // 3.取出会话数据        String name = (String) session.getAttribute("name");        System.out.println(name);        // 4.1拿到session的id        System.out.println(session.getId());        // 4.2修改session的有效时间        session.setMaxInactiveInterval(20);        // 4.3销毁session        if (session != null) {            session.invalidate();        }        // 5.手动发送一个硬盘保存的cookie给浏览器        Cookie c = new Cookie("JSESSION", session.getId());        c.setMaxAge(60 * 60);        response.addCookie(c);    }    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        doGet(request, response);    }}

3. Session原理

代码解读:HttpSession session=request.getSession();
伪码分析执行过程
1. 第一次访问创建Session对象,给Session对象分配一个唯一的ID,叫JSESSIONID

new HttpSession();
  1. 把JSESSIONID作为Cookie的值发送给浏览器保存
Cookie cookie = new Cookie("JSESSIONID",sessionID);response.addCookie(cookie);
  1. 第二次访问时,浏览器带着JSESSIONID的cookie访问服务器
  2. 服务器得到JSESSIONID,在服务器的内存中搜索是否存放对应编号的session对象
  3. 如果找到对应编号的session对象,直接返回此对象
  4. 如果找不到对应编号的session对象,创建新的session对象,继续走1的流程

结论:通过JSESSION的cookie值在服务器中找session对象

4. Session应用:用户登录效果

需求:实现用户登录效果,如果登录成功,显示欢迎回来,xxx。如果失败显示登录失败
默认登录页面:

<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>登录页面</title></head><body>    <form action="/cookieTest/servlet/loginServlet" method="post">        用户名:<input type="text" name="userName" /> <br />         密码:<input type="text" name="userPwd" /> <br />         <input type="submit" value="登录" />    </form></body></html>

登录失败页面:

<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>信息提示页面</title></head><body>    <font color='red' size='3'>亲,你的用户名或密码输入有误!请重新输入!</font>    <br />    <a href="/cookieTest/index.html">返回登录界面</a></body></html>

表单提交后的主处理逻辑:

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 IndexServlet extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        response.setContentType("text/html;charset=UTF-8");        PrintWriter out = response.getWriter();        String html = "";        HttpSession session = request.getSession(false);        if (session == null) {            response.sendRedirect(request.getContextPath() + "/index.html");            return;        }        String userName = (String) session.getAttribute("userName");        if (userName == null) {            response.sendRedirect(request.getContextPath() + "/index.html");            return;        }        html = "<html><body>欢迎回来," + userName + ",<a href='"                + request.getContextPath()                + "/servlet/logoutServlet'>安全退出</a></body></html>";        out.write(html);    }    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        doGet(request, response);    }}

登录处理逻辑:

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 LoginServlet extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        request.setCharacterEncoding("UTF-8");        String userName = request.getParameter("userName");        String userPwd = request.getParameter("userPwd");        if ("eric".equals(userName) && "123456".equals(userPwd)) {            HttpSession session = request.getSession();            session.setAttribute("userName", userName);            response.sendRedirect(request.getContextPath() + "/servlet/indexServlet");        } else {            response.sendRedirect(request.getContextPath() + "/fail.html");        }    }    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        doGet(request, response);    }}

退出处理逻辑:

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 LogoutServlet extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        HttpSession session = request.getSession(false);        if (session != null) {            session.removeAttribute("userName");        }        response.sendRedirect(request.getContextPath() + "/index.html");    }    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        doGet(request, response);    }}

5. Session应用:购物车

public class Book {    private String id;    private String name;    private double price;    private String author;    public Book(String id, String name, double price, String author) {        super();        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 double getPrice() {        return price;    }    public void setPrice(double price) {        this.price = price;    }    public String getAuthor() {        return author;    }    public void setAuthor(String author) {        this.author = author;    }}
import java.util.LinkedHashMap;import java.util.Map;class Db {    private static Map<String, Book> books = new LinkedHashMap<String, Book>();    static {        books.put("1", new Book("1", "红楼梦", 15, "曹雪芹"));        books.put("2", new Book("2", "大漠谣", 20, "桐华"));        books.put("3", new Book("3", "诛仙", 15, "萧鼎"));        books.put("4", new Book("4", "朝花夕拾", 25, "鲁迅"));    }    public static Map<String, Book> getBooks() {        return books;    }    public static Book findBookById(String id){        return books.get(id);    }}
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;public class ListServlet extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        response.setContentType("text/html;charset=UTF-8");        PrintWriter out = response.getWriter();        out.print("本网站有以下书籍:<br/>");        Map<String, Book> books = Db.getBooks();        for (Map.Entry<String, Book> book : books.entrySet()) {            String url = request.getContextPath() + "/servlet/addCart?id="                    + book.getKey();            out.print("<a href='" + response.encodeURL(url) + "'>"                    + book.getValue().getName() + "</a><br/>");        }        String url2 = request.getContextPath() + "/servlet/showCart";        out.print("<a href='" + response.encodeURL(url2) + "'>查看购物车</a>");    }    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        doGet(request, response);    }}
import java.io.IOException;import java.io.PrintWriter;import java.util.ArrayList;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;public class AddCart 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 = Db.findBookById(id);        HttpSession session = request.getSession();        List<Book> list = (List<Book>) session.getAttribute("cart");        if (list == null) {            list = new ArrayList<Book>();        }        list.add(book);        session.setAttribute("cart", list);        out.print("购买成功!");    }    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        doGet(request, response);    }}
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;public class ShowCart extends HttpServlet {    public void doGet(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        response.setContentType("text/html;charset=UTF-8");        PrintWriter out = response.getWriter();        out.print("购物车有以下书籍:<br/>");        HttpSession session = request.getSession();        List<Book> books = (List<Book>) session.getAttribute("cart");        if (books == null) {            out.print("你还什么都没买呢");            response.setHeader("refresh", "2;url=" + request.getContextPath()                    + "/servlet/listServlet");            return;        }        for (Book book : books) {            out.write(book.getName() + "<br/>");        }    }    public void doPost(HttpServletRequest request, HttpServletResponse response)            throws ServletException, IOException {        doGet(request, response);    }}
原创粉丝点击