How to use Session attributes in Spring-mvc

Spring MvcSessionServlets

Spring Mvc Problem Overview


Could you help me write spring mvc style analog of this code?

 session.setAttribute("name","value");

And how to add an element that is annotated by @ModelAttribute annotation to session and then get access to it?

Spring Mvc Solutions


Solution 1 - Spring Mvc

If you want to delete object after each response you don't need session,

If you want keep object during user session , There are some ways:

  1. directly add one attribute to session:

     @RequestMapping(method = RequestMethod.GET)
     public String testMestod(HttpServletRequest request){
        ShoppingCart cart = (ShoppingCart)request.getSession().setAttribute("cart",value);
        return "testJsp";
     }
    

and you can get it from controller like this :

    ShoppingCart cart = (ShoppingCart)session.getAttribute("cart");

2. Make your controller session scoped

    @Controller
    @Scope("session")

3. Scope the Objects ,for example you have user object that should be in session every time:

    @Component
    @Scope("session")
    public class User
     {
        String user;
        /*  setter getter*/
      }

then inject class in each controller that you want

       @Autowired
       private User user

that keeps class on session.

  1. The AOP proxy injection : in spring -xml:

     <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
         http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
         http://www.springframework.org/schema/aop
         http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
    
       <bean id="user"    class="com.User" scope="session">     
           <aop:scoped-proxy/>
       </bean>
     </beans>
    

then inject class in each controller that you want

    @Autowired
    private User user

5.Pass HttpSession to method:

 String index(HttpSession session) {
            session.setAttribute("mySessionAttribute", "someValue");
            return "index";
        }

6.Make ModelAttribute in session By @SessionAttributes("ShoppingCart"):

  public String index (@ModelAttribute("ShoppingCart") ShoppingCart shoppingCart, SessionStatus sessionStatus) {
//Spring V4
//you can modify session status  by sessionStatus.setComplete();
}

or you can add Model To entire Controller Class like,

@Controller
    @SessionAttributes("ShoppingCart")
    @RequestMapping("/req")
    public class MYController {
    
        @ModelAttribute("ShoppingCart")
        public Visitor getShopCart (....) {
            return new ShoppingCart(....); //get From DB Or Session
        }  
      }

each one has advantage and disadvantage:

@session may use more memory in cloud systems it copies session to all nodes, and direct method (1 and 5) has messy approach, it is not good to unit test.

To access session jsp

<%=session.getAttribute("ShoppingCart.prop")%>

in Jstl :

<c:out value="${sessionScope.ShoppingCart.prop}"/>

in Thymeleaf:

<p th:text="${session.ShoppingCart.prop}" th:unless="${session == null}"> . </p>

Solution 2 - Spring Mvc

Use @SessionAttributes

See the docs: Using @SessionAttributes to store model attributes in the HTTP session between requests

"Understanding Spring MVC Model And Session Attributes" also gives a very good overview of Spring MVC sessions and explains how/when @ModelAttributes are transferred into the session (if the controller is @SessionAttributes annotated).

That article also explains that it is better to use @SessionAttributes on the model instead of setting attributes directly on the HttpSession because that helps Spring MVC to be view-agnostic.

Solution 3 - Spring Mvc

SessionAttribute annotation is the simplest and straight forward instead of getting session from request object and setting attribute. Any object can be added to the model in controller and it will stored in session if its name matches with the argument in @SessionAttributes annotation. In below eg, personObj will be available in session.

@Controller
@SessionAttributes("personObj")
public class PersonController {

	@RequestMapping(value="/person-form")
	public ModelAndView personPage() {
		return new ModelAndView("person-page", "person-entity", new Person());
	}
	
	@RequestMapping(value="/process-person")
	public ModelAndView processPerson(@ModelAttribute Person person) {
		ModelAndView modelAndView = new ModelAndView();
		modelAndView.setViewName("person-result-page");
		
		modelAndView.addObject("pers", person);
		modelAndView.addObject("personObj", person);
		
		return modelAndView;
	}
	
}

Solution 4 - Spring Mvc

The below annotated code would set "value" to "name"

