【Eclipse】SpringBootでcookieを操作する

# はじめに
この記事ではcookieの操作について学習結果をまとめています。保存、取得、削除、それぞれをSpringBootで実行する方法についてコントローラーの扱い方などについて参考になれば幸いです

cookieは何かについては次の参考記事にまとめています

https://qiita.com/EasyCoder/items/8ce7dfd75d05079be9d7

## cookieの操作コードはcontrollerクラスに記述する
Spring Bootでは、Cookieの操作はControllerクラスで行うことが多いですが、それが唯一の方法ではありません。場合によってはServiceクラスやUtilityクラスなど他の部分で行うこともあります。ただし、一般的にはHTTPリクエストとレスポンスに直接関与する作業はControllerに記述します。

## コントローラーの作成場所
Spring Bootプロジェクトにおいて、Controllerクラスを作成するための特定のディレクトリは明確には決まっていませんが、慣習的には`src/main/javaディレクトリ`の下にある、パッケージ構造に従った適切な場所に作成します。

たとえば、もしアプリケーションの基本パッケージが`com.example.myapp`であれば、一般的にはControllerクラスは`com.example.myapp.controllerパッケージ内`に作成します。

### パッケージ名について
パッケージ名（特に基本パッケージ名）は通常、組織の規約に基づいて決定されます。一般的には、組織のインターネットドメイン名を逆にしたものが使われます。パッケージ名はEclipseのプロジェクトの作成ウィザードですでに設定されています。組織のウェブサイトがwww.example.comであれば、com.exampleという基本パッケージ名が使われます。学習段階でパッケージの名称に迷う場合は画像のパッケージ名を参考にパッケージを作成し学習を進めてください。

## cookie用のコントローラーを作成する

![スクリーンショット 2023-06-27 15.17.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2765288/77bf9d59-6bde-ac0d-3c85-8e22759ee1ec.png)
![スクリーンショット 2023-06-27 15.19.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2765288/e241fe61-3f17-e2c4-195b-b364b4a243b2.png)

## Get通信（Getパラメータ）をcookieに保存する

Get通信はURLにパラメータを含ませて送信する方法です
次の例文ではGet通信で送られたパラメータをcookieに保存することができます

本来cookieの保存はPostメソッドで実行されますが、
解説のためにGet通信の場合をご参照ください

```java:CookieController.java
package com.example.controller;

// 必要なインポートは上書き保存で補完されます
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/cookie") 
public class CookieController {
    
    @GetMapping("/set")　　
    @ResponseBody // htmlではなく直接ブラウザに文字を出力します
    public String setCookie(@RequestParam String value, HttpServletResponse res) {
        // cookie名をtest_cookieとして保存します
        res.addCookie(new Cookie("test_cookie", value));
        return "保存しました";
    }
}
```
次のURLでリクエストを送信することで`test`というパラメータが保存されます
Getメソッドのパラメータは`?`以降に設定されます

http://localhost:8080/cookie/set?value=test


### @RequestParam
getメソッドに設定した`value`の値を取得するアノテーションです
今回は`value=test`だったので`test`という値を引数で渡しています
```java
@RequestParam String value
```

### HttpServletResponse
HttpServletResponseクラスのaddCookieメソッドはリクエストを送信したユーザーのブラウザにcookieの保存を命令します
```java
public String メソッド名(HttpServletResponse res) {
    res.addCookie(Cookieクラスのオブジェクト);
    // 後続処理
}
```

### Cookieクラスのオブジェクト
新しいCookieクラスでcookie情報を生成します。
```java
new Cookie("cookie名", 値)
```
このメソッドは新しいCookieオブジェクトをJavaのメモリ上に作成するだけで、つまり入れ物を作成しただけに止まります。この時点ではまだクライアント（通常はウェブブラウザ）には送信されず、結果クライアントに保存もされません。

この作成されたCookieオブジェクトをクライアントに送信し、クライアントに保存させるためには、このオブジェクトをHTTPレスポンスに追加し、そのレスポンスをクライアントに送信する必要があります。これを行うためには、　`HttpServletResponse`の`addCookieメソッド`を使用します。

## cookieに保存された値を表示させる
```java:CookieController.java
@GetMapping("/get") 
    @ResponseBody
    public String getCookie(@CookieValue("test_cookie") Cookie cookie) {
        // cookieの値を取得します
        return "cookieに保存された値は: " + cookie.getValue();
    }
```
http://localhost:8080/cookie/get

### 値を取得する
`@CookieValue`を付けた`Cookieクラスのオブジェクト`をcookie名を指定して引数に指定することでcookieを取得できます。
例では`Cookieクラスのオブジェクト`を代入している変数をcookieという名称にしていますが、例えば`cookieValue`という名称でも問題ありません
```java
public String メソッド名(@CookieValue("cookie名") Cookie cookie) {
    // 処理
}
```
さらに`getValue()メソッド`を呼び出すことでcookieの値を取得できます。
```java
cookie.getValue();
```
## cookieの有効期限を残り0秒に設定して削除する

cookieは残存期間を秒数で指定することができ、残存期間を0に指定することで、Cookieを削除することができます。

```java:CookieController.java
@GetMapping("/delete")
    @ResponseBody
    public String deleteCookie(@CookieValue("test_cookie") Cookie cookie, HttpServletResponse res) {
        cookie.setMaxAge(0);
        res.addCookie(cookie);
        return "削除しました";
    }
```
http://localhost:8080/cookie/delete

### cookieの有効期限を設定する　

cookieの残存期間を残り0秒に設定することでcookieを削除できますが、`addCookie`で情報を上書きするようにブラウザへ命令しなければ削除されずcookieは残り続けます

```java
public String メソッド名(@CookieValue("cookie名") Cookie cookie) {
    cookie.setMaxAge(0); // 有効期限を残り0秒に設定するための情報を作る
    res.addCookie(cookie); //　新しい有効期限をクライアント（ブラウザ）に送信する
}
```

cookieを削除した後にもう一度cookieの値を出力しようとするとエラーが発生します

![スクリーンショット 2023-06-27 18.36.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2765288/c2a5e208-8478-2768-73d6-9ad242a51d62.png)


## あとがき

ブラウジングをしているとcookieという単語はよく目にしていました。一時データ・・・という言葉は認識はしていましたが、それ以上のことはわかっていませんでした。cookieとはテキストデータのことで前回にブラウジングした時の、例えば買い物カゴだとか、動画の視聴履歴だとか、そういった情報がテキストにメモとして残されているのだなと、今回の操作方法学習で少し理解しました