Announcement Announcement Module
Collapse
No announcement yet.
Spring MVC 3.1 RedirectAttributes is not working Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring MVC 3.1 RedirectAttributes is not working

    I'm trying to implement RedirectAttributes feature in Spring MVC 3.1-Release

    I'm sending simple form to Post URL and would like to see the the value I'm sending in redirect:

    my Controller looks like this:

    Code:
    @Controller
    public class DefaultController {
    
        @RequestMapping(value="/index.html", method=RequestMethod.GET)
        public ModelAndView indexView(){
            ModelAndView mv = new ModelAndView("index");
        return mv;
        }
    
        @RequestMapping(value="/greetings.action", method=RequestMethod.POST)
        public ModelAndView startTask(@RequestParam("firstName") String firstName,RedirectAttributes redirectAttributes){
            redirectAttributes.addFlashAttribute("redirectAttributes.firstName", firstName);
            ModelAndView mv = new ModelAndView(new RedirectView("success.html"));
            return mv;
        }
    
        @RequestMapping(value="/success.html", method=RequestMethod.GET)
        public ModelAndView successView(){
            ModelAndView mv = new ModelAndView("success");
            return mv;
        }
    }
    My servlet XML looks like this:

    Code:
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:p="http://www.springframework.org/schema/p"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.1.xsd
    http://www.springframework.org/schema/mvc
    http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
    <mvc:annotation-driven/>
    <context:component-scan base-package="com.vanilla.flashscope.controllers" />
    
        <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix">
                <value>/</value>
            </property>
            <property name="suffix">
                <value>.jsp</value>
            </property>
        </bean>
    </beans>
    My problem is that in success.html view redirectAttributes is empty:

    Code:
    <body>
    <h5>${redirectAttributes.firstName} </h5> 
    </body>
    Prints nothing!

    I checked few post in this forum and I undestans that I should have RequestMappingHandlerMapping, RequestMappingHandlerAdapter, and ExceptionHandlerExceptionResolver enabled, but as far as I understand having
    Code:
    <mvc:annotation-driven/>
    enables these Handlers automatically.

    What is wrong? Please help.

  • #2
    You have the handlers (that is indeed what mvc:annotation-driven does, amongst other things).

    However the fact that it doesn't print anything doesn't mean it isn't working... Have you checked that you actually get a value?

    Another note is why aren't you simply using a view-controller to map the index and success view, saves you some code.

    Comment


    • #3
      Originally posted by Marten Deinum View Post

      However the fact that it doesn't print anything doesn't mean it isn't working... Have you checked that you actually get a value?
      Thank you for reply. Actually, I haven't found any documentation how to fetch the values in GET request after redirect. with Spring 3.0 I used this solution. So I thought I can fetch values the same way.
      How can I check that I got the value in my GET controller? Unfortunately, I got lost here.

      Comment


      • #4
        The values are added to the model/request by the DispatcherServlet (which delegates that to a FlashMapManager). What I was hinting at was that your first name is empty in the POST (not the GET).

        Comment


        • #5
          After the redirect, any code can access the flash map via RequestContextUtils.getInputFlashMap(request) assuming the DispatcherServlet is used to process the request. An annotated controller however doesn't need to do anything at all because its model is populated with the content of the flash map, assuming the RequestMappingHandlerAdapter is in use. I see one issue with the above code sample, possibly two.

          In successView() a ModelAndView is returned, which ignores the content of the "implicit" model that is populated with the flash attributes. As far as I can see there is really no need to use ModelAndView and its use is generally not very helpful with annotated controllers. A more idiomatic way to write the above controller is:

          Code:
          @Controller
          public class DefaultController {
          
              @RequestMapping(value="/index.html", method=RequestMethod.GET)
              public String indexView(){
                  return "index";
              }
          
              @RequestMapping(value="/greetings.action", method=RequestMethod.POST)
              public String startTask(@RequestParam("firstName") String firstName,RedirectAttributes redirectAttributes){
                  redirectAttributes.addFlashAttribute("redirectAttributes.firstName", firstName);
                  return "redirect:success.html";
              }
          
              @RequestMapping(value="/success.html", method=RequestMethod.GET)
              public String successView(){
                  return "success";
              }
          }
          To check or to add something to the model, simply add a Model argument to any of the @RequestMapping methods.

          The second (potential) issue is with having a "." in the the name of the attribute. I suspect the EL expression "${redirectAttributes.firstName}" might be interpreted as an attribute called "redirectAttributes" with a field called firstName but you'd have to confirm that.

          Comment


          • #6
            Rossen, thank you for your feedback.

            I've tried the following:

            Code:
            @RequestMapping(value="/success.html", method=RequestMethod.GET)
            	public String successView(HttpServletRequest request){
            		Map<String,?> map = RequestContextUtils.getInputFlashMap(request); 
                            if (map != null){
                            String firstName = map.get("firstName");}
            		return "success";
            	}
            but map is null.

            I tried it as you suggested:

            Code:
            	@RequestMapping(value="/success.html", method=RequestMethod.GET)
            	public String successView(HttpServletRequest request){
            		return "success";
            	}
            prints nothing.

            I also tried it without "." just use firstName, but the result was the same. How can I make sure that RequestMappingHandlerAdapter is in use?

            Comment


            • #7
              You didn't show the method that does the redirect. I presume it returns "redirect:something" or a RedirectView.

              Set logging for org.springframework.web to DEBUG level. After the request, confirm a message from RequestMappingHandlerMapping:

              Code:
              RequestMappingHandlerMapping - Looking up handler method for path /form
              RequestMappingHandlerMapping - Returning handler method [public java.lang.String ...]
              Also look for messages from the DefaultFlashMapManager before and after the redirect:

              Code:
              DefaultFlashMapManager - Saving FlashMap=[Attributes={...}]
              DispatcherServlet - Successfully completed request
              DispatcherServlet - DispatcherServlet with name 'appServlet' processing GET request for ...
              DefaultFlashMapManager - Retrieved FlashMap(s): ...
              DefaultFlashMapManager - Found matching FlashMap(s): [[Attributes={..}]

              Comment


              • #8
                I had a similar problem, and looking at the source I found out it won't work with ModelAndView. Returning a string from the redirecting handler method works.

                @Rossen - I think ModelAndView can be useful if one handler method can have very different outputs. I use it to set exposeModelAttributes to false for example. I haven't found another way of doing that...

                So in a way it would be helpful if ModelAndView would be able to handle RedirectAttributes properly.

                Comment


                • #9
                  @meyertree, the change for ModelAndView has been made as part of SPR-8968. As for ModelAndView accepting a Model as input and returning either a view name (String) or a View instance works in most cases.

                  Comment


                  • #10
                    Oh great, it's already fixed Thank you.

                    Comment

                    Working...
                    X