深度好文之Servlet技术详解(七)Cookie对象

目录

一.介绍

 二.Cookie对象的特点 

三.Cookie对象的创建

四.获取Cookie中的数据

 五.解决Cookie不支持中文

 六.Cookie跨域问题

 七.状态Cookie与持久化Cookie

八.通过Cookie实现客户端与服务端会话的维持


一.介绍

Cookie 对象与 HttpSession 对象的作用是维护客户端浏览器与服务端的会话状态的两个对象。由于 HTTP 协议是一个无状态的协议,所 以服务端并不会记录当前客户端浏览器的访问状态,但是在有些时 候我们是需要服务端能够记录客户端浏览器的访问状态的,如获取 当前客户端浏览器的访问服务端的次数时就需要会话状态的维持。
Servlet 中提供了 Cookie 对象与 HttpSession 对象用于维护客户端 与服务端的会话状态的维持。二者不同的是 Cookie 是通过客户端浏 览器实现会话的维持,而 HttpSession 是通过服务端来实现会话状态 的维持。

 二.Cookie对象的特点 

  • Cookie使用字符串存储数据
  • Cookie使用KeyValue结构存储数据
  • 单个Cookie存储数据大小限制在4097个字节
  • Cookie存储的数据中Servlet4.0之前不支持中文,Servlet4.0中支持
  • Cookie是与域名绑定所以不支持跨一级域名访问
  • Cookie对象保存在客户端浏览器内存或系统磁盘中
  • Cookie分为持久化Cooke(放在系统磁盘中)与状态Cookie (放在客户端浏览器内存)
  • 浏览器在保存同一域名所返回Cookie的数量是有限的。不同浏览器支持的数量不同,Chrome浏览器为50
  • 浏览器每次请求时都会把与当前访问的域名相关的所有Cookie在请求中提交到服务端。

三.Cookie对象的创建

注意Cookie是服务器端创建并返回给用户的。

Cookie cookie = new Cookie("key","value")
通过 new 关键字创建 Cookie 对象
response.addCookie(cookie)
通过 HttpServletResponse 对象将 Cookie 写回给客户端浏览器。
CreateCookieServlet.java:
package com.first.servlet;

import javax.servlet.ServletException;
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;

public class CreateCookieServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //创建Cookie对象
        Cookie cookie=new Cookie("key","流连忘返");
        //将Cookie写回给客户端浏览器
        resp.addCookie(cookie);

        PrintWriter pw=resp.getWriter();
        pw.println("create cookie ok");
        pw.flush();
        pw.close();
    }
}
配置web.xml:
    <servlet>
        <servlet-name>CreateCookieServlet</servlet-name>
        <servlet-class>com.first.servlet.CreateCookieServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>CreateCookieServlet</servlet-name>
        <url-pattern>/cookie.do</url-pattern>
    </servlet-mapping>

输出:

先按F12,再访问此servlet

点击Application-->Cookie

四.获取Cookie中的数据

浏览器每次请求时都会把与当前访问的域名相关的 Cookie 在请求中提交到服务端。通过 HttpServletRequest 对象获取 Cookie ,返回 Cookie 数组。
Cookie[] cookies = request.getCookies();

上节运行的浏览器不要关(服务器也别关,因为实际生活中服务器就是一直运行),因为我们现在使用的是状态cookie(会保存到当前浏览器中),浏览器一关cookie就被清空了。

 GetCookieDataServlet.java:

package com.first.servlet;

import javax.servlet.ServletException;
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;

public class GetCookieDataServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //从客户端获取Cookie对象
        Cookie[] cookies=req.getCookies();

        //获取Cookie中的数据
        PrintWriter pw=resp.getWriter();
        for (int i=0;i<cookies.length;i++){
            Cookie cookie=cookies[i];
            String name=cookie.getName();
            String value=cookie.getValue();
            pw.println("Name: "+name+" Value: "+value);
        }
        pw.flush();
        pw.close();
    }
}
配置web.xml:
    <servlet>
        <servlet-name>GetCookieDataServlet</servlet-name>
        <servlet-class>com.first.servlet.GetCookieDataServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>GetCookieDataServlet</servlet-name>
        <url-pattern>/getCookie.do</url-pattern>
    </servlet-mapping>

输出:

 五.解决Cookie不支持中文

Cookie name 的值不能使用中文, Value 是可以的。但是在Servlet4.0 版本之前 Cookie 中的 Value 也是不支持中文存储的,如果 存储的数据中含有中文,代码会直接出现异常。我们可以通过对含 有中文的数据重新进行编码来解决该问题。在 Servlet4.0 中的 Cookie Value 开始支持中文存储。

报的异常:

java.lang.IllegalArgumentException: Control character in cookie value or attribute.

还是建议做如下处理,因为这样普适性较高,不用担心版本问题。

URLEncoder.encode("content","code")
将内容按照指定的编码方式做 URL 编码处理。
URLDecoder.decode("content","code")
将内容按照指定的编码方式做 URL 解码处理。

上面的两个例子稍加修改:

CreateCookieServlet.java:
//创建Cookie对象
Cookie cookie=new Cookie(URLEncoder.encode("回头看","utf-8"),
                URLEncoder.encode("流连忘返","utf-8"));
GetCookieDataServlet.java:
pw.println("Name: "+ URLDecoder.decode(name,"utf-8")
                    +" Value: "+URLDecoder.decode(value,"utf-8"));

