How to pass model attributes from one Spring MVC controller to another controller?
Asked Answered
C

10

44

I am redirecting from a controller to another controller. But I also need to pass model attributes to the second controller.

I don't want to put the model in session.

Please help.

Campbellite answered 15/9, 2011 at 10:53 Comment(1)
Consider accepting the most upvoted answer (by @aborskiy). It seems to be the right solution since 2013.Exemplify
F
14

I think that the most elegant way to do it is to implement custom Flash Scope in Spring MVC.

the main idea for the flash scope is to store data from one controller till next redirect in second controller

Please refer to my answer on the custom scope question:

Spring MVC custom scope bean

The only thing that is missing in this code is the following xml configuration:

<bean id="flashScopeInterceptor" class="com.vanilla.springMVC.scope.FlashScopeInterceptor" />
<bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
  <property name="interceptors">
    <list><ref bean="flashScopeInterceptor"/></list>
  </property>
</bean>
Fincher answered 15/9, 2011 at 11:25 Comment(0)
M
117

I use spring 3.2.3 and here is how I solved similar problem.
1) Added RedirectAttributes redirectAttributes to the method parameter list in controller 1.

public String controlMapping1(
        @ModelAttribute("mapping1Form") final Object mapping1FormObject,
        final BindingResult mapping1BindingResult,
        final Model model, 
        final RedirectAttributes redirectAttributes)

2) Inside the method added code to add flash attribute to redirectAttributes redirectAttributes.addFlashAttribute("mapping1Form", mapping1FormObject);

3) Then, in the second contoller use method parameter annotated with @ModelAttribute to access redirect Attributes

@ModelAttribute("mapping1Form") final Object mapping1FormObject

Here is the sample code from Controller 1:

@RequestMapping(value = { "/mapping1" }, method = RequestMethod.POST)
public String controlMapping1(
        @ModelAttribute("mapping1Form") final Object mapping1FormObject,
        final BindingResult mapping1BindingResult,
        final Model model, 
        final RedirectAttributes redirectAttributes) {

    redirectAttributes.addFlashAttribute("mapping1Form", mapping1FormObject);

    return "redirect:mapping2";
}   

From Contoller 2:

@RequestMapping(value = "/mapping2", method = RequestMethod.GET)
public String controlMapping2(
        @ModelAttribute("mapping1Form") final Object mapping1FormObject,
        final BindingResult mapping1BindingResult,
        final Model model) {

    model.addAttribute("transformationForm", mapping1FormObject);

    return "new/view";  
}
Margueritamarguerite answered 27/6, 2013 at 14:44 Comment(9)
nicely answered, exactly what I was looking for.Inelastic
Worked for my settings too! Thank you! Plus your explanation was clear :)Cardoza
Awesome explanation. Just got what i want. But the parameters are appending to the url, can we restrict that parameters without appending to the url.Hurricane
Reinsert is misguiding. See the @petr-kopac response.Bilow
Just a note... because it mada me crazy... for working it is necessary to have a <mvc:annotation-driven /> in your springmvc file... then just step 1 and 2 are necessary.Raybin
You are awesome, I had the exact same problem and this fixed it, thank you for this.Vanya
Do we need to clear flashAttribute after binding with ModelAttribute in the second controller?Washburn
It worked fine. this is what i was looking for. Thank you.Consociate
It helped me too! Thank you so much!Sailboat
R
15

Using just redirectAttributes.addFlashAttribute(...) -> "redirect:..." worked as well, didn't have to "reinsert" the model attribute.

Thanks, aborskiy!

Rolo answered 12/1, 2014 at 15:13 Comment(1)
Exactly. Reinsert is misguiding. The important bit is the redirectAttributes.addFlashAttribute. The second handler doesn't have to expect an extra @ModelAttribute argument.Bilow
F
14

I think that the most elegant way to do it is to implement custom Flash Scope in Spring MVC.

