在实际的开发过程中,经常会使用String类型的参数,而用户提交给后端的字符串可以说五花八门:""," “,” 123456","123456 “,”  123456 " 等等。如果不对这些空格进行处理,不仅会浪费存储空间,还会引起一些不必要的麻烦。

接收String类型的参数通常两种方式:

①.使用url或者form表单的形式
对于这种情况,我们在参数绑定时注册下面的类即可:

@RestControllerAdvice
public class GlobalHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(GlobalHandler.class);

    /**
     *  url和form表单中的参数trim
     *
     * @param binder
     */
    @InitBinder
    public void initBinder(WebDataBinder binder) {
        // 构造方法中 boolean 参数含义为如果是空白字符串, 是否转换为 null
        // 即如果为 true, 那么 "" 会被转换为 null, 否者为""
        binder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
    }
}

②.接收Request BodyJSONXML对象参数
Spring MVC默认使用 Jackson 对参数进行反序列化,所以对Jackson加入如下自定义转换器即可:

@Configuration
public class ApplicationConfig {

    /**
     * Request Body中JSON或XML对象参数trim
     *
     * @return
     */
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        return jacksonObjectMapperBuilder -> {
            // 时区问题
            jacksonObjectMapperBuilder.timeZone(TimeZone.getDefault());
            jacksonObjectMapperBuilder.deserializerByType(String.class, new StdScalarDeserializer<String>(String.class) {
                @Override
                public String deserialize(JsonParser jsonParser, DeserializationContext ctx)
                        throws IOException {
                    // 去除前后空格
                    return StringUtils.trimWhitespace(jsonParser.getValueAsString());
                }
            });
        };
    }
}
优化

对于这种所有项目都需要的通用配置,我们应该抽取一个公共模块,然后通过引入依赖来实现自动配置

common模块下创建自动配置类 WebMvcStringTrimAutoConfiguration

package com.zzs.common.autoconfigure;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.servlet.DispatcherServlet;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.servlet.Servlet;
import java.io.IOException;

@Configuration
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
@AutoConfigureAfter(WebMvcAutoConfiguration.class)
public class WebMvcStringTrimAutoConfiguration {

    @ControllerAdvice
    public static class ControllerStringParamTrimConfig {

        /**
         * url和form表单中的参数trim
         */
        @InitBinder
        public void initBinder(WebDataBinder binder) {
            // 构造方法中 boolean 参数含义为如果是空白字符串,是否转换为null
            // 即如果为true,那么 " " 会被转换为 null,否者为 ""
            StringTrimmerEditor stringTrimmerEditor = new StringTrimmerEditor(false);
            binder.registerCustomEditor(String.class, stringTrimmerEditor);
        }
    }

    /**
     * Request Body中JSON或XML对象参数trim
     */
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        return jacksonObjectMapperBuilder -> jacksonObjectMapperBuilder
                .deserializerByType(String.class, new StdScalarDeserializer<String>(String.class) {
                    @Override
                    public String deserialize(JsonParser jsonParser, DeserializationContext ctx)
                            throws IOException {
                        return StringUtils.trimWhitespace(jsonParser.getValueAsString());
                    }
                });
    }
}

然后在 resurces 创建 META-INF/spring.factories 文件

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.zzs.common.autoconfigure.WebMvcStringTrimAutoConfiguration
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