1. @InitBinder作用
在springmvc的controller层可以定义用@InitBinder注解的方法,如下:
@InitBinder
public void initBinder(WebDataBinder binder) throws Exception {
binder.registerCustomEditor(Long.class, new CustomNumberEditor(Long.class, true));
binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
}
如上方法initBinder被@InitBinder注解,initBinder方法里的参数WebDataBinder可以注册我们自定义的属性编辑器PropertyEditor,属性编辑器为我们把一种类型转成另一种类型,如:binder.registerCustomEditor(Long.class, new CustomNumberEditor(Long.class, true));里第一个参数表示要转换的类型为Long.class,通过第二个参数把Long.class类型转成我们想要的类型。具体自定义属性编辑器怎么定义请自行百度。
在@InitBinder注解的方法里注册的属性编辑器会通过beanWrapper进行注册,beanWrapper继承PropertyEditorRegistrySupport,PropertyEditorRegistrySupport主要成员变量如下:
@Nullable
private ConversionService conversionService;//可以注入,通过getConversionService()方法获取。
private boolean defaultEditorsActive = false;//为true,getDefaultEditor()方法才会注册默认提供的属性编辑器。
private boolean configValueEditorsActive = false;//为true会为String[].class,short[].class,int[].class,long[].class注册一个StringArrayPropertyEditor
@Nullable
private Map, PropertyEditor> defaultEditors;//默认属性编辑器的容器
@Nullable
private Map, PropertyEditor> overriddenDefaultEditors;//用于覆盖默认属性编辑器
@Nullable
private Map, PropertyEditor> customEditors;//自定义属性编辑器
@Nullable
private Map customEditorsForPath;//带path的
其中
则得出结论:通过@InitBinder注解的方法注册的自定义属性编辑器会被放进Map类型的customEditors里,以备我们自己使用。
2.webDataBinder作用
webDataBinder是用来给bean属性赋值的,还提供“属性访问器”、“验证器”、“类型转换”、“国际化”等功能。
我的controller中方法里的参数接收的前端参数都是字符串类型的,我们的方法中的参数却有java的各种类型,这时再为参数赋值时就要先把入参类型进行转成方法中的参数类型,再入参值赋值到对应的方法参数中。在spring中进行参数类型转换的是参数解析器,拿ModelAttributeMethodProcessor参数解析器举例,其解析方法如下:
public final Object resolveArgument(
MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest request, WebDataBinderFactory binderFactory)
throws Exception {
String name = ModelFactory.getNameForParameter(parameter);
Object target = (mavContainer.containsAttribute(name)) ?
mavContainer.getModel().get(name) : createAttribute(name, parameter, binderFactory, request);
WebDataBinder binder = binderFactory.createBinder(request, target, name);//在创建WebDataBinder对象时则可以从binder中取转换成对象
if (binder.getTarget() != null) {
bindRequestParameters(binder, request);
validateIfApplicable(binder, parameter);
if (binder.getBindingResult().hasErrors()) {
if (isBindExceptionRequired(binder, parameter)) {
throw new BindException(binder.getBindingResult());
}
}
}
mavContainer.addAllAttributes(binder.getBindingResult().getModel());
return binder.getTarget();
}
参考:https://blog.csdn.net/hongxingxiaonan/article/details/50282001
https://blog.csdn.net/roberts939299/article/details/73824201
https://www.cnblogs.com/w-y-c-m/p/8443892.html
https://blog.csdn.net/shenchaohao12321/article/details/80356890
https://www.cnblogs.com/sonng/archive/2017/04/02/6658825.html
https://blog.csdn.net/qq_38016931/article/details/82080940
https://blog.csdn.net/zxfryp909012366/article/details/82923061