DomainClassConverter双重转换

时间:2015-07-09 15:13:13

标签: java spring model-view-controller

我试图在我的Spring MVC项目中使用Spring的DomainClassConverter功能。但我的控制器出了问题。 问题是我无法将表单的更改值更改为ModelAttribute。 例如:我的数据库中有对象User{id: 1, username: "user", pass: "111"},当我尝试将其修改为表单结束发布更改(User{id: 1, username: "user_changed", pass: "222"})到控制器时,我收到持久用户(没有更改)

@RequestMapping(method = RequestMethod.POST) public ModelAndView create(@ModelAttribute("user") @Valid User user, BindingResult bindingResultUser, ModelAndView model, WebRequest webRequest, Locale locale) {...}

经过一段时间的调试后,我找到了这种转换器行为的原因。

当ModelAttributeMethodProcessor尝试将绑定的用户对象转换为ModelAttribute时,

首先从此行开始:返回binder.convertIfNecessary(binder.getTarget(),parameter.getParameterType(),parameter);

@Override
public final Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
        NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {

    String name = ModelFactory.getNameForParameter(parameter);
    Object attribute = (mavContainer.containsAttribute(name) ?
            mavContainer.getModel().get(name) : createAttribute(name, parameter, binderFactory, webRequest));

    WebDataBinder binder = binderFactory.createBinder(webRequest, attribute, name);
    if (binder.getTarget() != null) {
        bindRequestParameters(binder, webRequest);
        validateIfApplicable(binder, parameter);
        if (binder.getBindingResult().hasErrors() && isBindExceptionRequired(binder, parameter)) {
            throw new BindException(binder.getBindingResult());
        }
    }

    // Add resolved attribute and BindingResult at the end of the model
    Map<String, Object> bindingResultModel = binder.getBindingResult().getModel();
    mavContainer.removeAttributes(bindingResultModel);
    mavContainer.addAllAttributes(bindingResultModel);

    return binder.convertIfNecessary(binder.getTarget(), parameter.getParameterType(), parameter);
}

然后,DataBinder-&gt;调用ConversionService-&gt; DomainClassConverter转换User对象以将其转换为ModelAttribute。 DomainConverter首先转换User-&gt; Id,然后返回User,此时用户正在重新读取数据库并丢失DataBinder所做的所有修改后的分配。

当我替换这行时,我解决了这个问题~~ if(sourceType.equals(targetType)){~~ to if(sourceType.getType()!= null&amp;&amp; sourceType.getType())。 equals(targetType.getType())){

    @Override
    public Object convert(Object source, TypeDescriptor sourceType, TypeDescriptor targetType) {

        if (source == null || !StringUtils.hasText(source.toString())) {
            return null;
        }

        if (sourceType.equals(targetType)) {
            return source;
        }

        Class<?> domainType = sourceType.getType();

        EntityInformation<Object, ?> entityInformation = repositories.getEntityInformationFor(domainType);

        return conversionService.convert(entityInformation.getId(source), targetType.getType());
    }

理论上我们必须比较TypeDescriptors类型。或者我错了?

0 个答案:

没有答案