_Người dịch: Nguyễn Trần Nhật Đức lớp Spring Boot 1A+1B

Nguồn: https://zetcode.com/spring/cookies/_

Bài viết này sẽ cho thấy cách làm việc với cookies trên một ứng dụng Spring. Cookies được đọc (read) với annotation @CookieValue

Spring là một khung ứng dụng Java phổ biến để tạo các ứng dụng doanh nghiệp.

Cookies

Cookie là một phần dữ liệu mà máy chủ gửi đến trình duyệt web của người dùng. Trình duyệt sẽ lưu trữ dữ liệu đó và gửi trở lại request đến cùng một máy chủ vào lần truy cập tiếp theo.

Cookie chủ yếu được sử dụng để quản lý theo phiên, cá nhân hóa và theo dõi.

@CookieValue

@CookieValue là một annotation cho biết rằng một tham số phương thức phải được liên kết với một cookie HTTP.

HttpCookie

HttpCookie đại diện cho một cookie HTTP dưới dạng một cặp name-value nhất quán với nội dung của header request* "Cookie". Class ResponseCookie con có các thuộc tính bổ sung được lưu trong header response* "Set-Cookie".

*: Tìm hiểu về header request, header response tại đây

Ví dụ về Spring Cookies

Ví dụ sau đây tạo một ứng dụng web Spring đọc và ghi một cookie.

pom.xml
src
├───main
│   ├───java
│   │   └───com
│   │       └───zetcode
│   │           ├───config
│   │           │       MyWebInitializer.java
│   │           │       WebConfig.java
│   │           └───controller
│   │                   MyController.java
│   └───resources
│           logback.xml
└───test
    └───java```

Đây là một cấu trúc dự án của ứng dụng Spring

_pom.xml_

```java
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
            http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zetcode</groupId>
    <artifactId>cookiesex</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
        <spring-version>5.1.3.RELEASE</spring-version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>4.0.1</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.1.3.RELEASE</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.2.2</version>
            </plugin>

            <plugin>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>9.4.14.v20181114</version>
            </plugin>

        </plugins>
    </build>
</project>```

Chúng ta khai báo các dependency của dự án

_resources/logback.xml_

```java
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <logger name="org.springframework" level="ERROR"/>
    <logger name="com.zetcode" level="INFO"/>

    <appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <Pattern>%d{HH:mm:ss.SSS} %blue(%-5level) %magenta(%logger{36}) - %msg %n
            </Pattern>
        </encoder>
    </appender>

    <root>
        <level value="INFO" />
        <appender-ref ref="consoleAppender" />
    </root>

File logback.xml là một file cấu hình (configuration) cho thư viện logging Logback.

com/zetcode/config/MyWebInitializer.java

package com.zetcode.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

@Configuration
public class MyWebInitializer extends
        AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return null;
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {

        return new Class[]{WebConfig.class};
    }

    @Override
    protected String[] getServletMappings() {

        return new String[]{"/"};
    }
}

DispatcherServlet, là một front controller cho ứng dụng web Spring, đã được đăng ký MyWebInitializer.

@Override
protected Class<?>[] getServletConfigClasses() {

    return new Class[]{WebConfig.class};
}

getServletConfigClasses() trả về một class cấu hình web

com/zetcode/config/WebConfig.java

package com.zetcode.config;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"com.zetcode"})
public class WebConfig {

}

WebConfig kích hoạt các annotation Spring MVC với @EnableWebMvc và cấu hình scan component cho package com.zetcode.

com/zetcode/MyController.java

package com.zetcode.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseCookie;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class MyController {

    private static final Logger logger = LoggerFactory.getLogger(MyController.class);

    @ResponseStatus(value = HttpStatus.OK)
    @GetMapping(value = "/readCookie")
    public void readCookie(@CookieValue(value = "fav-col",
            defaultValue = "unknown") String favColour) {

        logger.info("Favourite colour: {}", favColour);
    }

    @ResponseStatus(value = HttpStatus.OK)
    @GetMapping(value = "/writeCookie")
    public ResponseEntity writeCookie() {

        var favColour = "steelblue";
        var cookie = ResponseCookie.from("fav-col", favColour).build();

        return ResponseEntity.ok()
                .header(HttpHeaders.SET_COOKIE, cookie.toString())
                .build();
    }
}

Chúng ta có 2 phương thức GET mapping. Cái thứ nhất là để đọc một cookie và cái thứ hai để ghi một cookie.

public void readCookie(@CookieValue(value = "fav-col",
        defaultValue = "unknown") String favColour) {

Chúng ta đọc một cookie value với annotation @CookieValue. Có một giá trị mặc định (default) nếu như cookie chưa được đặt (set) hay đã hết hạn.

var favColour = "steelblue";
var cookie = ResponseCookie.from("fav-col", favColour).build();

return ResponseEntity.ok()
        .header(HttpHeaders.SET_COOKIE, cookie.toString())
        .build();

Chúng ta tạo một cookie với ResponseCookie và set nó thành header response.

java $ mvn jetty:run

Chúng ta khởi chạy server Jetty. Bây giờ, trước tiên hãy tìm trình duyệt đến localhost:8080/writeCookie và sau đó đọc cookie bằng cách điều hướng đến localhost:8080/readCookie.

Trong bài này chúng ta đã làm việc với cookie trong Spring