【JavaWeb】Cookie

What are cookies for?

Thinking Question 1 - Throwing bricks to attract jade

When you visit a certain website, can you see the time when you last logged in to the website, and what you should pay attention to is that the
last login time of different users must be different. How is this achieved?

image-20221218200759797

Thinking Question 2 - Throwing Bricks to Induce Jade

When you visit a shopping website, can you see the products you have browsed before? The products browsed by different users must be different. How is this achieved?

The solution - cookie technology

Cookie (small cookie) is a client-side technology, and the server writes each user's data to the user's respective browser in the form of a cookie. When users use a browser to access web resources in the server, they will bring their own data. In this way, the web resource handles the user's own data. 【Simple diagram】

image-20221218201836766

image-20221218201900683

image-20221218202141883

cookie introduction

Two said cookie

  1. Cookie is the server saving the user's information on the client side, such as login name, browsing history, etc., which can be saved in the form of cookie.
  2. Cookie information is like a cookie (cookie), the amount of data is not large, and the server can read it from the client browser when needed, which can be understood through the diagram.

image-20221218202705919

image-20221218202754090

What can cookies be used for?

  1. Save information such as last login time
  2. Save user name, password, no need to log in again for a certain period of time
  3. Personalization of the website, such as customizing the services and content of the website.

Cookies are saved in the local browser! ! !

Basic use of cookies

Documentation

https://docs.oracle.com/javaee/7/api/

image-20221218204243983

Common methods of cookies

  1. A cookie is a bit like a table (KV), divided into two columns, one is the name, the other is the value, and the data type is String, as shown in the figure
    image-20221218204501185

  2. How to create a cookie (created on the server side)

Cookie c = new Cookie(String name,String val); 
c.setMaxAge();//保存时间
  1. How to add a cookie to the client
response.addCookie(c);
  1. How to read cookies (read cookie information on the server side)
request.getCookies();

The underlying implementation mechanism of cookies - creating and reading cookies

Server-side creation of cookies

package com.hspedu.cookie;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @ClassName CreateCookie
 * @Description TODO
 * @Author zephyr
 * @Date 2022/12/18 22:37
 * @Version 1.0
 */

@WebServlet(name = "CreateCookie", value = "/createCookie")
public class CreateCookie extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
        System.out.println("==========CreateCookie被调用==========");
        //1. 创建一个Cookie对象
        /**
         * 1) username 该cookie的名字,唯一的,可以理解成key
         * 2) zephyr 该cookie的值
         * 3) 可以创建多个cookie对象
         * 4) 这是这个cookie在服务器端,还没有到浏览器
         */
        Cookie cookie = new Cookie("username", "zephyr");

        response.setContentType("text/html;charset=utf-8");

        //2. 将cookie发送给浏览器,让浏览器将该cookie保存起来
        response.addCookie(cookie);
        PrintWriter writer = response.getWriter();
        writer.println("<h1>创建cookie成功!<h1>");
        writer.flush();
        writer.close();
    }

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

image-20221218224843369

image-20221218224847269

Server-side read cookie

package com.hspedu.cookie;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

/**
 * @ClassName ReadCookies
 * @Description 演示:读取从客户端发送来的cookie信息
 * @Author zephyr
 * @Date 2022/12/19 10:47
 * @Version 1.0
 */

@WebServlet(name = "ReadCookies", value = "/readCookies")
public class ReadCookies extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
        System.out.println("==========CreateCookie被调用==========");

        //1. 通过Request对象读取所有Cookie信息
        Cookie[] cookies = request.getCookies();
        //2. 遍历Cookie
        if (cookies != null && cookies.length > 0){
    
    
            for (Cookie cookie : cookies) {
    
    
                System.out.println(cookie.getName() + " = " + cookie.getValue());
            }
        }
        //Cookie: JSESSIONID=BA235330CCE65FE095ED5EFB37B3A113; username=zephyr
        //3. 给浏览器返回信息
        response.setContentType("text/html;charset=utf-8");
        response.getWriter().println("<h1>读取cookie信息成功<h1>");

    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
        doPost(request, response);
    }
}

