Session Attributes in Spring MVC

In this post, we are exploring the use of session attributes in Spring MVC. We will explore the use of @SessionAttribute and @SessionAttributes annotation available in the Spring MVC framework.

 

Introduction

While working on the web application, we may come into a situation where the same attributes referred to in multiple pages. In an online shopping, we may need to refer to a user shopping cart at multiple pages.

To make sure the availability of the attributes (shopping cart in our case), we need to store/persist this information so as we can pull the same information on the next page. In a web application, a good place to store those attributes is in the user’s session.

Let’s explore the option to use @SessionAttribute and @SessionAttributes annotation to do this task.

 

1. Application Setup

We are using Spring Boot to build our sample application. We will use Spring Boot starters to bootstrap our web application. This is how our pom.xml look like.

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>2.0.4.RELEASE</version>
	<relativePath/>
	<!-- lookup parent from repository -->
</parent>
<properties>
	<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
	<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
	<java.version>1.8</java.version>
</properties>
<dependencies>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-thymeleaf</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-web</artifactId>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-devtools</artifactId>
		<scope>runtime</scope>
	</dependency>
	<dependency>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-test</artifactId>
		<scope>test</scope>
	</dependency>
</dependencies>

 

2. Sample Use Case

To understand session attributes in Spring MVC or specifically the @SessionAttribute and @SessionAttributes annotation, let’s take an example of a shopping cart with the following workflow.

  • Customer adds products to the cart by going to the PDP.
  • Once the customer clicks on add to cart button that product goes to the shopping cart.
  • Customer has the option to check all the products in the shopping cart by clicking on the view shopping cart link.
  • When the customer clicks on the view cart link, they land on the shopping cart page to view all products from the cart.

Here is the Shopping cart POJO

package com.javadevjournal.model;

import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public class ShoppingCart {

 private String customerName;
 private List < String > products;
 private String product;

 public String getCustomerName() {
  return customerName;
 }

 public void setCustomerName(String customerName) {
  this.customerName = customerName;
 }

 public List < String > getProducts() {
  return products;
 }

 public void setProducts(List < String > products) {
  this.products = products;
 }


 public void setProduct(String product) {
  if (CollectionUtils.isEmpty(this.getProducts())) {
   List < String > products = new ArrayList < > ();
   products.add(product);
   this.setProducts(products);
  } else {
   this.getProducts().add(product);
  }
 }

 @Override
 public boolean equals(Object o) {
  if (this == o) return true;
  if (!(o instanceof ShoppingCart)) return false;
  ShoppingCart that = (ShoppingCart) o;
  return Objects.equals(getCustomerName(), that.getCustomerName()) &&
   Objects.equals(getProducts(), that.getProducts());
 }

 @Override
 public int hashCode() {

  return Objects.hash(getCustomerName(), getProducts());
 }
}

We need two controllers to complete our application. One controller is responsible to add a product to the shopping cart and the second controller is responsible to give shopping cart details which include products in the cart.

 

2.1 @ModelAttribute Annotation

We will use @ModelAttribute annotation to support our @SessionAttribute and @SessionAttributes annotation. This annotation binds a method parameter or method return value to a named model attribute, exposed to a web view. When our controller is accessed for the first time, Spring instantiate an instance and place it in the Model.

 @ModelAttribute("shoppingCart")
 public ShoppingCart shoppingCart() {
  return new ShoppingCart();
 }

 

2.2 @SessionAttributes

We need to tell the Spring MVC framework to consider our ShoppingCart as session scope object. To to this, we use @SessionAttributes annotation in our AddToCartController.

@Controller
@SessionAttributes("shoppingCart")
public class AddToCartController { //controller logic
}

This is how our ShoppingCart controller looks like

package com.javadevjournal.controller;

import com.javadevjournal.model.ShoppingCart;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.SessionAttributes;

@Controller
@SessionAttributes("shoppingCart")
public class AddToCartController {

 @PostMapping("/addToCart")
 public String addToCart(final Model model, @ModelAttribute ShoppingCart shoppingCart, final String productCode) {
  if (shoppingCart != null) {
   //add product to the shopping cart list
   shoppingCart.setProduct(productCode);
   model.addAttribute("cart", shoppingCart);
  } else {
   ShoppingCart cart = new ShoppingCart();
   cart.setCustomerName("Super customer");
   cart.setProduct(productCode);
   model.addAttribute("cart", cart);
  }

  return "redirect:" + "product-detail-page";
 }

 @GetMapping("/product-detail-page")
 public String viewPDP(Model model, @ModelAttribute("shoppingCart") ShoppingCart shoppingCart) {
  if (shoppingCart != null) {
   model.addAttribute("cart", shoppingCart);
  } else {
   model.addAttribute("cart", new ShoppingCart());
  }
  return "product";
 }

 @ModelAttribute("shoppingCart")
 public ShoppingCart shoppingCart() {
  return new ShoppingCart();
 }
}

 

2.3 @SessionAttribute

In our ShoppingCart controller, we are binding the ShoppingCart object to the session by using @SessionAttribues annotation.@SessionAttribute annotation retrieve the existing attribute from the session. This annotation allows you to tell Spring which of your model attributes will also be copied to HttpSession before rendering the view.

Let’s continue with our example, In this step, we are creating a new CartPageController which is responsible to get all the products from the customer shopping cart. We are using Session to store our shopping cart, to retrieve this shopping cart, we are will use @SessionAttribute annotation.

 public String cart(@SessionAttribute("shoppingCart") ShoppingCart cart, final Model model) { // }

This is how our CartPageController look like

package com.javadevjournal.controller;

import com.javadevjournal.model.ShoppingCart;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.SessionAttribute;
import org.springframework.web.bind.annotation.SessionAttributes;

@Controller
public class CartPageController {

 @GetMapping("/cart")
 public String cart(@SessionAttribute("shoppingCart") ShoppingCart cart, final Model model) {
  model.addAttribute("cart", cart);
  return "cart";
 }
}

 

2.4. Running Application

Let’s see our application in action, In the first step, add to cart page shown to the customer where customer adds products to the shopping cart.

Session Attributes in Spring MVC

For this post, we are adding following 4 products to the shopping cart

  1. 123
  2. 234
  3. 321
  4. 432

Please remember, all these products are in the ShoppingCart object stored in the session. When we click on the “Go To cart Page” link, we land on the shopping cart page served by ShoppingCartController.

Session Attributes in Spring MVC

 

Using @SessionAttribute,@SessionAttributes with @ModelAttribute is a simple and easy strategy and does not need any complex logic.

 

Summary

In this post, we explore the use of session attributes in Spring MVC. We got an understanding of using @SessionAttribute,@SessionAttributes with @ModelAttribute annotation. Download the complete application for this project from GitHub

1 thought on “Session Attributes in Spring MVC”

Comments are closed.