# How to create and read cookies in Spring Boot

By Atta Ur Rehman Shah (https://attacomsian.com/about). Published Apr 24, 2019, updated Sep 25, 2022. Topics: Spring Boot.
Canonical URL: https://attacomsian.com/blog/cookies-spring-boot

> A complete guide to learning how to read, write, and delete cookies in a Spring Boot web application. 

An HTTP cookie (also known as **web cookie**, **browser cookie**) is a small piece of information stored by the server in the user's browser. The server sets the cookies while returning the response for a request made by the browser. The browser stores the cookies and sends them back with subsequent requests to the same server. 

Cookies are typically used for session management, user-tracking, and storing user preferences. Cookies are also used to recognize the client across multiple requests. Without cookies,  the server would treat every request as a new client.

In this article, you'll learn how to create, read, and remove HTTP cookies in a Spring Boot application.

## Creating a Cookie

To set a cookie in Spring Boot, we can use the `addCookie()` method from the `HttpServletResponse` class. All you need to do is to create a new instance of `Cookie` and add it to the response as shown below:

```java
@GetMapping("/change-username")
public String setCookie(HttpServletResponse response) {
    // create a cookie
    Cookie cookie = new Cookie("username", "Jovan");

    //add a cookie to the response
    response.addCookie(cookie);

    return "Username is changed!";
}
```

### Cookie Expiration Date

If no expiration time is specified for a cookie, it lasts as long as the session is not expired. Such cookies as called **session cookies**.  Session cookies remain active until the user closes their browser or clears their cookies. The `username` cookie created above is, in fact, a session cookie.

But you can override this default behavior and set the cookie expiration time using the `setMaxAge()` method of the `Cookie` class:

```java
// create a cookie
Cookie cookie = new Cookie("username", "Jovan");
cookie.setMaxAge(7 * 24 * 60 * 60); // expires in 7 days

//add a cookie to the response
response.addCookie(cookie);
```

 Now, instead of expiring on browser close, the `username` cookie will remain active for the next 7 days. Cookies that expire at a specified date and time are called **permanent cookies**.

> **Note:** The expiry time passed to `setMaxAge()` method is in seconds. The expiry date and time are relative to the client where the cookie is being set, not the server.

### Secure Cookie

A secure cookie is only sent to the server over an encrypted HTTPS connection. Secure cookies cannot be transmitted to the server over unencrypted HTTP connections.

To make a cookie `Secure`, use the `setSecure()` method:

```java
// create a cookie
Cookie cookie = new Cookie("username", "Jovan");
cookie.setMaxAge(7 * 24 * 60 * 60); // expires in 7 days
cookie.setSecure(true);

//add a cookie to the response
response.addCookie(cookie);
```

### `HttpOnly` Cookie

If the `HttpOnly` attribute is set for a cookie, it is not accessible to the client scripts. For example, you can not use the `Document.cookie` property to access `HttpOnly` cookies in JavaScript.

```java
// create a cookie
Cookie cookie = new Cookie("username", "Jovan");
cookie.setMaxAge(7 * 24 * 60 * 60); // expires in 7 days
cookie.setSecure(true);
cookie.setHttpOnly(true);

//add a cookie to the response
response.addCookie(cookie);
```

This is one way to secure a cookie from being changed by malicious code or cross-site scripting (XSS) attacks.

### Cookie Path

The `Path` attribute specifies a URL path for which the cookie should be sent to the server. By default, if no path is specified, a cookie is only sent to the server for the URL that was used to set it in the browser. 

You can use the `setPath()` method to set the `Path` directive for the cookie:

```java
// create a cookie
Cookie cookie = new Cookie("username", "Jovan");
cookie.setMaxAge(7 * 24 * 60 * 60); // expires in 7 days
cookie.setSecure(true);
cookie.setHttpOnly(true);
cookie.setPath("/"); // global cookie accessible every where

//add a cookie to the response
response.addCookie(cookie);
```

By explicitly setting the `Path` directive, the cookie will be delivered to the specified URL and all of its subdirectories.

## Reading a Cookie

Spring framework provides `@CookieValue` annotation to get the value of any HTTP cookie without iterating over all the cookies fetched from the request. This annotation can be used to map the value of a cookie to the controller method parameter:

```java
@GetMapping("/")
public String readCookie(@CookieValue(value = "username", defaultValue = "Atta") String username) {
    return "Hey! My username is " + username;
}
```

In above code snippet, notice the `defaultValue = "Atta"`. If the default value is not set, Spring will throw a `java.lang.IllegalStateException` exception on failure to find the cookie with the name `username` in the HTTP request.


## Reading all Cookies

Instead of using the `@CookieValue` annotation, we can also use the `HttpServletRequest` class as a controller method parameter to read all cookies. This class provides the `getCookies()` method that returns all cookies sent by the browser as an array of `Cookie`.

```java
@GetMapping("/all-cookies")
public String readAllCookies(HttpServletRequest request) {

    Cookie[] cookies = request.getCookies();
    if (cookies != null) {
        return Arrays.stream(cookies)
                .map(c -> c.getName() + "=" + c.getValue()).collect(Collectors.joining(", "));
    }

    return "No cookies";
}
```

Read [this article](https://attacomsian.com/blog/read-cookies-spring-boot) to learn more ways to read cookies in Spring Boot. 

## Deleting a Cookie

To delete a cookie, you need to create a new instance of the `Cookie` class with the same name and the `Max-Age` directive to `0`, and add it again to the response as shown below: 

```java
// create a cookie
Cookie cookie = new Cookie("username", null);
cookie.setMaxAge(0);
cookie.setSecure(true);
cookie.setHttpOnly(true);
cookie.setPath("/");

//add a cookie to the response
response.addCookie(cookie);
```

> **Note:** Don't set the `Max-Age` directive value to `-1`. Otherwise, it will be treated as a session cookie by the browser.

## Summary

Cookies provide a way to exchange the information between the server and the browser to manage sessions (logins, shopping carts, game scores), remember user preferences (themes, privacy policy acceptance), and track user behavior across the site.

Spring Boot provides an easy way to read, write and remove HTTP cookies.

 1. `@CookieValue` annotation maps the value of the cookie to the method parameter. You should set the default value to avoid runtime exceptions when the cookie is not available.
 2. `HttpServletResponse` class can be used to set a new cookie in the browser. You just need to create an instance of `Cookie` and add it to the response.
 3. To read all cookies, you can use `HttpServletRequest`'s `getCookies()` method which returns an array of `Cookie`.
 4. `Max-Age` directive specifies the date and time when the cookie should expire. 
 5. If you are storing sensitive information in a cookie, ensure to set the `Secure` and `HttpOnly` attributes to avoid XSS attacks.
 6. Set the `Path=/` to make a cookie accessible everywhere for the current domain.
 7. To delete a cookie, set the `Max-Age` to `0` and pass all the properties you used to set it for the first time.

> ? Download the complete source code from [GitHub](https://github.com/attacomsian/code-examples/tree/master/spring-boot/cookies) available under the MIT license.

**Read Next:** [How to get and set cookies in JavaScript](https://attacomsian.com/blog/javascript-cookies)