image-20221219112132718

image-20221219112242221

What is the use of JSESSIONID?

session means session.

JSESSIONID is the unique identifier of the session.

Cookie application example

Read the specified cookie

Traverse through a tool class to find the specified cookie.

CookieUtils.java

package com.hspedu.cookie;

import javax.servlet.http.Cookie;

/**
 * @ClassName CookieUtils
 * @Description 对Cookie数组进行过滤
 * @Author zephyr
 * @Date 2022/12/19 11:40
 * @Version 1.0
 */
public class CookieUtils {
    
    
    public static Cookie readCookieByName(String cookieName, Cookie[] cookies) {
    
    
        //如果传输参数不正确就返回null
        if (cookieName == null || "".equals(cookieName) || cookies == null || cookies.length == 0) {
    
    
            return null;
        }
        for (Cookie cookie : cookies
        ) {
    
    
            if (cookieName.equals(cookie.getName())) {
    
    
                return cookie;
            }
        }
        //没找到就返回null
        return null;
    }
}

modify cookies

Requirement: Given a specified cookie, find the cookie, if found, modify the value to jyl-hi; if not found, prompt that the cookie cannot be found.

UpdateCookie.java

package com.hspedu.cookie;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;

/**
 * @ClassName UpdateCookie
 * @Description TODO
 * @Author zephyr
 * @Date 2022/12/19 11:59
 * @Version 1.0
 */

@WebServlet(name = "UpdateCookie", value = "/updateCookie")
public class UpdateCookie extends HttpServlet {
    
    
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
        System.out.println("==========UpdateCookie被调用==========");

        //1. 根据name,查找cookie
        String cookieName = "email";
        Cookie[] cookies = request.getCookies();
        Cookie cookie = CookieUtils.readCookieByName(cookieName, cookies);
        if (cookie == null){
    
    
            System.out.println("当前访问服务器的客户端没有该cookie");
        } else {
    
    
            cookie.setValue("jyl-hi");
            //2. 遍历cookie查看值
            for (Cookie cookie_ : cookies) {
    
    
                System.out.println(cookie_.getName() + " = " + cookie_.getValue());
            }
            //3. cookie返回给浏览器
            response.addCookie(cookie);
        }

    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
        doPost(request, response);
    }
}

After resetting the value of the cookie through setValue, be sure to response.addCookie(cookie)return the cookie!
If the newly created cookie has the same name as the browser's existing cookie, it will be overwritten.

Cookie life cycle

introduce

  1. The life cycle of cookies refers to how to manage when cookies are destroyed (deleted)
  2. setMaxAge()
    1. Positive number, indicating to expire after the specified number of seconds
    2. A negative number means that the cookie will be deleted when the browser is closed (the default value is -1)
    3. 0, means delete the cookie immediately

Applications

Demonstrate the life cycle of cookies

System.out.println("==========CookieLive被调用==========");

//演示创建一个cookie,生命周期为60s
Cookie cookie = new Cookie("job", "java");
//1. 从创建该cookie开始计时,60s后就无效了
//2. 浏览器根据创建时间,计时到60s就认为该cookie无效
//3. 如果该cookie无效,那么浏览器在发出http请求时,就不在携带该cookie
cookie.setMaxAge(60);

response.addCookie(cookie);

image-20221219125200350

Visit CookieLive, return Set-Cookie: job=java; Max-Age=20; Expires=Mon, 19-Dec-2022 04:51:49 GMT. Tells the browser to invalidate (do not carry) this cookie after 60 seconds.

image-20221219124749931

After 60 seconds, the browser sends an http request to the server without the job cookie.


Demo deletes a cookie

System.out.println("==========CookieLive被调用==========");
        //演示删除一个cookie:username
        //1. 先得到这个cookie
        Cookie usernameCookie = CookieUtils.readCookieByName("username", request.getCookies());
        //2. 将其的生命周期设置为0
        usernameCookie.setMaxAge(0);
        //3. 通知浏览器
        response.addCookie(usernameCookie);

