day15_Cookie和Session

一、 HTTP无状态特点

1.Http协议的特点是无状态:

  • 无法在多个请求之间实现数据共享
  • 在实际开发中,我们需要在请求之间共享数----》比如操作邮箱,需要在不同请求之间共享用户名username等操作

2.解决方案:

  • Cookie,客户端会话跟踪技术
    (数据存储在客户端)
  • Session,服务端会话跟踪技术
    (数据存储在服务器,通过客户端 cookie 的 jsessionid 值(( session 的id ))来获取 session )

二、 Cookie

概述

Cookie,有时也用其复数形式 Cookies,指某些网站为了辨别用户身份、进行 session 跟踪而储存在用户本地终端上的数据(通常经过加密)。定义于 RFC2109 和 2965 中的都已废弃,最新取代的规范是 RFC6265 [1] 。(可以叫做浏览器缓存)

cookie比喻

  • 由服务器将共享数据通过Cookie发送到浏览器,将共享数据保存在浏览器中()
    创建Cookie对象: new Cookie(String name, String value)
    name:共享数据的名称
    value:共享数据的值

  • 将Cookie中封装的数据发送给浏览器()
    使用响应对象中的addCookie(cookie对象)将数据响应给浏览器

  • 浏览器发请求的时候,会自动的将数据发送到服务器,如果我们需要使用对应的数据,那么直接获取即可()
    使用请求对象中的 getCookies()方法获取到浏览器中发送过来的所有的Cookie数据
    通过 Cookie 的name属性获取到指定名称的 Cookie 的value

Cookie的常用方法

  • 1.创建Cookie,共享数据(cookie存储有限制4kb)

Cookie c = new Cookie(String 共享数据名称,String 共享数据值);
response对象.addCookie(c);

值是String类型的,所以在多个数据共享时不方便

  • 2.获取Cookie中的共享数据

Cookie[] cs = req.getCookies();

获取指定名称的Cookie的值

(1)Jsp中如何获取Cookie中的数据:${cookie.cookie的name.cookie对象的value属性}
例子: Cookie 对象${cookie.user.value}
(2)java中如何获取Cookie中的数据:Cookie[] cookies = req.getCookies(); 获取cookie集合后foreach

// 获取浏览器带过来的cookie数据
        String username = null;
        Cookie[] cookies = req.getCookies();
        if(cookies!=null){
            for (Cookie c : cookies) {              
                System.out.println(c.getName());
                // 判断是否是需要的数据
                if("username".equals(c.getName())){
                    
                    // 删除cookie
                    //c.setMaxAge(0);
                    //resp.addCookie(c);
                    // 修改cookie数据
                    //c.setValue(c.getValue()+"MM");
                    // 解决tomcat8以下中文乱码的问题
                    // username = URLDecoder.decode(c.getValue(),"utf-8");
                    username = c.getValue();
                }else{
                    System.out.println("不是需要的数据:" + c.getName());
                }
            }
        }
  • 3.修改Cookie中的共享数据

1.为当前Cookie重新设置一个数据 cookie对象.setValue(“xxxx”);
2.重新创建一个name值相同的Cookie覆盖

一定记得将修改之后的数据发送到浏览器中进行更新
--->response.addCookie(Cookie对象);

  • 4.设置Cookie的存活时间

void setMaxAge(int expiry)
expiry>0:指定存活的时间,10表示能够存活10秒

通常登录用户的信息我们可以使用Cookie来保存一段时间,让后用户在这段时间以后可以不再填 写账号密码等信息

expiry=0:立即删除当前的Cookie
expiry<0:默认值,当前浏览器进程,关闭浏览器,数据销毁

5.删除浏览器中指定的Cookie信息

Cookie对象.setMaxAge(0)
response.addCookie(Cookie对象);

Cookie对中文的支持

