如何将spring @ModelAttribute与构建器模式一起使用

时间:2017-10-16 16:47:13

标签: java spring jsp spring-mvc builder-pattern

我是Builder Patterns的新手,并试图找到一种在Spring模型中使用Builder模式的方法。

我以前的模型有所有的setter和getter方法,我用Builder方法替换了,现在代码看起来像这样:

public class UserInterests {
    private final String user;
    private final int interestlevel;

    private UserInterests(UserInterestBuilder builder) {
        this.user = builder.user;
        this.interestlevel = builder.interestlevel;
    }

    public String getUser() {
        return user;
    }

    public static class UserInterestBuilder {
        private String user;
        private int interestlevel;

        public UserInterestBuilder() {
        }

        public UserInterestBuilder user(final String userId) {
            this.user = user;
            return this;
        }

        public UserInterestBuilder interestLevel(final int interestLevel) {
            this.interestLevel = interestLevel;
            return this;
        }

        public UserInterests build() {
            return new UserInterests(this);
        }
    }
}

以前,没有构建器,我从UI(jsp)获取用户兴趣级别,并将其绑定到UserInterests模型。在控制器中,我使用@ModelAttribute来获取UserInterests的实例并正在使用它。

Controller snippet:

@RequestMapping(value = "/addInterest", method = RequestMethod.POST)
public ModelAndView addUserInterest(
        @ModelAttribute(USER_INTEREST) UserInterests userInterests,
        BindingResult result, HttpSession session, ModelAndView model) {
//do something here
}

JSP片段

<html>
<head></head>
<body>
    <form:form modelAttribute="userInterests" action="addInterest" 
method="post">
<!-- Do more -->
</body>
</html>                         

但是,由于我将模型更改为使用构建器,因此我不能使用userInterests模型实例,因为它的构造函数是私有的。我可以使用request.getParameter()分别获取user和interestlevel值,并使用build绑定到userInterests模型。但有没有办法直接使用@ModelAttribute为构建器而必须单独获取值。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:0)

ModelAttribute注释由ModelAttributeMethodProcessor处理,属性通过数据绑定到Servlet请求参数填充。 Witthin DataBinder的内容是遵循实际执行绑定的方法

protected void applyPropertyValues(MutablePropertyValues mpvs) {
        try {
            // Bind request parameters onto target object.
            getPropertyAccessor().setPropertyValues(mpvs, isIgnoreUnknownFields(), isIgnoreInvalidFields());
        }
        catch (PropertyBatchUpdateException ex) {
            // Use bind error processor to create FieldErrors.
            for (PropertyAccessException pae : ex.getPropertyAccessExceptions()) {
                getBindingErrorProcessor().processPropertyAccessException(pae, getInternalBindingResult());
            }
        }
    }

查看BeanWrapperImpl哪个是最常见的属性访问器,除了JDK的标准PropertyEditors之外,它还具有从spring包中自动注册默认property editors的基本功能,所以基本上它完全链接到JavaBeans(基本上是属性及其具有特殊命名约定的访问者),这意味着它不支持任何其他样式,例如在你的案例Builder模式中。

答案 1 :(得分:0)

如果您真的想使用构建器注入UserInterests,您可以编写自己的HandlerMethodArgumentResolver来检查请求并使用UserInterestBuilder来提供UserInterests的实例。特别是,我发现有点强迫,通过使用Command或Form对象将参数绑定到对象来创建对象,可以使这种情况更加简单。