这节来说springboot中的初始化参数配置,使用过SSM的都知道,springmvc中的初始化参数配置是可以通过@InitBinder来实现参数初始化配置,
示例:以去除字符串前后空格为例:
package com.osy.config;
import com.osy.editorregistrar.ZyDateEditor;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;
import java.util.Date;
@ControllerAdvice
public class MyControllerAdvice {
@InitBinder
public void initBinder(WebDataBinder webDataBinder) {
webDataBinder.registerCustomEditor(String.class,new StringTrimmerEditor(true));
}
}
这种原来就是通过切面的形式,在进行参数绑定之前,把前后空格去除,
还有一种方式就是针对某个controller的,将下面这段写在需要去除的controller中即可。
@InitBinder
public void initBinder(WebDataBinder webDataBinder) {
webDataBinder.registerCustomEditor(String.class,new StringTrimmerEditor(true));
}
这样在springboot中也是适用的,
那么ConfigurableWebBindingInitializer类也是为了进行初始话配置的,springboot设计出这个应该是为了迎合springboot的一些设计理念,这里就不升入研究,来说一下这么使用吧!
Spring MVC使用a WebBindingInitializer来初始化WebDataBinder特定请求。如果创建自己的ConfigurableWebBindingInitializer @Bean,Spring Boot会自动将Spring MVC配置为使用它。
上面这段话是官方文档对其的解释,看得我一脸懵逼,能大概知道的就是通过注解@Bean来注入 ConfigurableWebBindingInitializer 对象,那么跟着做一把:(网上搜了一把,大部分都是这样的,)
package com.osy.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
@Configuration
public class WebBindConfig {
@Bean
public ConfigurableWebBindingInitializer getConfigurableWebBindingInitializer() {
ConfigurableWebBindingInitializer configurableWebBindingInitializer = new ConfigurableWebBindingInitializer();
return configurableWebBindingInitializer;
}
}
照做之后发现什么变化都没有,然后仔细思考了一下,需要做什么操作,传什么参数进行配置,什么都没有,就创建一个示例,他能干嘛,诸多疑问,于是,就去看了一下他的源码。看到了这么一个属性:
@Nullable
private PropertyEditorRegistrar[] propertyEditorRegistrars;
这不就是属性编辑注册器吗,然后又看到初始化绑定的方法
@Override
public void initBinder(WebDataBinder binder) {
binder.setAutoGrowNestedPaths(this.autoGrowNestedPaths);
if (this.directFieldAccess) {
binder.initDirectFieldAccess();
}
if (this.messageCodesResolver != null) {
binder.setMessageCodesResolver(this.messageCodesResolver);
}
if (this.bindingErrorProcessor != null) {
binder.setBindingErrorProcessor(this.bindingErrorProcessor);
}
if (this.validator != null && binder.getTarget() != null &&
this.validator.supports(binder.getTarget().getClass())) {
binder.setValidator(this.validator);
}
if (this.conversionService != null) {
binder.setConversionService(this.conversionService);
}
if (this.propertyEditorRegistrars != null) {
for (PropertyEditorRegistrar propertyEditorRegistrar : this.propertyEditorRegistrars) {
propertyEditorRegistrar.registerCustomEditors(binder);
}
}
}
最下面循环属性编辑注册器,然后将binder注册进去,这一下就明白了,我们只需要传入相对应的注册器进去就可以了。然后他提供了两个方法:
public final void setPropertyEditorRegistrar(PropertyEditorRegistrar propertyEditorRegistrar) {
this.propertyEditorRegistrars = new PropertyEditorRegistrar[] {propertyEditorRegistrar};
}
public final void setPropertyEditorRegistrars(@Nullable PropertyEditorRegistrar[] propertyEditorRegistrars) {
this.propertyEditorRegistrars = propertyEditorRegistrars;
}
上面是传入单个注册器,下面是传入注册器的数组,(PS:为什么不加一个可变参数的方法呢?非得写一个数组,让我很不适)
注册器PropertyEditorRegistrar是一个接口,我们创建StringPropertyEditorRegistrar去实现他,然后实现其方法:
package com.osy.editorregistrar;
import org.springframework.beans.PropertyEditorRegistrar;
import org.springframework.beans.PropertyEditorRegistry;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
public class StringPropertyEditorRegistrar implements PropertyEditorRegistrar {
@Override
public void registerCustomEditors(PropertyEditorRegistry registry) {
// 将StringTrimmerEditor注册进去
registry.registerCustomEditor(String.class,new StringTrimmerEditor(true));
}
}
顺便也写了一个字符串映射到Date对象上面的注册器
package com.osy.editorregistrar;
import org.springframework.beans.PropertyEditorRegistrar;
import org.springframework.beans.PropertyEditorRegistry;
import java.util.Date;
public class DatePropertyEditorRegistrar implements PropertyEditorRegistrar {
@Override
public void registerCustomEditors(PropertyEditorRegistry registry) {
// ZyDateEditor需要继承PropertyEditorSupport ,重写setAsText方法
registry.registerCustomEditor(Date.class,new ZyDateEditor());
}
}
package com.osy.editorregistrar;
import java.beans.PropertyEditorSupport;
import java.text.ParseException;
import java.text.SimpleDateFormat;
public class ZyDateEditor extends PropertyEditorSupport {
// ZyDateEditor需要继承PropertyEditorSupport ,重写setAsText方法
@Override
public void setAsText(String text) throws IllegalArgumentException {
if (text == null) {
setValue(null);
} else {
String date = text.trim();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
try {
setValue(simpleDateFormat.parse(date));
} catch (ParseException e) {
e.printStackTrace();
}
}
}
}
最后我们将两个注册器设置进去:
package com.osy.config;
import com.osy.editorregistrar.DatePropertyEditorRegistrar;
import com.osy.editorregistrar.StringPropertyEditorRegistrar;
import org.springframework.beans.PropertyEditorRegistrar;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
@Configuration
public class WebBindConfig {
@Bean
public ConfigurableWebBindingInitializer getConfigurableWebBindingInitializer() {
ConfigurableWebBindingInitializer configurableWebBindingInitializer = new ConfigurableWebBindingInitializer();
configurableWebBindingInitializer.setPropertyEditorRegistrars(
new PropertyEditorRegistrar[]{new StringPropertyEditorRegistrar(), new DatePropertyEditorRegistrar()});
return configurableWebBindingInitializer;
}
}
最后达到的效果和
@ControllerAdvice+@InitBinder实现的效果一致,个人觉得@ControllerAdvice+@InitBinder实现起来非常方便的,但是不知道springboot为什么弄了这么一个类出来,并且轻描淡写的一笔带过,只有我这么不甘心的人才这么深入的去探索他,不然在网上找了一堆,也找不到重点的。难受!!!
PC:通过@ControllerAdvice+@InitBinder来自定义绑定的话,也需要继承PropertyEditorSupport类,重写 setAsText方法。