Spring MVC 4 - @SessionAttributes or @SessionAttribute example

Posted on August 28, 2017


Technologies used: Java SE 1.8 | Spring 4.3.10.RELEASE | Maven 3.3.9 | Eclipse Neon.3 | Apache Tomcat  7.0.47

In this post, I will show you how to use the @SessionAttributes and @SessionAttribute annotations in Spring MVC with the help of a small login application.

@SessionAttributes annotation is used to store the model attribute in the session. This annotation is used at controller class level.

@SessionAttributes("user")
public class LoginController {

	@ModelAttribute("user")
	public User setUpUserForm() {
		return new User();
	}
}

In the above code snippet, the model attribute ‘user’ will be added to the session if the name attribute of the @ModelAttribute and @SessionAttributes annotations is same.
 
@SessionAttribute annotation is used to retrieve the existing attribute from session that is managed globally and it is used at method parameter as shown follows.

@GetMapping("/info")
public String userInfo(@SessionAttribute("user") User user) {
	//...
	//...
	return "user";
}

Let's begin step by step..

Project structure

Review the following web project structure build using Maven.

Spring-mvc-session-attributes.png

Related - How to create a web project using maven build tool in eclipse IDE.

Jar dependencies

Open pom.xml file of your maven project and add the following dependencies in it.

<dependencies>
  <!-- Spring MVC Dependency -->
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>4.3.10.RELEASE</version>
  </dependency>
  <!-- JSTL Dependency -->
  <dependency>
    <groupId>javax.servlet.jsp.jstl</groupId>
    <artifactId>javax.servlet.jsp.jstl-api</artifactId>
    <version>1.2.1</version>
  </dependency>
  <dependency>
    <groupId>taglibs</groupId>
    <artifactId>standard</artifactId>
    <version>1.1.2</version>
  </dependency>
  <!-- Servlet Dependency -->
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
  </dependency>
  <!-- JSP Dependency -->
  <dependency>
    <groupId>javax.servlet.jsp</groupId>
    <artifactId>javax.servlet.jsp-api</artifactId>
    <version>2.3.1</version>
    <scope>provided</scope>
  </dependency>
</dependencies>

Model class

Consider the following model class.

User.java

package com.boraji.tutorial.spring.model;

public class User {
   private String email;
   private String password;
   private String fname;
   private String mname;
   private String lname;
   private int age;

	// Getter and Setter methods
}

Controller class

Create a LoginController class and annotated this class with @SessionAttributes to store the user object in the session.

LoginController.java

package com.boraji.tutorial.spring.controller;

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;

import com.boraji.tutorial.spring.model.User;

@Controller
@SessionAttributes("user")
public class LoginController {
   /*
    * Add user in model attribute
    */
   @ModelAttribute("user")
   public User setUpUserForm() {
      return new User();
   }

   @GetMapping("/")
   public String index() {
      return "index";
   }

   @PostMapping("/dologin")
   public String doLogin(@ModelAttribute("user") User user, Model model) {

      // Implement your business logic
      if (user.getEmail().equals("[email protected]") && user.getPassword().equals("[email protected]")) {
         // Set user dummy data
         user.setFname("Sunil");
         user.setMname("Singh");
         user.setLname("Bora");
         user.setAge(28);
      } else {
         model.addAttribute("message", "Login failed. Try again.");
         return "index";
      }
      return "success";
   }
}

Now, create another controller class named as UserController and annotated the controller's handler method parameter with  @SessionAttribute to get the user object from session.

UserController.java

package com.boraji.tutorial.spring.controller;

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.SessionAttribute;

import com.boraji.tutorial.spring.model.User;

@Controller
@RequestMapping("/user")
public class UserController {

   /*
    * Get user from session attribute
    */
   @GetMapping("/info")
   public String userInfo(@SessionAttribute("user") User user) {

      System.out.println("Email: " + user.getEmail());
      System.out.println("First Name: " + user.getFname());

      return "user";
   }
}

 

JSP Views

Create a new folders as \WEB-INF\views under src\main\webapp folder. 

Now create index.jspsuccess.jsp and user.jsp files under src\main\webapp\WEB-INF\views under folder.

index.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
  pageEncoding="ISO-8859-1"%>
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>BORAJI.COM</title>
</head>
<body>
  <h1>User Login</h1>

  <form:form action="dologin" method="post" modelAttribute="user">
    <table>
      <tr>
        <td>Email</td>
        <td><form:input path="email" /></td>
      </tr>
      <tr>
        <td>Password</td>
        <td><form:password path="password" /></td>
      </tr>
      <tr>
        <td><button type="submit">Login</button></td>
      </tr>
    </table>
  </form:form>

  <span style="color: red;">${message}</span>
</body>
</html>

success.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
  pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>BORAJI.COM</title>
</head>
<body>
  <h1>Login Success Page</h1>
  <p>You are logged in with email ${user.email}.</p>
 
  <!-- Click here to view the session attributes -->
  <a href="/user/info">View profile</a>
</body>
</html>

user.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
  pageEncoding="ISO-8859-1"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>BORAJI.COM</title>
</head>
<body>
  <h1>User profile Page</h1>
  <table>
    <tr>
      <td>First Name</td>
      <td>${user.fname}</td>
    </tr>
    <tr>
      <td>Middle Name</td>
      <td>${user.mname}</td>
    </tr>
    <tr>
      <td>Last Name</td>
      <td>${user.lname}</td>
    </tr>
    <tr>
      <td>Age</td>
      <td>${user.age}</td>
    </tr>
  </table>
</body>
</html>

Spring configuration

Create a web @Configuration class annotated with @EnableWebMvc and @ComponentScan as follows. 

WebConfig.java

package com.boraji.tutorial.spring.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "com.boraji.tutorial.spring.controller" })
public class WebConfig extends WebMvcConfigurerAdapter {

   @Bean
   public InternalResourceViewResolver resolver() {
      InternalResourceViewResolver resolver = new InternalResourceViewResolver();
      resolver.setViewClass(JstlView.class);
      resolver.setPrefix("/WEB-INF/views/");
      resolver.setSuffix(".jsp");
      return resolver;
   }
}

Servlet container initialization

Create a container initializer class by extending the AbstractAnnotationConfigDispatcherServletInitializer class as follows.

MyWebAppInitializer.java

package com.boraji.tutorial.spring.config;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

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

   @Override
   protected Class<?>[] getServletConfigClasses() {
      return new Class[] { WebConfig.class };
   }

   @Override
   protected String[] getServletMappings() {
      return new String[] { "/" };
   }
}

The AbstractAnnotationConfigDispatcherServletInitializer class, implements the WebApplicationInitializer, is implemented in Servlet 3.0+ environments in order to configure the ServletContext programmatically. 

 

Build + Deploy + Run application

Use the following maven commands to build, package, deploy and run application.

mvn clean install  (This command triggers war packaging)

mvn tomcat7:run (This command run embedded tomcat and deploy war file automatically)

You can refer this link to learn how to run the above commands in Eclipse IDE.

 

Type the following URLs in browser's address bar to open the user login from.

http://localhost:8080/

Spring-mvc-session-attributes01.png

Now, enter the username and password. On successful login, you will see the follow page.

Spring-mvc-session-attributes02.png

Now, click on the 'View profile' link to view the user information from session attributes.

Spring-mvc-session-attributes03.png

Download Sources