java - 在方法参数上使用 @ModelAttribute

标签 java spring-mvc

如本节所述 link下节 在方法参数上使用@ModelAttribute

An @ModelAttribute on a method argument indicates the argument should be retrieved from the model.

但我观察到,即使没有使用 @ModelAttribute 注释 UserDetail,userDetail 也会正确填充。这是相关的代码片段

<form:form id="userForm" action="path/userDetail" method="post" commandName="userDetail">

    @RequestMapping(value="/userDetail", method=RequestMethod.POST)
    public String processUserDetail(UserDetail userDetail, HttpServletRequest request, HttpServletResponse response, Locale locale) 
    {}

所以我的问题确实是 spring 本身填充了处理程序方法参数中存在的项目自定义对象(在本例中为 userDetail) 即使不注释 @ModelAttribute。我相信@ModelAttribute 在呈现 View 时发挥作用,但在提交 Spring 时发挥作用 如果方法参数存在于模型中,则自动填充方法参数?

最佳答案

即使不注释@ModelAttribute,处理程序方法也会解析参数吗?

是的,但是 @ModelAttribute 改变的是发生适当解析的点。框架在参数解析过程中所做的是它获取每个参数并遍历已注册的解析器列表,一旦找到支持该参数的第一个解析器,它就会解析它并移动到下一个参数。

处理模型属性的解析器是ServletModelAttributeMethodProcessor .它被注册了两次,第一次只扫描用@ModelAttribute 注释的参数,第二次作为列表中的最后一次,即使没有注释也解析参数。

您可以通过检查 RequestMappingHandlerAdapter 的来源来检查解析器的列表和顺序。 .注意 ServletModelAttributeMethodProcessor 的两个注册, true/false 参数决定注解是否强制

private List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() {
    List<HandlerMethodArgumentResolver> resolvers = new ArrayList<HandlerMethodArgumentResolver>();

    // Annotation-based argument resolution
    resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false));
    resolvers.add(new RequestParamMapMethodArgumentResolver());
    resolvers.add(new PathVariableMethodArgumentResolver());
    resolvers.add(new PathVariableMapMethodArgumentResolver());
    resolvers.add(new MatrixVariableMethodArgumentResolver());
    resolvers.add(new MatrixVariableMapMethodArgumentResolver());
    resolvers.add(new ServletModelAttributeMethodProcessor(false));
    resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters()));
    resolvers.add(new RequestPartMethodArgumentResolver(getMessageConverters()));
    resolvers.add(new RequestHeaderMethodArgumentResolver(getBeanFactory()));
    resolvers.add(new RequestHeaderMapMethodArgumentResolver());
    resolvers.add(new ServletCookieValueMethodArgumentResolver(getBeanFactory()));
    resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory()));

    // Type-based argument resolution
    resolvers.add(new ServletRequestMethodArgumentResolver());
    resolvers.add(new ServletResponseMethodArgumentResolver());
    resolvers.add(new HttpEntityMethodProcessor(getMessageConverters()));
    resolvers.add(new RedirectAttributesMethodArgumentResolver());
    resolvers.add(new ModelMethodProcessor());
    resolvers.add(new MapMethodProcessor());
    resolvers.add(new ErrorsMethodArgumentResolver());
    resolvers.add(new SessionStatusMethodArgumentResolver());
    resolvers.add(new UriComponentsBuilderMethodArgumentResolver());

    // Custom arguments
    if (getCustomArgumentResolvers() != null) {
        resolvers.addAll(getCustomArgumentResolvers());
    }

    // Catch-all
    resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true));
    resolvers.add(new ServletModelAttributeMethodProcessor(true));

    return resolvers;
}

关于java - 在方法参数上使用 @ModelAttribute,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27589520/

相关文章:

java - Spring 4推荐更换JpaTemplate

java - 避免 Java/Servlet Web 堆栈中的 IllegalStateException

Java 内存解释 (SUN JVM)

java - 如何使用 Hibernate 和 spring MVC 在 Jsp 页面上显示数据库中的图像

java - Springboot请求方法 'POST'不支持

java - spring-data-redis 与 Spring 3 兼容吗?

java - 更改项目类型

java - 向特定服务发送 SOAP 请求

java - 在 java 中访问已经引用的 bean Spring mvc 中的 bean 时出现空指针异常

java - Spring boot + gradle 将命令行参数传递给 application.property