@RequestMapping("/testing")
@Controller
public class TestController {
@RequestMapping(method = RequestMethod.GET)
public String testMestod(HttpServletRequest request){
    request.getSession().setAttribute("name", "value");
    return "testJsp";
  }
}

To access the same in JSP use ${sessionScope.name}.

For the @ModelAttribute see this link

Solution 5 - Spring Mvc

Isn't it easiest and shortest that way? I knew it and just tested it - working perfect here:

@GetMapping
public String hello(HttpSession session) {
    session.setAttribute("name","value");
    return "hello";
}

p.s. I came here searching for an answer of "How to use Session attributes in Spring-mvc", but read so many without seeing the most obvious that I had written in my code. I didn't see it, so I thought its wrong, but no it was not. So lets share that knowledge with the easiest solution for the main question.

Solution 6 - Spring Mvc

Try this...

@Controller
@RequestMapping("/owners/{ownerId}/pets/{petId}/edit")
@SessionAttributes("pet")
public class EditPetForm {
 
    @ModelAttribute("types")
     
    public Collection<PetType> populatePetTypes() {
        return this.clinic.getPetTypes();
    }
     
    @RequestMapping(method = RequestMethod.POST)
    public String processSubmit(@ModelAttribute("pet") Pet pet, 
            BindingResult result, SessionStatus status) {
        new PetValidator().validate(pet, result);
        if (result.hasErrors()) {
            return "petForm";
        }else {
            this.clinic.storePet(pet);
            status.setComplete();
            return "redirect:owner.do?ownerId="
                + pet.getOwner().getId();
        }
    }
}

Solution 7 - Spring Mvc

In Spring 4 Web MVC. You can use @SessionAttribute in the method with @SessionAttributes in Controller level

@Controller
@SessionAttributes("SessionKey")
public class OrderController extends BaseController {

    GetMapping("/showOrder")
    public String showPage(@SessionAttribute("SessionKey") SearchCriteria searchCriteria) {
     // method body
}

Solution 8 - Spring Mvc

When I trying to my login (which is a bootstrap modal), I used the @sessionattributes annotation. But problem was when the view is a redirect ("redirect:/home"), values I entered to session shows in the url. Some Internet sources suggest to follow http://docs.spring.io/spring/docs/4.3.x/spring-framework-reference/htmlsingle/#mvc-redirecting But I used the HttpSession instead. This session will be there until you close the browsers. Here is sample code

        @RequestMapping(value = "/login")
        @ResponseBody
        public BooleanResponse login(HttpSession session,HttpServletRequest request){
            //HttpServletRequest used to take data to the controller
            String username = request.getParameter("username");
            String password = request.getParameter("password");
    
           //Here you set your values to the session
           session.setAttribute("username", username);
           session.setAttribute("email", email);

          //your code goes here
}

You don't change specific thing on view side.

<c:out value="${username}"></c:out>
<c:out value="${email}"></c:out>

After login add above codes to anyplace in you web site. If session correctly set, you will see the values there. Make sure you correctly added the jstl tags and El- expressions (Here is link to set jstl tags https://menukablog.wordpress.com/2016/05/10/add-jstl-tab-library-to-you-project-correctly/)

Solution 9 - Spring Mvc

Use This method very simple easy to use

HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getNativeRequest();

															request.getSession().setAttribute("errorMsg", "your massage");

in jsp once use then remove

<c:remove var="errorMsg" scope="session"/>		

										

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestiongstackoverflowView Question on Stackoverflow
Solution 1 - Spring MvcAli.MojtehedyView Answer on Stackoverflow
Solution 2 - Spring MvcHeinrich FilterView Answer on Stackoverflow
Solution 3 - Spring MvcAmarView Answer on Stackoverflow
Solution 4 - Spring MvcaksappyView Answer on Stackoverflow
Solution 5 - Spring MvcstrashView Answer on Stackoverflow
Solution 6 - Spring MvcR Palanivel-Tamilnadu IndiaView Answer on Stackoverflow
Solution 7 - Spring Mvcsendon1982View Answer on Stackoverflow
Solution 8 - Spring MvcMenuka IshanView Answer on Stackoverflow
Solution 9 - Spring MvcBachasView Answer on Stackoverflow