如下:
http://localhost:8080/user?type=1&key=&id=10231
后端接受到的key="",而非key=null。
再如下:
{
"name": "",
"origin": 0,
...
}
后端接受到的name="",而非name=null。
当然,最优的处理方式是前端处理,判断空白字符串就不要传递了,但是老项目了,前端全部去改来不及了,后续优化吧!
现提供后端统一处理方式,代码如下:
package com.china.system.config;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.Formatter;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Locale;
/**
* @author songjianyong
* @date 2021/08/31 15:58
* <p> 空格 转 NULL </p>
*/
@Configuration
public class WebMvcSerializationConfig implements WebMvcConfigurer {
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
// 仅适用实体类型的对象参数
converters.add(mappingJackson2HttpMessageConverter());
}
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addFormatterForFieldType(String.class, new Formatter<String>() {
@Override
public String print(String text, Locale locale) {
return StringUtils.trimToNull(text);
}
@Override
public String parse(String text, Locale locale) {
return StringUtils.trimToNull(text);
}
});
}
@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
SimpleModule simpleModule = new SimpleModule();
simpleModule.addDeserializer(String.class, new BlankStringToNull(String.class));
ObjectMapper mapper = new ObjectMapper();
//未知属性是否报错
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.registerModule(simpleModule);
//防止日期转成时间戳:1630463093355
//或使用注解 @JsonFormat(locale = "zh", timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
converter.setObjectMapper(mapper);
return converter;
}
public static class BlankStringToNull extends StdDeserializer<String> {
private static final long serialVersionUID = 7095734746386292457L;
protected BlankStringToNull(Class<String> vc) {
super(vc);
}
@Override
public String deserialize(JsonParser parser, DeserializationContext context) throws IOException {
return StringUtils.trimToNull(parser.getText());
}
}
}
或直接在原有的基础上注册Module,如下:
package com.china.system.config;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.Formatter;
import org.springframework.format.FormatterRegistry;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.io.IOException;
import java.util.List;
import java.util.Locale;
/**
* @author songjianyong
* @date 2021/08/31 15:58
* <p> 空格 转 NULL </p>
*/
@Configuration
public class WebMvcSerializationConfig implements WebMvcConfigurer {
@Override
public void addFormatters(FormatterRegistry registry) {
registry.addFormatterForFieldType(String.class, new Formatter<String>() {
@Override
public String print(String text, Locale locale) {
return StringUtils.trimToNull(text);
}
@Override
public String parse(String text, Locale locale) {
return StringUtils.trimToNull(text);
}
});
}
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
SimpleModule simpleModule = new SimpleModule();
simpleModule.addDeserializer(String.class, new BlankStringToNull(String.class));
for (HttpMessageConverter<?> converter : converters) {
if (converter instanceof MappingJackson2HttpMessageConverter) {
ObjectMapper mapper = ((MappingJackson2HttpMessageConverter) converter).getObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.registerModule(simpleModule);
}
}
}
public static class BlankStringToNull extends StdDeserializer<String> {
private static final long serialVersionUID = 7095734746386292457L;
protected BlankStringToNull(Class<String> vc) {
super(vc);
}
@Override
public String deserialize(JsonParser parser, DeserializationContext context) throws IOException {
return StringUtils.trimToNull(parser.getText());
}
}
}