1

I am faced with a peculiar problem. I am learning SpringMVC and this is my first application project with it.

When we use @SesssionAttributes annotation in a controller, the session attribute is automatically updated, if any handler method having a @ModelAttribute argument with the same name as a @SessionAttribute in its signature is invoked.

now i redirected the control to another handler mathod which in turn renders a jsp. The problem I am facing is that I am able to access the @SessionAttribute in the redirected handler method but in the jsp it renders the session attribute is lost.

Here is the code.

@Controller
@EnableWebMvc
@RequestMapping("/courtreservation/*")
@SessionAttributes("courtDetails")
public class ControllerServlet {



@RequestMapping(value="basePage",method=RequestMethod.GET)
public String basePageRenderer(Model model,HttpServletRequest request){
CourtDetails tempObj = (CourtDetails)request.getSession().getAttribute("courtDetails");        
 GenericXmlApplicationContext context = new GenericXmlApplicationContext();
    context.load("configs/applicationContext.xml");
    context.refresh();
    CourtDetails courtDetails = (CourtDetails)context.getBean("courtDetails");
    List<String> allSports = courtDetails.getAllSports();
    Calendar calendar = Calendar.getInstance();
    int numDay = calendar.get(Calendar.DAY_OF_WEEK);
    System.out.println(numDay);
    String[] days = {"sunday","monday","tuesday","wednesday","friday","saturday","sunday"};
    /*List<String> daysAvailableForReservation = new ArrayList<>();
    if(numDay == 1) {
        for(String day:days) {
            daysAvailableForReservation.add(day);
        }
    }
    else {
       for(int i=numDay--;i<days.length;i++) {
           daysAvailableForReservation.add(days[i]);
       }
    }*/
    model.addAttribute("daysAvailableForReservation", days);
    model.addAttribute("courtDetails", courtDetails);
    model.addAttribute("allSports",allSports);
    return "welcomePage";
}

@RequestMapping(value="checkAvailability",method=RequestMethod.POST)
public String checkAvailability(CourtDetails courtDetails,HttpServletRequest request,HttpServletResponse response,Model model) {
    HttpSession session = request.getSession();
    courtDetails = (CourtDetails)session.getAttribute("courtDetails");
    Boolean isAvailable = courtDetails.checkAvailability();
    if(isAvailable) {
        model.addAttribute("isAvailable","true");
        model.addAttribute("courtDetails",courtDetails);
        return "welcomePage";
    }
    model.addAttribute("isAvailable", "false");
    model.addAttribute("courtDetails",courtDetails);
    return "unavailable";
}






}

After the redirect from checkAvailability the @SessionAttribute("courtDetails") is available in the basePageRenderer() but not in the jsp it renders which is welcomePage.jsp.

here are the view resolution configs.

1) Controller servlet config:

<bean class="org.springframework.web.servlet.view.XmlViewResolver" 
          p:location="/WEB-INF/classes/configs/appViews.xml" 
          p:order="0" />

2) appView.xml

<bean id="unavailable"
      class="org.springframework.web.servlet.view.RedirectView"
      p:url="/Sports_Reservation/courtreservation/basePage"  />
Nish
  • 31
  • 1
  • 6

2 Answers2

1

It seems to be well explained here. I had similar issue, and ended up using forward instead of redirect.

Community
  • 1
  • 1
Sanjay
  • 8,755
  • 7
  • 46
  • 62
0

Change your second handler to be like this:

@RequestMapping(value="checkAvailability",method=RequestMethod.POST)
public String checkAvailability(
    @ModelAttribute("courtDetails") CourtDetails courtDetails,
    HttpServletRequest request,
    HttpServletResponse response,
    Model model
)

This will read the modelAttribute from session and then set the values from the post. You don't need to manually read the value from session.

Neil McGuigan
  • 46,580
  • 12
  • 123
  • 152
  • Thanks for the reply Neil. My understanding about the fix propounded by you is that as soon as the method checkAvailability() is called the session attribute would be updated and the method would read the model attribute from session only if it isn't present in the model(Request scope). Since i already have the model attribute embedded in the request the spring won't read it from the session. Am i missing something or my understanding here is flawed? Please correct me if that's the case. Moreover this still doesn't solve the problem of session attribute getting lost at redirect. – Nish Aug 25 '15 at 22:49
  • If the redirect is the problem then you should store the model in a flashAttribute. See redirectAttributes parameter – Neil McGuigan Aug 25 '15 at 23:44
  • Hi Neil, your modifications in the second handler method are working, Thank you. However I am not able to understand as to how is this handler picking up the "courtDetails" attribute from the @SessionAttribute? My understanding goes like this. The method is a post request so already existing model attributes are lost as they are in request scope. So when the handler is called the @SessionAttribute automatically gets updated with the values submitted with the form. Since there is no model/request scope attribute "courtDetails" the handler reads it from the session. Am I right? – Nish Aug 26 '15 at 15:42
  • @Nish When your GET method exits, Spring puts "courtDetails" into session (because it's a sessionattribute). It reads it from session again just before POST (because it's a modelattribute). see https://stackoverflow.com/questions/8688135/modelattribute-annotation-when-to-use-it/26916920#26916920 – Neil McGuigan Aug 26 '15 at 17:50
  • Thanks a lot my friend, the things a little clearer now. However the peculiarity with the session objects continue to persist when redirecting. They remain in session scope and are very well accessible in controller handler methods but are somehow lost in the view (read jsp). From what I could find out on the net it's a bug in spring, – Nish Aug 27 '15 at 18:16