输出:

 六.Cookie跨域问题

域名分类:域名分为顶级域、顶级域名(一级域名)、二级域名。

域名等级的区别:一级域名比二级域名更高级,二级域名是依附于一级域名之下的附属分区域名,即二级域名是一级域名的细化分 级。例如: baidu.com 为一级域名, news.baidu.com 为二级域 名。

Cookie不支持一级域名的跨域,支持二级域名的跨域。一级域名(即顶级域名)需要申请,二级域名不需要申请,二级域名自己扩展即可。

 七.状态Cookie与持久化Cookie

状态 Cookie Cookie 对象仅会被缓存在浏览器所在的内存中。当浏览器关闭后 Cookie 对象 也会被销毁。
持久化 Cookie :浏览器会对 Cookie 做持久化处理,基于文件形式保存在系统的指定目录中。在 Windows10 系统中为了安全问题不会显 Cookie 中的内容。
Cookie 对象创建后默认为状态 Cookie 。可以使用 Cookie 对象下的cookie.setMaxAge(60) 方法设置失效时间,单位为秒。一旦设置了 失效时间,那么该 Cookie 为持久化 Cookie ,浏览器会将 Cookie 对象 持久化到磁盘中。当失效时间到达后文件删除。
        //创建Cookie对象
        Cookie cookie=new Cookie(URLEncoder.encode("回头看","utf-8"),
                URLEncoder.encode("流连忘返","utf-8"));
        //变为持久化cookie,生存时间是120s,在生存时间内关闭浏览器没问题
        cookie.setMaxAge(120);

八.通过Cookie实现客户端与服务端会话的维持

需求:当客户端浏览器第一次访问 Servlet 时响应 您好,欢迎您第一次访问! ,第二次访问时响应 欢迎您回来!
WelcomeServlet.java:
package com.first.servlet;

import javax.servlet.ServletException;
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;

public class WelcomeServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //获取Cookie
        Cookie[] cookies=req.getCookies();
        //有无标志访问的Cookie
        boolean flag=false;
        if (cookies!=null){
            for (Cookie cookie:cookies){
                if ("welcome".equals(cookie.getName())){
                    //不是第一次访问
                    flag=true;
                    break;
                }
            }
        }
        resp.setContentType("text/plain;charset=utf-8");
        PrintWriter pw=resp.getWriter();
        if (flag){
            pw.println("欢迎您回来!");
        }else {
            pw.println("您好,欢迎您第一次访问!");
            Cookie cookie=new Cookie("welcome","welcome");
            cookie.setMaxAge(60);
            //把这个cookie响应给用户
            resp.addCookie(cookie);
        }
    }
}
web.xml配置:
    <servlet>
        <servlet-name>WelcomeServlet</servlet-name>
        <servlet-class>com.first.servlet.WelcomeServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>WelcomeServlet</servlet-name>
        <url-pattern>/welcome.do</url-pattern>
    </servlet-mapping>
输出:

刷新一下

Cookie 总结
Cookie 对于存储内容是基于明文的方式存储的,所以安全性很低。 win10做了改进,不再让用户直接看到明文。
不要在 Cookie 中存放敏感数据。在数据存储时,虽然在 Servlet4.0 Cookie 支持中文,但是建议对 Cookie 中存放的内容做编码处理, 也可提高安全性。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Servlet中,可以使用表单、Cookie和Session内置对象来传递数据。 1. 使用表单传递数据:可以在HTML页面中创建一个表单,用户输入数据后,将数据通过POST或GET方法提交给Servlet。在Servlet中,可以通过HttpServletRequest对象的getParameter()方法获取表单中的数据。 示例代码: ```java // HTML页面 <form action="MyServlet" method="post"> <input type="text" name="username"> <input type="submit" value="Submit"> </form> // Servlet protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); // 处理数据 } ``` 2. 使用Cookie传递数据:Cookie是一种在客户端存储数据的机制。在Servlet中,可以使用Cookie类的构造函数创建一个Cookie对象,并通过HttpServletResponse对象addCookie()方法将Cookie发送给客户端。在下一个Servlet中,可以通过HttpServletRequest对象的getCookies()方法获取客户端发送的Cookie。 示例代码: ```java // Servlet1 Cookie cookie = new Cookie("username", "John"); response.addCookie(cookie); response.sendRedirect("Servlet2"); // Servlet2 Cookie[] cookies = request.getCookies(); if (cookies != null) { for (Cookie cookie : cookies) { if (cookie.getName().equals("username")) { String username = cookie.getValue(); // 处理数据 } } } ``` 3. 使用Session传递数据:Session是一种在服务器端存储数据的机制。在Servlet中,可以通过HttpServletRequest对象的getSession()方法获取Session对象,并使用Session对象的setAttribute()方法设置数据。在下一个Servlet中,可以通过HttpServletRequest对象的getSession()方法获取相同的Session对象,并使用getAttribute()方法获取数据。 示例代码: ```java // Servlet1 HttpSession session = request.getSession(); session.setAttribute("username", "John"); response.sendRedirect("Servlet2"); // Servlet2 HttpSession session = request.getSession(); String username = (String) session.getAttribute("username"); // 处理数据 ``` 通过以上方法,你可以在不同的Servlet之间传递数据。但需要注意的是,使用Cookie和Session传递数据时,数据会暴露在客户端或服务器端,因此需要谨慎处理敏感信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深海鱼肝油ya

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值