SpringBoot 自定义ConfigurableWebBindingInitializer(可配置web初始化绑定器)

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攻击)
            //HtmlUtils.htmlEscape 默认的是ISO-8859-1编码格式,会将中文的某些符号进行转义。
            //如果不想让中文符号进行转义请使用UTF-8的编码格式。例如:HtmlUtils.htmlEscape(text.trim(), "UTF-8")
            setValue(HtmlUtils.htmlEscape(text.trim()));
        } else {
            //HTML转义(防止XSS攻击)
            //HtmlUtils.htmlEscape 默认的是ISO-8859-1编码格式,会将中文的某些符号进行转义。
            //如果不想让中文符号进行转义请使用UTF-8的编码格式。例如:HtmlUtils.htmlEscape(text, "UTF-8")
            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;
    }
}
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值