【问题标题】:Return types in Spring MVCSpring MVC 中的返回类型
【发布时间】:2014-01-13 11:37:17
【问题描述】:

我是 Spring MVC 的新手,正在尝试从 Spring MVC Docs 学习概念:

一个 ModelAndView 对象,模型隐含地丰富了命令 对象和@ModelAttribute 注释的引用数据的结果 访问器方法。

有人可以帮助我理解这一点吗? “模型隐含地丰富了命令对象”以及“@ModelAttribute 注释引用数据访问器方法的结果”是什么意思?

一个模型对象,其视图名称通过 RequestToViewNameTranslator 和隐含丰富的模型 命令对象和@ModelAttribute 注释引用的结果 数据访问器方法。

这里的Spring是如何确定视图名的?

用于公开模型的 Map 对象,隐含视图名称 通过 RequestToViewNameTranslator 和模型确定 隐含地丰富了命令对象和结果 @ModelAttribute 注解的引用数据访问器方法。

这里也是这样,视图名是怎么确定的?

【问题讨论】:

    标签: java spring-mvc


    【解决方案1】:

    Q1:“模型隐含地丰富了命令对象和@ModelAttribute 注释引用数据访问器方法的结果”是什么意思?

    Here 你可以看到,“模型是一个 Map,允许使用多个按名称键入的对象”。我们可以在视图页面中通过它们的名称从模型中检索这些对象。

    我们通常希望在视图页面中传递命令对象或引用数据,并通过使用上述将它们放入模型对象的机制将它们传递给视图。

    我们可以通过将@ModelAttribute 注释添加到任何引用数据或命令(或其访问者)来显式地将对象放入模型中并隐式地放入。除此之外,我们在请求服务方法中使用的不带@ModelAttribute 标记的命令对象也会自动添加到模型中。

    例如看下面的代码块:

    @ModelAttribute
    public getSchool(){ //implicitly added to model by invoking this getter
       return new School();
    }
    
    @RequestMapping("/saveStudent.html")
    public ModelAndView saveStudent(ClassRoom classRoom, // implicitly added to model
                                    @ModelAttribute Student student, // implicitly added to model
                                    Model model) {
    
        model.addAttribute("abc", new Abc()); //explicitly added to model
        return new ModelAndView("myView", model);
    }
    

    当您尝试从视图中分别按名称“school”、“classRoom”、“student”、“abc”获取对象时,您将获得这些对象的引用,因为这些对象已添加到您的模型中。

    Q2 & Q3:当我们没有在控制器方法的返回类型中明确提及视图名称时,视图名称是如何确定的

    Spring 总是更喜欢约定而不是配置。有一个名为RequestToViewNameTranslator 的bean。当您没有明确提及视图名称时,RequestToViewNameTranslator 从请求的 URL 生成逻辑视图名称。假设您的请求 url 是 /home.html 并且您没有从控制器中提及任何视图名称,然后 RequestToViewNameTranslator 生成一个逻辑视图名称 "home" 并尝试解析它。 Here你会发现它更详细。

    感谢和愉快的编码!

    【讨论】:

      【解决方案2】:

      “模型隐含地丰富了命令对象”是什么意思 以及“@ModelAttribute 注释参考数据的结果 访问器方法”?

      Command 对象是 Spring 根据请求参数创建的对象。换句话说,假设你有

      public ModelAndView doSomething(SomeFoo foo, @ModelAttribute SomeBar bar) {
          return new ModelAndView("view-name");
      }
      

      Spring 将隐式添加对象foobar 引用返回的ModelAndView。请注意,虽然SomeFoo 没有用@ModelAttribute 注释,但Spring 仍将其视为模型属性。您必须查看 HandlerMethodArgumentResolver 才能了解原因。

      您还可以使用@ModelAttribute 注释方法,这些方法将被调用,并且在您的方法所在的@Controller 处理的每个请求上,创建的对象将添加到Model。这就是results of @ModelAttribute annotated reference data accessor methods 的含义.

      这里的Spring是如何确定视图名的?

      它准确地告诉你它是如何确定的:它使用RequestToViewNameTranslator,默认是DefaultRequestToViewNameTranslator。阅读 javadoc 了解更多详情。

      这里也是这样,视图名是怎么确定的?

      同上。


      为了回答您评论中的问题,Spring 注册了许多 HandlerMethodArgumentResolver 实例来解析要传递给您的 @RequestMapping 注释方法的参数。它以特定顺序注册它们,优先考虑特定类型的参数,如ModelModelMapModelAndView 等,然后是注释参数(例如,@PathVariable@RequestParam 等的处理程序)。然后 Spring 遍历这个列表并使用它找到的第一个可以处理参数的列表。

      其中一个HandlerMethodArgumentResolverServletModelAttributeMethodProcessor,它处理@ModelAttribute 注释参数。 Spring 记录了其中的两 (2) 个。一种用于实际使用@ModelAttribute 注释的参数,另一种用于未注释的参数。这样你就可以注入你自己的HandlerMethodArgumentResolver 来处理你的参数。

      HandlerMethodArgumentResolver的注册顺序

      ...
      ServletModelAttributeMethodProcessor for @ModelAttribute annotated parameters
      ...
      your own HandlerMethodArgumentResolver
      ...
      ServletModelAttributeMethodProcessor for parameters not annotated with ModelAttribute
      

      【讨论】:

      • 谢谢 Sotirios,你能告诉我这里的 foo 和 bar 有什么区别吗?我的意思是,通过将 ModelAttribute 注释添加到方法参数中,我们可以获得什么好处吗?我了解 foo 和 bar 对象将根据请求参数填充,如果正确,请告诉我。可能这些都是简单的问题,但由于我是 Spring MVC 的新手,所以我有点困惑。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-11-15
      • 2013-09-07
      • 2017-03-13
      • 1970-01-01
      • 1970-01-01
      • 2013-06-12
      • 2012-02-15
      相关资源
      最近更新 更多