Capture packets on the browser side and you can see in the response header: Set-Cookie: username=zephyr; Max-Age=0; Expires=Thu, 01-Jan-1970 00:00:10 GMT.

image-20221219130136261

Then you can see that the cookie in the browser has been deleted.

image-20221219130336578

What happens if you don't set the lifecycle

However, if the life cycle is not set, the default setMaxAge(-1)is a session-level life cycle, which means that the cookie will be deleted when the browser is closed.

image-20221219131005538

effective cookie path

  1. Cookie effective path Path setting
  2. The path attribute of Cookie can effectively filter which Cookies can be sent to the server. Which ones are not posted. The path attribute is effectively filtered by the requested address

image-20221219131349399

image-20221219131409832

  1. The rules are as follows

image-20221219131709379

Applications

System.out.println("==========CookiePath被调用==========");

//1. 创建2个cookie
Cookie bandCookie = new Cookie("band", "Gelneryus");
Cookie instrumentCookie = new Cookie("instrument", "Guitar");
//2. 设置不同的有效路径
bandCookie.setPath(request.getContextPath()); // ContextPath = /cs
// instrumentCookie的有效路径是 /cs/ins
instrumentCookie.setPath(request.getContextPath() + "/ins");
//3. 保存到浏览器
response.addCookie(bandCookie);
response.addCookie(instrumentCookie);
//4. 给浏览器返回信息
response.setContentType("text/html;charset=utf-8");
response.getWriter().println("<h1>设置cookie路径成功<h1>");

image-20221219132859263

image-20221219133055612

image-20221219133249790

Homework: Automatically fill in the login account

  1. If the user name is hspedu and the password is 123456, the user is considered legal and the login is successful, otherwise the login is invalid
  2. It is required to realize that if the login is successful, the user, who logs in within 3 days, can automatically fill in his login name
  3. The login page needs to be returned using a servlet, not html

Login login page (written as Servlet)

package com.hspedu.cookie;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @ClassName Login
 * @Description TODO
 * @Author zephyr
 * @Date 2022/12/19 16:05
 * @Version 1.0
 */

@WebServlet(name = "Login", value = "/login")
public class Login extends HttpServlet {
    
    
    HttpServletRequest request = null;
    HttpServletResponse response = null;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
        System.out.println("==========Login被调用==========");

        this.request = request;
        this.response = response;

        //先读取cookie,看看cookie里有没有username和pwd
        Cookie[] cookies = request.getCookies();
        Cookie usernameCookieRead = CookieUtils.readCookieByName("username", cookies);
        Cookie pwdCookieRead = CookieUtils.readCookieByName("pwd", cookies);
        if (usernameCookieRead != null && pwdCookieRead != null) {
    
    //cookie存在
            showLoginHtml(usernameCookieRead.getValue(), pwdCookieRead.getValue());
        } else {
    
    
            showLoginHtml("", "");
        }

    }

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


    public void showLoginHtml(String username, String pwd) throws ServletException, IOException{
    
    
        String content = "<!DOCTYPE html>\n" +
                "<html lang=\"en\">\n" +
                "<head>\n" +
                "  <base href=\"/cs/\">\n" +
                "    <meta charset=\"UTF-8\">\n" +
                "    <title>登录界面</title>\n" +
                "</head>\n" +
                "<body>\n" +
                "<h1>用户登录界面</h1>\n" +
                "<form action=\"loginServlet\" method=\"get\">\n" +
                "  用户名:<input type=\"text\" name=\"username\" value=\""+username+"\"><br>\n" +
                "  密码:<input type=\"text\" name=\"pwd\" value=\""+pwd+"\"><br>\n" +
                "  <input type=\"submit\" value=\"登录\">\n" +
                "</form>\n" +
                "\n" +
                "</body>\n" +
                "</html>";
        if (request != null && response != null){
    
    
            response.setContentType("text/html;charset=utf-8");
            PrintWriter writer = response.getWriter();
            writer.println(content);
            writer.flush();
            writer.close();
        }
    }
}

LoginServlet

