前后端交互时将返回值中的null置为空字符串的8种方式(FastJson、Jackson等)
返回给前端的Json对象中有很多字段没有值,就会有很多的null值(如下图)
前端判断处理会比较麻烦,所以打算在后端回传数据时做一下处理:
1、字符串null值置为空字符串
2、空List转为[]
3、封装数字类型null转为0
4、Boolean类型null转为false
先看想要达到的效果:
一、通过继承WebMvcConfigurationSupport,重写configureMessageConverters方法实现
@Configuration
public class MyJsonConfig extends WebMvcConfigurationSupport {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();
FastJsonConfig config = new FastJsonConfig();
config.setSerializerFeatures(
//json格式输出
SerializerFeature.PrettyFormat,
// 保留map为空的字段
SerializerFeature.WriteMapNullValue,
// 将String类型的null转成""形式
SerializerFeature.WriteNullStringAsEmpty,
// 将Number类型的null转成0
SerializerFeature.WriteNullNumberAsZero,
// 将List类型的null转成[],而不是""
SerializerFeature.WriteNullListAsEmpty,
// Boolean类型的null转成false
SerializerFeature.WriteNullBooleanAsFalse,
// 处理可能循环引用的问题
SerializerFeature.DisableCircularReferenceDetect);
converter.setFastJsonConfig(config);
converter.setDefaultCharset(StandardCharsets.UTF_8);
List<MediaType> mediaTypeList = new ArrayList<>();
mediaTypeList.add(MediaType.APPLICATION_JSON);
converter.setSupportedMediaTypes(mediaTypeList);
converters.add(converter);
}
}
二、通过实现WebMvcConfigurer,重写configureMessageConverters方法实现
@Configuration
public class BaseMvcConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = new ObjectMapper();
/**
* 序列换成Json时,将所有的Long变成String
* 因为js中得数字类型不能包括所有的java Long值
*/
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
// 所有的double类型返回保留三位小数
simpleModule.addSerializer(Double.class, CustomerDoubleSerialize.instance);
simpleModule.addSerializer(Double.TYPE, CustomerDoubleSerialize.instance);
objectMapper.registerModule(simpleModule);
jackson2HttpMessageConverter.setObjectMapper(objectMapper);
converters.add(jackson2HttpMessageConverter);
}
}
三、在Springboot启动类中注入Bean---FastJson
@Bean
public HttpMessageConverters fastJsonConverters() {
FastJsonHttpMessageConverter4 fastConverter = new FastJsonHttpMessageConverter4();
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat, SerializerFeature.IgnoreNonFieldGetter,
SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullStringAsEmpty);
fastConverter.setFastJsonConfig(fastJsonConfig);
List supportedMediaTypes = new ArrayList();
supportedMediaTypes.add(new MediaType("text", "json", Charset.forName("utf8")));
supportedMediaTypes.add(new MediaType("application", "json", Charset.forName("utf8")));
fastConverter.setSupportedMediaTypes(supportedMediaTypes);
HttpMessageConverter<?> converter = fastConverter;
return new HttpMessageConverters(converter);
}
四、在Springboot启动类中注入Bean---Jackson
@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
List<MediaType> supported = new ArrayList<>();
supported.add(MediaType.APPLICATION_JSON_UTF8);
mappingJackson2HttpMessageConverter.setSupportedMediaTypes(supported);
// JsonMapper
ObjectMapper objectMapper = new ObjectMapper();
// null值的处理,必须要放在第一步,否则会将下面的日期格式化覆盖掉 null ==> ""
objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
@Override
public void serialize(Object value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeString("");
}
});
// 处理默认日期格式化:yyyy-MM-dd HH:mm:ss
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
mappingJackson2HttpMessageConverter.setObjectMapper(objectMapper);
return mappingJackson2HttpMessageConverter;
}
五、使用fastjson的toJSONString方式
/**
* @Description: 将java对象的null值置空,转成JSON对象
* @Parameters: Object 任意java对象
* @Return: JSONObject 返回fastjson的JSON对象
* @Auther: WZH
* @Date: 2021/1/15 9:54
*/
public static JSONObject nullToEmptyJson(Object object){
String returnString = JSONObject.toJSONString(object,
//json格式输出
SerializerFeature.PrettyFormat,
// 保留map为空的字段
SerializerFeature.WriteMapNullValue,
// 将String类型的null转成""形式
SerializerFeature.WriteNullStringAsEmpty,
// 将Number类型的null转成0
SerializerFeature.WriteNullNumberAsZero,
// 将List类型的null转成[],而不是""
SerializerFeature.WriteNullListAsEmpty,
// Boolean类型的null转成false
SerializerFeature.WriteNullBooleanAsFalse,
// 处理可能循环引用的问题
SerializerFeature.DisableCircularReferenceDetect);
return JSONObject.parseObject(returnString);
}
六、通过反射判断修改(可根据需要补全其他类型)
public static <T> void nullToEmpty(T bean){
Field[] field = bean.getClass().getDeclaredFields();
//遍历所有属性
for (Field item : field) {
//获取属性的名字
String name = item.getName();
//将属性的首字符大写,方便构造get,set方法
name = name.substring(0, 1).toUpperCase() + name.substring(1);
//获取属性的类型
String type = item.getGenericType().toString();
//如果type是类类型,则前面包含"class ",后面跟类名
if ("class java.lang.String".equals(type)) {
try {
Method mGet = bean.getClass().getMethod("get" + name);
//调用getter方法获取属性值
String value = (String) mGet.invoke(bean);
if (value == null || "".equals(value)) {
Method mSet = bean.getClass().getMethod("set" + name, String.class);
mSet.invoke(bean, new String(""));
}
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
七、在entity实体类或者字段上面加JsonInclude注解,过滤掉NULL值的属性
@JsonInclude(JsonInclude.Include.NON_NULL)
八、直接在entity字段上加JSONField注解,转Json时不返回当前字段
@JSONField(serialize = false)
如何选择:
1、全局生效,添加之后该服务下的所有接口都会生效,选择前四种;
2、针对特定接口使用,作为静态方法根据自己需要加在接口返回前,方式五和六;
3、针对特定实体类或者字段不传null值属性,使用方式七;
4、直接在Json序列化时不传某个字段,使用方式八。