the main idea for the flash scope is to store data from one controller till next redirect in second controller

Please refer to my answer on the custom scope question:

Spring MVC custom scope bean

The only thing that is missing in this code is the following xml configuration:

<bean id="flashScopeInterceptor" class="com.vanilla.springMVC.scope.FlashScopeInterceptor" />
<bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
  <property name="interceptors">
    <list><ref bean="flashScopeInterceptor"/></list>
  </property>
</bean>
Fincher answered 15/9, 2011 at 11:25 Comment(0)
M
4

You can resolve it by using org.springframework.web.servlet.mvc.support.RedirectAttributes.

Here is my controller sample.

@RequestMapping(method = RequestMethod.POST)
    public String eligibilityPost(
            @ModelAttribute("form") @Valid EligibiltyForm form,
            Model model,
            RedirectAttributes redirectAttributes) {
        if(eligibilityService.validateEligibility(form)){
            redirectAttributes.addFlashAttribute("form", form);
            return "redirect:<redirect to your page>";
        }
       return "eligibility";
    }

read more on my blog at http://mayurshah.in/596/how-do-i-redirect-to-page-keeping-model-value

Masterpiece answered 10/5, 2016 at 8:58 Comment(0)
M
3

I had same problem.

With RedirectAttributes after refreshing page, my model attributes from first controller have been lost. I was thinking that is a bug, but then i found solution. In first controller I add attributes in ModelMap and do this instead of "redirect":

return "forward:/nameOfView";

This will redirect to your another controller and also keep model attributes from first one.

I hope this is what are you looking for. Sorry for my English

Mcdougall answered 2/4, 2016 at 16:1 Comment(1)
when I do this the model attributes are lostWhilst
I
1

If you want just pass all attributes to redirect...

public String yourMethod( ...., HttpServletRequest request, RedirectAttributes redirectAttributes) {
    if(shouldIRedirect()) {
        redirectAttributes.addAllAttributes(request.getParameterMap());
        return "redirect:/newPage.html";
    }
}
Integrand answered 4/8, 2017 at 22:44 Comment(0)
L
0

Maybe you could do it like this:

Don't use the model in first controller. Store data in some other shared object which could be then retrieved by second controller.

Look at this and this post. It's about the similar issue.

P.S.

You could probabbly use session scoped bean for that shared data...

Link answered 15/9, 2011 at 11:15 Comment(0)
P
0

I used @ControllerAdvice , please check is available in Spring 3.X; I am using it in Spring 4.0.

@ControllerAdvice 
public class CommonController extends ControllerBase{
@Autowired
MyService myServiceInstance;

    @ModelAttribute("userList")
    public List<User> getUsersList()
    {
       //some code
       return ...
    }
}
Pernik answered 29/10, 2015 at 2:54 Comment(0)
C
-1

By using @ModelAttribute we can pass the model from one controller to another controller

[ Input to the first Controller][1]

[]: https://i.sstatic.net/rZQe5.jpg from jsp page first controller binds the form data with the @ModelAttribute to the User Bean

@Controller
public class FirstController {
    @RequestMapping("/fowardModel")
    public ModelAndView forwardModel(@ModelAttribute("user") User u) {
        ModelAndView m = new ModelAndView("forward:/catchUser");
        m.addObject("usr", u);
        return m;
    }
}

@Controller
public class SecondController {
    @RequestMapping("/catchUser")
    public ModelAndView catchModel(@ModelAttribute("user")  User u) {
        System.out.println(u); //retrive the data passed by the first contoller
        ModelAndView mv = new ModelAndView("userDetails");
        return mv;
    }
}
Condescension answered 12/6, 2018 at 10:56 Comment(1)
In Second controller Spring create new User object and set the values of first Controller user object with the new User Object.Condescension
P
-2

Add all model attributes to the redirecting URL as query string.

Pharmacist answered 15/9, 2011 at 11:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.