在我们日常项目开发过程中,往往会遇到前端请求参数中有空格的情况,前端提交后后端的字符串什么形式的都有(例: " xxx ", " xxxxx ", “”, “null” 等等),这样不对空格进行处理直接传参,不仅浪费空间,还会造成数据跟查询结果有出入的情况,引起很多不必要的麻烦。那么,怎么快速的去除前端传参中字符串类型参数的前后空格呢?
在开发过程中,后端接收前端的传参有两种方式:
对于 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));
}
}
对于使用 body 中的 JSON 或者 XML 的传参方式,在 Spring 中,默认是使用的 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());
}
});
};
}
}
对于上述的两种传参方式,我们优化一下,将两个合并成一个统一的类来进行实现;
package com.wblog.framework.config;
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;
/**
* 序列化处理前端请求数据的前后空格
* @author wangxk
* @date 2023-12-27
*/
@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 {
System.out.println("Jackson2ObjectMapperBuilderCustomizer jsonParser.getValueAsString() = " + jsonParser.getValueAsString());
return StringUtils.trimWhitespace(jsonParser.getValueAsString());
}
});
}
}
由于 Spring 启动时,是默认加载同级别目录下所有的 Bean,如果我们重写的 WebMvcStringTrimAutoConfiguration 类是在外部目录时,我们就需要手动去指定一下需要加载的类,在 resurces 下创建 META-INF/spring.factories 文件,将我们的类加到里面去:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.wblog.framework.config.WebMvcStringTrimAutoConfiguration
参考链接: