ZetCode

Spring cookies tutorial

last modified October 18, 2023

Spring cookies tutorial shows how to work with cookies in a Spring application. Cookies are read with @CookieValue annotation.

Spring is a popular Java application framework for creating enterprise applications.

Cookies

Cookie is a small piece of data that a server sends to the user's web browser. The browser may store it and send it back with the next request to the same server.

Cookies are mainly used for session management, personalization, and tracking.

@CookieValue

@CookieValue is an annotation which indicates that a method parameter should be bound to an HTTP cookie.

HttpCookie

HttpCookie represents an HTTP cookie as a name-value pair consistent with the content of the "Cookie" request header. The ResponseCookie sub-class has the additional attributes expected in the "Set-Cookie" response header.

Spring cookies example

The following example creates a Spring web application that writes and reads a cookie.

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

This is the project structure of the Spring application.

pom.xml
<?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>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <spring-version>5.3.23</spring-version>
    </properties>

    <dependencies>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.4.0</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.3.23</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>

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

            <plugin>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>9.4.49.v20220914</version>
            </plugin>

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

We declare the project dependencies.

resources/logback.xml
<?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>
</configuration>

The logback.xml is a configuration file for the Logback logging library.

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, which is a front controller for a Spring web application, is registered in MyWebInitializer.

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

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

The getServletConfigClasses returns a web configuration class.

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 {

}

The WebConfig enables Spring MVC annotations with @EnableWebMvc and configures component scanning for the com.zetcode package.

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

We have two GET mappings. The first mapping reads a cookie, the second one writes a cookie.

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

We read a cookie value with @CookieValue. There is a default value if the cookie is not set or has expired.

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

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

We create a cookie with ResponseCookie and set it to the response header.

$ mvn jetty:run

We start the Jetty server. Now, first locate the browser to the localhost:8080/writeCookie and then read the cookie by navigating to localhost:8080/readCookie.

In this article we have work with cookies in Spring.

Author

My name is Jan Bodnar and I am a passionate programmer with many years of programming experience. I have been writing programming articles since 2007. So far, I have written over 1400 articles and 8 e-books. I have over eight years of experience in teaching programming.

List all Spring tutorials.