ModelAndView.addObject vs Model.addAttribute

前端 未结 1 1697
暗喜
暗喜 2021-02-04 19:30

Good day, I\'m learning Spring MVC and I\'m writting my tiny webapp following this tutorial but I slightly modified it as a \"list of tasks\" and not \"list of users\". One thin

1条回答
  •  离开以前
    2021-02-04 19:42

    You've hit an edge case that doesn't occur very often. Let's go by try

    @RequestMapping("/edit")  
    public String editTask(@RequestParam String id, Model model) {
        Task task = taskService.getTask(id);
        model.addAttribute("task", task);
        return "edit";
    }
    

    In this case, Spring will create a Model object from its ModelAndViewContainer and pass that as an argument to your method. So if you had model attributes added earlier, they would be available to you here and the ones you add in will be available later. You return a String view name. Spring will use that String with a ViewResolver to resolve which jsp or other type of view to render or forward to.

    With this

    @RequestMapping("/edit")  
    public ModelAndView editTask(@RequestParam String id, @ModelAttribute Task task) {  
        // Retrieve task from the database
        task = taskService.getTask(id);
        ModelAndView model = new ModelAndView("edit");
        model.addObject("task", task);
        return model;
    }
    

    Spring, because of the @ModelAttribute, will create a Task object and pass that as an argument when invoking (reflection) your method. The ModelAndView object you create, add to, and return will be merged with the ModelAndView object contained in the ModelAndViewContainer that is managed by Spring for your request. So things you add here will also be available later.

    The hitch: It appears ModelAttribute has priority on the model attributes, so it doesn't get overwritten by the model attributes you add to the ModelAndView object. Actually it gets written to your ModelAndView object, overwriting your "task" attribute. Remember that if you don't specify a value attribute to @ModelAttribute annotation, it uses the type of the argument to give it a name. For example, Task ==> "task", List ==> taskList, etc.

    0 讨论(0)
提交回复
热议问题