3

When modifying a ModelAttribute that is listed as a SessionAttribute, why doesent it keep its new value?

Every time I make a request to the example below, it prints out "Initial value.", which is a correct value for the first request. But after the first request, its value should be "new value".

Why doesent ModelAttribute store its value?

I have a base class. All servlets extending this:

@SessionAttributes(value = {"test_string", "something"})
public abstract class Base<T>
    {
    public abstract T request(
            @ModelAttribute("test_string") String _test_string,
            ModelAndView _mv);

    @ModelAttribute("test_string")
    private String getTest()
    {
        return "Initial value.";
    }
}

I have a specific servlet:

@Controller
public class InterfaceController extends Base<String>
{
    @PostMapping(value = "/interface")
    @ResponseBody
    @Override
    public String request(
        @ModelAttribute("test_string") String _test_string,
        ModelAndView _mv)
    {
        System.out.println(_test_string);
        _test_string = "new value";

        return "whatever content";
    }
}
Gábor DANI
  • 2,063
  • 2
  • 22
  • 40

1 Answers1

3

I'm no Spring MVC expert but your problem seems to be understanding Java pass-by-reference and String inmutability. I've made a diagram to help you understand what the problem is but you may need to research more info about it.

Diagram

  1. When you invoke sysout, you are printing the value pointed by "_test_string" (method argument), that at this point is the same that ModelAttribute "test_string".

  2. When you assign "new value" to "_test_string" (method argument), notice that you're NOT changing the value of "test_string" (ModelAttribute)

  3. It's what I think you have to do to overwrite the value stored in the Model.

RubioRic
  • 2,442
  • 4
  • 28
  • 35
  • I think it's even have nothing to do with String `immutabilty` as the value is yet to be reassigned. – VPK Jan 22 '18 at 08:55
  • Ok, it makes sense. So if I must return a String (because I am rendering json with Gson), how do I update the Model? If not possible, then the less elegant way is to instead of String, return the updated ModelAndView, and pass the String Json to the view. How? I tried with the MappingJackson2JsonView and it renders the whole Model to Json which is not a good idea. – Gábor DANI Jan 22 '18 at 10:45
  • That's a different question. As I said, I'm no Spring MVC expert, sorry. But I don't undestand your new problem. If you need to pass a simple String between your controller and your view, you can use my point (3) statement or another similar approach. You can recover attribute "test_string" in your view. If you use Json to represent all your model, I guess that you can use some library to extract the specific data you need. – RubioRic Jan 22 '18 at 11:17