我试图在我的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类型。或者我错了?