Cookie中的name属性和value都不支持中文,如果有中文,抛下面的异常(Tomcat8.5以下会出现HTTP Status 500错误

  • 解决思路:将中文重新编码,转换成另外的一种数据(不是中文)
    核心类:URLEncoder
public class EncoderDemo {
    public static void main(String[] args) throws Exception {
        String name = "小米aaa111";
        name = URLEncoder.encode(name,"utf-8");
        System.out.println(name);//%E5%B0%8F%E7%B1%B3aaa111
        // 编码和解码要一致
        name = URLDecoder.decode(name,"utf-8");
        System.out.println(name);//小米aaa111
    }
}

核心类:URLDecoder

Cookie[] cookies = req.getCookies();
for (Cookie c : cookies) {  
    if("username".equals(c.getName())){
        // 解决tomcat8以下中文乱码的问题
        username = URLDecoder.decode(c.getValue(),"utf-8");
    }
}

Cookie的域范围

一级域名:baidu.com
二级域名:news.baidu.com map.baidu.com
可以使用Cookie实现, 但是每个Cookie都有一个域名,如果访问的是当前域名下的资源,浏览器才会将其发送到服务器

  • 解决方案:将Cookie的域名设值成对应的域名即可c.setDomain(“baidu.com”);

Cookie的路径

如果当前Servlet的资源路径/cookie/login---->那么Cookie的路径就是:/cookie
只有在请求资源路径以/cookie开头的资源的时候才会将当前cookie发送到服务器

  • 如果需要在/session/xxx的资源中获取到上面的Cookie,此时只能将上面的Cookie的路径修改为/或者/session
    c.setPath("/");

三、 Session

Session概述

在计算机中,尤其是在网络应用中,称为“会话控制”。Session 对象存储特定用户会话所需的属性及配置信息。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求来自应用程序的 Web 页时,如果该用户还没有会话,则 Web 服务器将自动创建一个 Session 对象。当会话过期或被放弃后,服务器将终止该会话。

总结:Session:服务端的技术,将共享数据存在服务器中,实现在多次请求中数据的共享

Session比喻

如果比喻做办卡,客户端的cookie拿的是卡号(cookie 的 jsessionid 值 【】)
而用户的信息存储在了超市的服务器上

Session常用方法

  • 1.获取Session对象:
    request对象.getSession();获取Session对象,如果没有,服务器自动创建一个新的Session对象
    request对象.getSession(true);获取Session对象,如果没有,服务器自动创建一个新的Session对象
    request对象.getSession(false);获取Session对象,如果没有,返回null

Web服务器自动创建Session对象HttpSession session = request对象.getSession();

  • 2.添加共享数据:
    session.setAttribute(String name,Object value);
    sesssion.setAttribute(“username”, username);
    此时,从服务器发回来一个session的id,作为后面获取对应具体的共享数据的标识

  • 3.从session对象中获取到具体的共享数据

Object value = session对象.getAttribute(String name); ${共享数据名称}

servlet:

protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 1.设置请求参数编码方式
        req.setCharacterEncoding("utf-8");

        String username = null;
    
        // 获取服务器带过来的cookie数据
        username = (String) req.getSession().getAttribute("USER_IN_SESSION");
        
        
        // 2.调用业务方法来处理请求查询邮件
        System.out.println("content:" + username);
        String content = "这是查询到的邮件内容";
        
        // 3.控制跳转
        req.setAttribute("user", username);
        req.setAttribute("content", content);
        req.getRequestDispatcher("/WEB-INF/view/content.jsp").forward(req, resp);
    }

jsp:


    欢迎:${user}   --         session:${USER_IN_SESSION}
    
${info}
  • 4.修改共享数据
    重新设置一个同名的共享数据,将前面的覆盖掉
        // 修改session值
        HttpSession session = req.getSession();
        session.setAttribute("USER_IN_SESSION", "新的数据");
  • 5.Session共享数据的超时管理

和浏览器长时间不交互,超过指定时间之后,就自动销毁当前session
session是在关闭浏览器的是自动销毁(web.xml可以配置服务器的超时时间)

void setMaxInactiveInterval(int interval)
interval:指定超时时间,默认值30分钟

// 设置session对象的超时时间:10秒
session.setMaxInactiveInterval(10);
  • 6.手动销毁Session对象,在注销功能上使用
    void invalidate()
// 删除session,实现注销
req.getSession().invalidate();
  • 7.Session的URL重写
    浏览器禁用Cookie,浏览器就无法保存服务端发送过来的sessionid(钥匙),请求,服务器拿不到sessionid,就无法获取到共享数据

1.手动在请求url后面拼接jsessionid
http://localhost/session/list;jsessionid=6225FDD3988C3B11BD8320899E9B1D2F
2.自动在请求的URL后面拼接jsessionid
HttpServletResponse:
String encodeURL(String url)

新邮件(4)

新邮件(4)

四、 cookie和seesiond的选用:

如果需要保留用户的信息,而且是需要保留一段时间,这个时候使用cookie
如果只是需要在本次操作中共享数据,使用session

你可能感兴趣的:(day15_Cookie和Session)