Good day. I am learning Spring on the sly and faced with strangeness when the controller method works:
@ModelAttribute("status") public String getStatus() { return dao.pullStatus(); } This method sets the value of the field of the model that should store the status of the operation ("completed" or "not completed"). This value is taken from the laststatus dao field of the object. The application should work like this:
Go to the page http: // localhost: 8084 / JPAsample /
On it is the command execution button (a piece of listalldata.jsp):
<form action="showCat.do"> <input type="submit" value="Показать кошку по ID: "/> <input name="id" /> </form> The corresponding controller method works:
@RequestMapping("showCat.do") public ModelAndView showOne(long id) { c = dao.getCatById(id); ModelAndView mv = new ModelAndView("listalldata"); return mv; } The getCatById (id) method will either find an entry in the database or not. Depending on this, laststatus will be = "completed" or "not completed" respectively.
Element:
<div class="status">${status}</div> displays the word "completed" or "not done."
In practice, the inscription on the status of the operation changes after the second click on the button "Show cat by ID:". For example, I want to find a cat by id, which is not in the database. Initially, the status is empty. I press "show", the status remains empty. Once again I press "show", but already with id, which is in the database. But the status becomes "not fulfilled". Those. The status is updated with a delay in one step.
What is interesting, if you distort and cut the controller method into two parts like this:
@RequestMapping("showCat.do") public String showOne(long id) { c = dao.getCatById(id); return "redirect:showCatPart2.do"; } @RequestMapping("showCatPart2.do") public ModelAndView showOneP2() { ModelAndView mv = new ModelAndView("listalldata"); return mv; } Information about the status of implementation becomes relevant. Please help me figure it out.
Update.
Tried to add the status in ModelAndView manually. In the following way:
Option 1:
@RequestMapping("showCat.do") public ModelAndView showOne(long id) { c = dao.getCatById(id); ModelAndView mv = new ModelAndView("listalldata"); mv.addObject("cats", Collections.singletonList(c)); mv.addObject("status"); return mv; } Option 2:
@RequestMapping("showCat.do") public ModelAndView showOne(@ModelAttribute("status") String status, long id) { c = dao.getCatById(id); ModelAndView mv = new ModelAndView("listalldata"); mv.addObject("cats", Collections.singletonList(c)); mv.addObject("status", status); return mv; } The result is the same.
The description of the mechanism of work of the @ModelAttribute method was found in the question in the English "stack" and in this blog . It turns out the controller's method with the annotation @ModelAttribute is called each time before calling the @RequestMapping method. This means that the controller first accesses the dao object and reads the status from the field, and then calls the showOne (id) method to search the database and change the status of the operation. But the model does not get a changed status, but one that was considered before the showOne (id) method was executed. This explains the late status update in one step, and why splitting the method into two parts showOne (id) solves the problem.
But then another question arises: Is such a decision "cultural"? Perhaps there is a more elegant way.