package com.hspedu.cookie;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * @ClassName LoginServlet
 * @Description TODO
 * @Author zephyr
 * @Date 2022/12/19 15:13
 * @Version 1.0
 */

@WebServlet(name = "LoginServlet", value = "/loginServlet")
public class LoginServlet extends HttpServlet {
    
    
    String correctUserName = "jingyl";
    String correctPwd = "123456";
    HttpServletRequest request = null;
    HttpServletResponse response = null;

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
        System.out.println("==========LoginServlet被调用==========");

        this.request = request;
        this.response = response;

        if (checkForm()){
    
    
            showSuccess();
        } else {
    
    
            showFail();
        }
    }

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

    /**
     * 返回登陆成功的信息
     */
    public void showSuccess() throws ServletException, IOException {
    
    
        //通知浏览器已经写入cookie
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.println("<h1>登录成功!<h1>");
    }

    /**
     * 返回登陆失败的信息
     */
    public void showFail() throws ServletException, IOException {
    
    
        //通知浏览器已经写入cookie
        response.setContentType("text/html;charset=utf-8");
        PrintWriter writer = response.getWriter();
        writer.println("<h1>登录失败!<h1>");
    }

    public boolean checkForm() throws ServletException, IOException {
    
    
        //读取表单里的username和pwd
        String username = request.getParameter("username");
        String pwd = request.getParameter("pwd");
        if (username.equals(correctUserName) && pwd.equals(correctPwd)) {
    
    //如果账号密码正确则保存在浏览器的cookie
            //创建cookie保存用户名和密码
            Cookie usernameCookie = new Cookie("username", username);
            Cookie pwdCookie = new Cookie("pwd", pwd);

            //生命周期为3天
            usernameCookie.setMaxAge(60 * 60 * 24 * 3);
            pwdCookie.setMaxAge(60 * 60 * 24 * 3);

            response.addCookie(usernameCookie);
            response.addCookie(pwdCookie);
            return true;
        } else {
    
    
            return false;
        }
    }



}

Cookie considerations and details

  1. A cookie can only identify one kind of information, and it contains at least a name (NAME) and setting value
    (VALUE) to identify the information.
  2. A WEB site can send multiple cookies to a browser, and a browser can also store cookies provided by multiple WEB sites.
  3. There is no limit to the total number of cookies, but there is a limit to the number of cookies for each domain name and the size of each cookie (different browsers have different restrictions, just know it), and cookies are not suitable for storing information with a large amount of data.
  4. Note that when deleting cookies, the paths must be consistent, otherwise they will not be deleted
  5. Solve the Chinese garbled characters of cookies in Java servlet [code demo EncoderCookie.java ReadCookie2.java]

It is not recommended to store Chinese cookie information, which may be garbled, which can be solved by url encoding and decoding.

Solve the Chinese cookie garbled problem

If you save the Chinese Cookie directly, an error will be reported

image-20221219163432769

image-20221219163508477

  • URLEncoder.encode()Chinese can be encoded by
System.out.println("==========EncoderCookie被调用==========");

//1. 如果直接错放中文的cookie会报错
//2. 通过将中文编码成 URL 编码
String company = URLEncoder.encode("景风眠教育", "utf-8");
Cookie cookie = new Cookie("company", company);

response.addCookie(cookie);

response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.println("<h1>EncoderCookie被成功调用[中文乱码测试]<h1>");
writer.flush();
writer.close();

image-20221219163842135

  • URLDecoder.decode()decoded by
System.out.println("==========EncoderCookie被调用==========");

Cookie[] cookies = request.getCookies();

Cookie cookie = CookieUtils.readCookieByName("company", cookies);
System.out.println(cookie.getName() + " = " + cookie.getValue());
System.out.println("===========解码后===========");
String decode = URLDecoder.decode(cookie.getValue());
System.out.println(cookie.getName() + " = " + decode);

response.setContentType("text/html;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.println("<h1>DecoderCookie被成功调用[中文解码测试]<h1>");
writer.flush();
writer.close();

image-20221219164433308

Guess you like

Origin blog.csdn.net/weixin_46421722/article/details/129463900