SpringBoot中自定义ConfigurableWebBindingInitializer的原因之一有如下:
1、可自定义属性编辑器(PropertyEditor)
一、SpringBoot为什么可以将我们自定义的ConfigurableWebBindingInitializer自动装配到SpringMVC中,下面是SpringBoot部分源码
/*
* WebMvcAutoConfiguration中有如下代码表示如果spring容器中存在ConfigurableWebBindingInitializer类,
* 则取Spring容器中的这个类,如果spring容器中不存在则调用WebMvcConfigurationSupport类中的
* getConfigurableWebBindingInitializer()方法获取
*/
protected ConfigurableWebBindingInitializer getConfigurableWebBindingInitializer() {
try {
return (ConfigurableWebBindingInitializer)this.beanFactory.getBean(ConfigurableWebBindingInitializer.class);
} catch (NoSuchBeanDefinitionException var2) {
return super.getConfigurableWebBindingInitializer();
}
}
二、实现自定义属性编辑器
1、字符编辑器,将字符进行HTML转义(防止XSS攻击)
import org.springframework.web.util.HtmlUtils;
import java.beans.PropertyEditorSupport;
/**
* web 字符串编辑器,将字符进行HTML转义(防止XSS攻击)
* @see org.springframework.beans.propertyeditors.StringTrimmerEditor
*/
public class StringEditor extends PropertyEditorSupport {
/** 是否将空字符串转换为null */
private final boolean emptyAsNull;
/** 是否去掉前后空格 */
private final boolean trimmed;
public StringEditor() {
this(true, true);
}
public StringEditor(boolean emptyAsNull, boolean trimmed) {
this.emptyAsNull = emptyAsNull;
this.trimmed = trimmed;
}
@Override
public String getAsText() {
return getValue() != null ? (String) getValue() : null;
}
@Override
public void setAsText(String text) throws IllegalArgumentException {
if (text == null) {
setValue(null);
} else if (emptyAsNull && text.isEmpty()) {
setValue(null);
} else if (trimmed) {
//HTML转义(防止XSS攻击)
setValue(HtmlUtils.htmlEscape(text.trim()));
} else {
//HTML转义(防止XSS攻击)
setValue(HtmlUtils.htmlEscape(text));
}
}
}
2、日期编辑器,可将String参数转换成Date
import org.apache.commons.lang3.time.DateUtils;
import java.beans.PropertyEditorSupport;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* Web - 日期编辑器
* @see org.springframework.beans.propertyeditors.CustomDateEditor
*/
public class DateEditor extends PropertyEditorSupport {
/** 是否将空字符串转换为null */
private final boolean emptyAsNull;
/** 日期格式数组 */
private final String[] datePatterns;
/** 日期编制器 */
private final DateFormat dateFormater;
public DateEditor() {
this(true, new String[]{"yyyy", "yyyy-MM", "yyyyMM", "yyyy/MM", "yyyy-MM-dd", "yyyyMMdd", "yyyy/MM/dd", "yyyy-MM-dd HH:mm:ss", "yyyyMMddHHmmss", "yyyy/MM/dd HH:mm:ss"}, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
}
public DateEditor(boolean emptyAsNull, String[] datePatterns, DateFormat dateFormater) {
this.emptyAsNull = emptyAsNull;
this.datePatterns = datePatterns;
this.dateFormater = dateFormater;
}
@Override
public String getAsText() {
return getValue() != null ? dateFormater.format((Date) getValue()) : null;
}
@Override
public void setAsText(String text) {
if (text == null) {
setValue(null);
} else if (emptyAsNull && text.isEmpty()) {
setValue(null);
} else {
try {
setValue(DateUtils.parseDate(text.trim(), datePatterns));
} catch (ParseException e) {
setValue(null);
}
}
}
}
三、自定义ConfigurableWebBindingInitializer
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.support.FormattingConversionService;
import org.springframework.validation.Validator;
import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
import java.util.Date;
/**
* 自定义Web绑定初始化器
* @see org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport 的getConfigurableWebBindingInitializer方法
*/
@Configuration
public class WebBindingInitializerConfiguration {
@Bean
public ConfigurableWebBindingInitializer configurableWebBindingInitializer(FormattingConversionService mvcConversionService, Validator mvcValidator) {
ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer();
initializer.setConversionService(mvcConversionService);
initializer.setValidator(mvcValidator);
//装配自定义属性编辑器
initializer.setPropertyEditorRegistrar(propertyEditorRegistry -> {
//PropertyEditors并不是线程安全的,对于每一个请求,我们都需要new一个PropertyEditor对象
propertyEditorRegistry.registerCustomEditor(String.class, new StringEditor());
propertyEditorRegistry.registerCustomEditor(Date.class, new DateEditor());
});
return initializer;
}
}
四、测试
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Date;
/**
* 自定义编辑器转换测试
*/
@RestController
@RequestMapping("/editor")
public class TestEditorController {
/**
* 字符串编辑器
* localhost:8080/editor?name={"A":"sdfawefa"}
* @param name 名称
* @return {"A":"sdfawefa"}
*/
@PostMapping
public String post(String name){
return name;
}
/**
* 日期编辑器
* localhost:8080/editor/date?date=2019-06-05
* @param date 日期
* @return "2019-06-04T16:00:00.000+0000"
*/
@PostMapping(value = "/date")
public Date date(Date date){
return date;
}
}