【JavaWeb】クッキー

クッキーは何のためにあるのでしょうか?

思考の質問 1 - レンガを投げて翡翠を引き寄せる

特定の Web サイトにアクセスしたときに、その Web サイトに最後にログインした時刻がわかりますが、
ユーザーごとに最終ログイン時刻が異なることに注意する必要があります。これはどのように実現されますか?

画像-20221218200759797

思考の質問 2 - レンガを投げて翡翠を誘導する

ショッピング Web サイトにアクセスしたときに、以前に閲覧した商品が表示されますか? ユーザーごとに閲覧した商品は異なるはずです。これはどのように実現されますか?

解決策 - Cookie テクノロジー

Cookie (小さい Cookie) はクライアント側のテクノロジであり、サーバーは各ユーザーのデータを Cookie の形式でユーザーのそれぞれのブラウザに書き込みます。ユーザーがブラウザを使用してサーバー内の Web リソースにアクセスすると、独自のデータが持ち込まれます。このようにして、Web リソースはユーザー自身のデータを処理します。【簡易図】

画像-20221218201836766

画像-20221218201900683

画像-20221218202141883

クッキーの紹介

二人はクッキーを言った

  1. Cookieとは、ログイン名や閲覧履歴などのユーザーの情報をクライアント側で保存するサーバーであり、Cookieの形式で保存することができます。
  2. Cookie 情報は Cookie (クッキー) のようなもので、データ量は大きくなく、必要なときにサーバーがクライアントのブラウザから読み込むことができます。これは図から理解できます。

画像-20221218202705919

画像-20221218202754090

Cookieは何に使用できますか?

  1. 最終ログイン時刻などの情報を保存する
  2. ユーザー名、パスワードを保存し、一定期間は再ログイン不要
  3. Web サイトのサービスやコンテンツのカスタマイズなど、Web サイトのパーソナライズ。

Cookie はローカル ブラウザに保存されます。

クッキーの基本的な使い方

ドキュメンテーション

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

画像-20221218204243983

クッキーの一般的な方法

  1. 図に示すように、Cookie はテーブル (KV) に似ており、2 つの列に分かれており、1 つは名前、もう 1 つは値で、データ型は文字列です。
    画像-20221218204501185

  2. Cookieの作成方法(サーバー側で作成)

Cookie c = new Cookie(String name,String val); 
c.setMaxAge();//保存时间
  1. クライアントにCookieを追加する方法
response.addCookie(c);
  1. Cookieの読み取り方法(サーバー側のCookie情報を読み取る)
request.getCookies();

Cookie の基礎となる実装メカニズム - Cookie の作成と読み取り

サーバー側での Cookie の作成

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);
    }
}

画像-20221218224843369

画像-20221218224847269

サーバー側の読み取りクッキー

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);
    }
}

画像-20221219112132718

画像-20221219112242221

JSESSIONID の用途は何ですか?

セッションとはセッションという意味です。

JSESSIONID はセッションの一意の識別子です。

Cookieの適用例

指定されたクッキーを読み取ります

ツール クラスを横断して、指定された 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;
    }
}

クッキーを変更する

要件: 指定された Cookie を指定して、Cookie を検索し、見つかった場合は値を jyl-hi に変更し、見つからなかった場合は、Cookie が見つからないことを示すプロンプトを表示します。

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);
    }
}

setValue を使用して Cookie の値をリセットした後は、必ずresponse.addCookie(cookie)Cookie を返してください。
新しく作成された Cookie がブラウザの既存の Cookie と同じ名前である場合、その Cookie は上書きされます。

Cookieのライフサイクル

導入

  1. Cookie のライフサイクルとは、Cookie が破棄 (削除) されるタイミングを管理する方法を指します。
  2. setMaxAge()
    1. 正の数。指定された秒数後に期限切れになることを示します。
    2. 負の数値は、ブラウザを閉じるときに Cookie が削除されることを意味します (デフォルト値は -1)。
    3. 0、Cookie をすぐに削除することを意味します

アプリケーション

Cookie のライフサイクルをデモンストレーションする

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);

画像-20221219125200350

CookieLive にアクセスして、 に戻りますSet-Cookie: job=java; Max-Age=20; Expires=Mon, 19-Dec-2022 04:51:49 GMT60 秒後にこの Cookie を無効にする (保持しない) ようにブラウザに指示します。

画像-20221219124749931

60 秒後、ブラウザはジョブ Cookie なしで http リクエストをサーバーに送信します。


デモでは 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);

ブラウザ側でパケットをキャプチャすると、応答ヘッダーに次の内容が表示されますSet-Cookie: username=zephyr; Max-Age=0; Expires=Thu, 01-Jan-1970 00:00:10 GMT

画像-20221219130136261

すると、ブラウザのCookieが削除されていることがわかります。

画像-20221219130336578

ライフサイクルを設定しないとどうなるか

ただし、ライフ サイクルが設定されていない場合、デフォルトはsetMaxAge(-1)セッション レベルのライフ サイクルです。これは、ブラウザを閉じるときに Cookie が削除されることを意味します。

画像-20221219131005538

有効な Cookie パス

  1. Cookie有効パス パス設定
  2. Cookie の path 属性は、どの Cookie をサーバーに送信できるかを効果的にフィルタリングできます。どれが掲載されていないのか。パス属性は、要求されたアドレスによって効果的にフィルタリングされます。

画像-20221219131349399

画像-20221219131409832

  1. ルールは次のとおりです

画像-20221219131709379

アプリケーション

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>");

画像-20221219132859263

画像-20221219133055612

画像-20221219133249790

宿題: ログインアカウントを自動的に入力します

  1. ユーザー名が hspedu でパスワードが 123456 の場合、ユーザーは正当であるとみなされ、ログインは成功します。それ以外の場合、ログインは無効です。
  2. ログインに成功すると、3 日以内にログインしたユーザーはログイン名を自動的に入力できることを認識する必要があります。
  3. ログイン ページは HTML ではなくサーブレットを使用して返される必要があります

ログイン ログイン ページ (サーブレットとして記述)

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();
        }
    }
}

ログインサーブレット

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 に関する考慮事項と詳細


  1. Cookie は 1 種類の情報のみを識別でき、情報を識別するための名前 (NAME) と設定値 (VALUE) が少なくとも含まれます。
  2. WEB サイトは複数の Cookie をブラウザに送信でき、ブラウザは複数の WEB サイトから提供された Cookie を保存することもできます。
  3. Cookie の総数に制限はありませんが、ドメイン名ごとの Cookie の数と各 Cookie のサイズには制限があり (ブラウザごとに制限が異なりますので、注意してください)、Cookie は大量の情報を保存するのには適していません。データの。
  4. Cookie を削除するときは、パスが一貫している必要があり、そうでない場合は削除されないことに注意してください。
  5. Java サーブレットの Cookie の中国語文字化けを解決する [コードデモ EncoderCookie.java ReadCookie2.java]

中国語の Cookie 情報を保存することはお勧めできません。文字化けする可能性がありますが、URL エンコードとデコードによって解決できます。

中国語のクッキー文字化け問題を解決

中国語の Cookie を直接保存すると、エラーが報告されます

画像-20221219163432769

画像-20221219163508477

  • 中国語は次のようにURLEncoder.encode()エンコードできます
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();

画像-20221219163842135

  • によってURLDecoder.decode()デコードされました
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();

画像-20221219164433308

おすすめ

転載: blog.csdn.net/weixin_46421722/article/details/129463900