JavaWeb之cookie&session

2021/5/22 12:28:12

本文主要是介绍JavaWeb之cookie&session,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

JavaWeb之cookie&session

  • 一、会话概述
  • 二、cookie
    • 2.1 cookie的属性
    • 2.2 cookie相关API
    • 2.3 cookie的一些细节
    • 2.4 使用cookie完成购物车案例
  • 三、session
    • 3.1 session概述
    • 3.2 session的基本使用
      • 3.2.1 获取session的方法
      • 3.2.2 会话域
      • 3.2.3 HttpSession原理
      • 3.2.4 cookie和session的区别
      • 3.2.5 持久化级别session
      • 3.2.6 session的使用细节

一、会话概述

日常生活中:从拨通电话到挂断电话之间的一连串你问我答的过程就是一个会话。

B/S架构中 : 从浏览器第一次给服务器发送请求时,建立会话;直到有一方断开,会话结束。

一次会话:包含多次请求响应。

会话中出现的问题:由于Http是一个无状态协议,不会记录每次请求的状态,这就造成了同一个会话的两请求之间相互独立,彼此没有联系。

此时就需要一种技术在客户端或者服务端,记录会话过程中产生的一些数据,这就是会话管理技术。

两种会话管理技术:

  • cookie:在一次会话的多次请求响应之间共享数据,将数据保存到客户端(浏览器)
  • session:在一次会话的多次请求之间共享数据,它将数据保存到服务器

二、cookie

cookie:利用客户端保存共享信息实现多次请求的数据共享。

使用cookie需要导入javax.servlet.http.Cookie

2.1 cookie的属性

  • name cookie的名称
  • value cookie的值
  • domain cookie的域名,默认值是访问服务的主机名称
  • path cookie的路径,默认值是应用的发布URI(发布名称/发布路径)
  • maxAge cookie的存活时间,0表示立即销毁
  • comment 描述信息 (无关紧要的属性)
  • version 版本号 (无关紧要的属性)

2.2 cookie相关API

方法名作用
Cookie cookie = new Cookie(name,value)创建Cookie对象
response.addCookie(Cookie c)将cookie写回浏览器
cookie.getName()获取cookie名
cookie.getValue()获取cookie的值
Cookie [] cookis = request.getCookies()获取cookie数组
cookie.setMaxAge(秒)设置cookie的有效时间
cookie.setPath("/path")设置cookie再次访问服务器时,自动携带cookie的依据

客户端带cookie到服务器机制:
请求资源URI去掉资源的部分之后和Cookie的Path进行比较,请求资源URI去掉资源的部分.startWith(cookiePath),结果为true,客户端就会带着cookie访问浏览器;如果为false,客户端访问浏览器就不会带cookie。

coolkiePath   /cookieandsession/servlet
PathQuestionDemo2     访问URI:     /cookieandsession/PathQuestionDemo2		
			URI去掉资源的部分:      /cookieandsession
PathQuestionDemo3     访问URI:     /cookieandsession/servlet/PathQuestionDemo3	
             URI去掉资源的部分:     /cookieandsession/servlet             

在上面的案例中,只有PathQuestionDemo3访问服务器会带着cookie

2.3 cookie的一些细节

  1. 一个服务器在浏览器端最多支持20个Cookie
  2. 所有服务器在浏览器端最多可以写300个Cookie
  3. 每个Cookie的大小不能超过4KB
  4. 定位一个cookie,domain+path+name

2.4 使用cookie完成购物车案例

xml配置:

<servlet>
        <servlet-name>CartServlet</servlet-name>
        <servlet-class>com.itcast.cart.CartServlet</servlet-class>
</servlet>
<servlet-mapping>
        <servlet-name>CartServlet</servlet-name>
        <url-pattern>/cart</url-pattern>
