Thymeleaf + Spring MVC Post/Redirect/Get

Tomas

I'm doing a Post/Redirect/Get thingy, using thymeleaf and Spring MVC and it works fine. Apart from when I get to the page doing the GET and do a refresh, the ModelAttribute is reset. Here's a snippet of something similar I'm doing.

@RequestMapping("/site")
public class SiteController {
    @RequestMapping(values = {"", "/"}, method = RequestMethod.GET)
    public String index(@ModelAttribute("form") Form form, Model model) {
        return "/site/index";
    }

    @RequestMapping(values = {"/postit"}, method = RequestMethod.POST)
    public String indexPoster(@ModelAttribute("form") Form form, Model model, RedirectAttributes redirectAttributes) {
        redirectAttributes.addFlashAttribute("form", form);
        return "redirect:/site/result";
    }

    @RequestMapping(values = {"/result"}, method = RequestMethod.GET)
    public String indexResult(@ModelAttribute("form") Form form, Model model) {
        // This will print the form, but if I do a page reload, the form properties will be reset.
        System.out.println(form);
        return "/site/result";
    }
}

My Form object is just a simple java bean with one String property called name, obviously my real form has a buttload of properties, but this is for simplicity in the question.

On my html page for /site/index I have a simple form using th:object="${form}" and th:field="*{name}" that does a post to /postit. And on my /site/result I just output the name entered in the form. (so it's sort of a Hello World at the moment :) ).

This flow works for me, but if I hit refresh after the /site/result has been loaded, the form variable in indexResult gets reset.

I've tried using

private Form form;
@ModelAttribute("form")
public Form getForm() {
    if (this.form == null) {
        this.form = new Form();
    }
    return this.form;
}

on the class level, but it feels "hacky". And if I navigate away from the page, do other stuff and then return the old data will still be there.

In this project we are refraining (as far as we can) to use the session to store data.

René Kamp

What you are experiencing is the exact behavior of flash attributes. They are stored in the session right before the redirect, then loaded as model attributes after the redirect and removed from the session immediately. They are only present for a single request after redirecting.

Unfortunately there doesn't seem to be a very elegent way of handling requests to a request mapping that requires certain flash/model attributes to be present. One way of doing it would be adding a flash attribute with a predefined key/value. This will be present as a model attribute after the redirect. If it's missing you can take action accordingly (e.g. redirect to the initial form).

If you want the form data to be available after multiple refreshes of the result page you have to either use the session or send them as request attributes through the URL although the latter is not really an elegant option.

A word of caution though: Your "sollution" of storing the form as a private will not work at all. Remember that spring controllers are singleton beans so now this single form model instance will be used for every concurrent request on your site effectivly making them share the submitted data.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related