</servlet-mapping>

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>购物车</title>
</head>
<body>
<a href="/cookieandsession/cart?action=showProductList">查看商品列表</a>
<hr/>
<a href="/cookieandsession/cart?action=showCartInfo">查看购物车</a>
</body>
</html>
public class CartServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //设置请求正文字符集
        req.setCharacterEncoding("UTF-8");
        //设置响应正文的MIME类型和字符集
        resp.setContentType("text/html;charset=UTF-8");
        //获取请求参数
        String action = req.getParameter("action");
        if ("showProductList".equals(action)){
            showProductList(req,resp);
        }else if ("showCartInfo".equals(action)){
            showCartInfo(req,resp);
        }else {
            System.out.println("无信息");
        }
        //获取请求参数
        String productName = req.getParameter("productName");
        if (productName != null){
            addCart(req,resp,productName);
        }

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }

    private void showProductList(HttpServletRequest req, HttpServletResponse resp){
        PrintWriter out = null;
        try {
            //获取输出流
            out = resp.getWriter();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //输出商品列表
        out.write("01.Xiaomi&nbsp;&nbsp;&nbsp;<a href='"+req.getContextPath()+"/cart?action=showProductList&productName=Xiaomi'>添加购物车</a><br/>");
        out.write("02.Huawei&nbsp;&nbsp;&nbsp;<a href='"+req.getContextPath()+"/cart?action=showProductList&productName=Huawei'>添加购物车</a><br/>");
        out.write("03.Lianxiang&nbsp;&nbsp;&nbsp;<a href='"+req.getContextPath()+"/cart?action=showProductList&productName=Lianxiang'>添加购物车</a><br/>");
    }

    private void showCartInfo(HttpServletRequest req, HttpServletResponse resp){
        PrintWriter out = null;
        try {
            //获取输出流
            out = resp.getWriter();
        } catch (IOException e) {
            e.printStackTrace();
        }
        out.write("<h1>购物车的详情:</h1>");
        //获取Cookie
        Cookie[] cookies = req.getCookies();
        //4.判断
        if(cookies == null || cookies.length == 0){
            out.write("您还没有添加商品到购物车");
        }else {
            for (Cookie cookie : cookies){
                //判断
                if("CartInfo".equals(cookie.getName())){
                    //找到了我们想要的cookie
                    String value = cookie.getValue();//Xiaomi-Xiaomi-Lianxiang
                    //分隔
                    String[] productNames = value.split("-");
                    //遍历名称
                    for(String productName : productNames){
                        out.write(productName+"<br/>");
                    }
                }
            }
        }
    }

    private void addCart(HttpServletRequest req, HttpServletResponse resp,String productName){
        PrintWriter out = null;
        try {
            //取出输出流
            out = resp.getWriter();
        } catch (IOException e) {
            e.printStackTrace();
        }
        //取出Cookie
        Cookie[] cookies = req.getCookies();
        //定义要写到客户端的Cookie
        Cookie cookie = null;
        //判断,如果没有Cookies就是第一次
        if(cookies == null || cookies.length == 0){
            cookie = new Cookie("CartInfo",productName);
        }else {
            //遍历
            for(Cookie c : cookies){
                //判断名称
                if("CartInfo".equals(c.getName())){
                    cookie = c;
                    break;
                }
            }
            //给cookie拼值,就是在原来的value上,再加上新的value(productName)
            String value = cookie.getValue()+"-"+productName;
            cookie.setValue(value);
        }
        //设置最大存活时间
        cookie.setMaxAge(Integer.MAX_VALUE);
        //把cookie写到浏览器
        resp.addCookie(cookie);
        //提示
        out.write("<hr size='7px' color='orange'>");
        out.write("添加成功。<a href='"+req.getContextPath()+"/cart?action=showCartInfo'>查看购物车</a>");
    }
}

三、session

3.1 session概述

session:在一次会话的多次请求之间共享数据,将数据保存到服务器端

在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),注意:一个浏览器独占一个session对象(默认情况下)。因此,在需要保存用户数据时,服务器程序可以把用户数据写到用户浏览器独占的session中,当用户使用浏览器访问其它程序时,其它程序可以从用户的session中取出该用户的数据,为用户服务。

Session对象由服务器创建,开发人员可以调用request对象的getSession方法得到session对象。

使用session需要导入javax.servlet.http.HttpSession

3.2 session的基本使用

3.2.1 获取session的方法

  • HttpSession session = request.getSession(); 无论之前有还是没有session,都会有返回一个session,若之前的找到了就使用之前的session;若之前的session没有找到,就创建一个session
  • HttpSession session = request.getSession(boolean create);当create为true时,与request.getSession()使用情况一致;当create为false时,若之前的找到了就使用之前的session;若之前的session没有找到,就返回null

3.2.2 会话域

HttpSession也是一个域对象,它表示的是会话域,作用范围是一次会话之中(包含多次请求)。

域对象常用api:

  • getAttribute(String name) 通过属性名获取域对象的属性
  • setAttibute(String name , Object obj) 设置域对象的属性
  • removeAttribtue(String name) 通过属性名移除域对象的属性

session生命周期:

  • 创建:第一次调用request.getSession() 创建session对象
  • 销毁:
1.关闭浏览器,会话结束;
2.超过一定时间没有对网站有任何操作时,会话超时结束,默认时间是30分钟;
3.手动调用 session.invalidate() 销毁session对象;
4.服务器非正常关闭销毁对象(关机 死机 蓝屏等)

正常关闭服务器将session保存到本地:
在这里插入图片描述
正常关闭session没有销毁 而是保存到本地 , 再次启动服务器时会加载本地文件到内存中。

3.2.3 HttpSession原理

HttpSession是利用了Cookie实现的,其本质是一个特殊的Cookie。

Cookie名称是固定的:JSESSIONID ,Cookie的值就是HttpSession的唯一标识。

在这里插入图片描述

3.2.4 cookie和session的区别

  • cookie : 存入浏览器 cookie的值存储是有限制 不安全
  • session: 存入服务器 session存储没有限制 相对安全

如果cookie被清除了,session还在,只不过无法直接找到session, 可以通过url重写地址栏可以找回来的。

如果浏览器禁用cookie,session还可以使用,session的底层基于cookie 但不完全依赖cookie 有其他的方式可以替代。

session是一个域对象 , 为什么cookie不是域对象?因为域对象指的是服务器端的技术,而cookie是浏览器端的技术。

3.2.5 持久化级别session

通过创建cookie,可以持久化保存session

 //创建session对象
HttpSession session = request.getSession();

 //自己创建cookie
Cookie cookie = new Cookie("JSESSIONID" , session.getId());
        
cookie.setMaxAge(60*60*7);
response.addCookie(cookie);

System.out.println("session地址值:" + session);
System.out.println("session的id为:" + session.getId());
System.out.println("session是否为新创建的:" + session.isNew());

3.2.6 session的使用细节

session的活化与钝化:

  • 钝化:当应用停止服务时,服务器会把Session域中内容序列化到磁盘上
  • 当应用再次启动时,服务器会把磁盘上的.ser文件内容加载回内存中

前提:

  1. 正常关闭
  2. 存入的是对象必须实现序列化接口

客户端禁用Cookie的会话保持:
3. 文字提示,请不要禁用您的Cookie
4. URL重写,在访问地址后面拼接一个JSESSIONID(不推荐使用)

  • encodeUrl(url):其他的连接使用此方法
  • endcodeRedirectUrl(url):重定向的连接就使用此方法
 //获取session
HttpSession session = request.getSession();

session.setAttribute("username","url重写");

String url=request.getContextPath();
System.out.println(response.encodeRedirectURL(url));

response.setContentType("text/html;charset=utf-8");
response.getWriter().print("<a href='"+url+"'>返回首页</a><br>");

String url2 = request.getContextPath()+"/demo2";
url2=response.encodeURL(url2);
System.out.println(url2);
response.getWriter().print("<a href='"+url2+"'>获取数据</a>");


这篇关于JavaWeb之cookie&session的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程