Springboot使用jackson或fastjson时过滤null值

1 篇文章 0 订阅
1 篇文章 0 订阅

Jackson全局过滤null值

方法一:使用yml配置方式

spring:
  jackson:
    default-property-inclusion: non_null

方法二:使用Bean注入方式配置

@Configuration
public class MyJacksonConfig {
    @Bean
    @Primary
    @ConditionalOnMissingBean(ObjectMapper.class)
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder)
    {
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
        // 通过该方法对mapper对象进行设置,所有序列化的对象都将按改规则进行系列化
        // Include.Include.ALWAYS 默认
        // Include.NON_DEFAULT 属性为默认值不序列化
        // Include.NON_EMPTY 属性为 空("") 或者为 NULL 都不序列化,则返回的json是没有这个字段的。这样对移动端会更省流量
        // Include.NON_NULL 属性为NULL 不序列化
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_EMPTY);
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 允许出现单引号
        objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
        return objectMapper;
    }
}

方法三:重写WebMvcConfigurationSupport的configureMessageConverters

public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        for (HttpMessageConverter converter : converters) {
            if (converter instanceof MappingJackson2HttpMessageConverter) {
                ObjectMapper mapper = ((MappingJackson2HttpMessageConverter) converter).getObjectMapper();
                mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
            }
        }
    }

方法四:重写WebMvcConfigurer的configureMessageConverters

public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        for (HttpMessageConverter converter : converters) {
            if (converter instanceof MappingJackson2HttpMessageConverter) {
                ObjectMapper mapper = ((MappingJackson2HttpMessageConverter) converter).getObjectMapper();
                mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
            }
        }
    }

使用前三种种方式配置时需注意:

只要使用@EnableWebMvc这个注解或者是继承WebMvcConfigurationSupport类,则以上三种配置无效。
这是因为加了@EnableWebMvc加了这个注解后Springboot加载的是WebMvcConfigurationSupport中的配置项,而不使用WebMvcAutoConfiguration引入的配置项。也就是说无论是使用@EnableWebMvc还是WebMvcConfigurationSupport,都会禁止Spring Boot的自动装配,同时也不能自动读取 application.properties 或 application.yml 文件中的配置(更详细的解释参考这篇博客),所以前两种方法也就无效啦。
那么为什么第三种方法也无效呢?阅读官方文档,发现官方的解释如下:

Finally, if you opt out of the Spring Boot default MVC configuration by providing your own @EnableWebMvc configuration, you can take control completely and do everything manually by using getMessageConverters from WebMvcConfigurationSupport.

也就是说可以使用 WebMvcConfigurationSupport 中的 getMessageConverters 手动执行所有操作,但是这样的话显然要麻烦得多,不如直接实现WebMvcConfigurer来得快。
终上所述,大多数时我们在SpringBoot中并不需要使用@EnableWebMvc注解或者继承WebMvcConfigurationSupport类,因为这样的话会是自动配置失效从而需要手动进行配置,而使用Springboot的自动配置就可以满足大部分的要求,以下是官方文档的描述:

Spring Boot provides auto-configuration for Spring MVC that works well with most applications.
If you want to keep Spring Boot MVC features and you want to add additional MVC configuration (interceptors, formatters, view controllers, and other features), you can add your own @Configuration class of type WebMvcConfigurer but without @EnableWebMvc. If you wish to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter, or ExceptionHandlerExceptionResolver, you can declare a WebMvcRegistrationsAdapter instance to provide such components.
If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc.

FastJson全局过滤null值

方法一:实现WebMvcConfigurer

原先的配置是:

@Configuration
public class MyWebMvcConfigurer implements WebMvcConfigurer {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    	//创建fastJson消息转换器
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
        //创建配置类
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        //修改配置返回内容的过滤
        //WriteNullListAsEmpty  :List字段如果为null,输出为[],而非null
        //WriteNullStringAsEmpty : 字符类型字段如果为null,输出为"",而非null
        //DisableCircularReferenceDetect :消除对同一对象循环引用的问题,默认为false(如果不配置有可能会进入死循环)
        //WriteNullBooleanAsFalse:Boolean字段如果为null,输出为false,而非null
        //WriteMapNullValue:是否输出值为null的字段,默认为false
        fastJsonConfig.setSerializerFeatures(
                SerializerFeature.QuoteFieldNames,
                SerializerFeature.DisableCircularReferenceDetect,
                SerializerFeature.WriteEnumUsingToString,
//                SerializerFeature.WriteMapNullValue,
                SerializerFeature.WriteDateUseDateFormat
        );
        fastConverter.setFastJsonConfig(fastJsonConfig);
        //将fastjson添加到视图消息转换器列表内
        converters.add(fastConverter);
    }

}

但是运行后发现并没有过滤null值:
在这里插入图片描述
参考这篇博客:记一次踩坑:springboot2.0.2配置fastjson不生效。原因是Springboot自带的jackson的converter把我们配置的fastjson的converter覆盖了,所以需要保证我们配置的fastjson的converter在jackson的后面即可,因此将配置修改为:

@Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
	    	Iterator<HttpMessageConverter<?>> iterator = converters.iterator();
	        while(iterator.hasNext()){
	            HttpMessageConverter<?> converter = iterator.next();
	            if(converter instanceof MappingJackson2HttpMessageConverter){
	            	//将springboot的jackson的消息转换器移除
	                iterator.remove();
	            }
	        }
            //创建fastJson消息转换器
            FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
            //创建配置类
            FastJsonConfig fastJsonConfig = new FastJsonConfig();
            //修改配置返回内容的过滤
            //WriteNullListAsEmpty  :List字段如果为null,输出为[],而非null
            //WriteNullStringAsEmpty : 字符类型字段如果为null,输出为"",而非null
            //DisableCircularReferenceDetect :消除对同一对象循环引用的问题,默认为false(如果不配置有可能会进入死循环)
            //WriteNullBooleanAsFalse:Boolean字段如果为null,输出为false,而非null
            //WriteMapNullValue:是否输出值为null的字段,默认为false
            fastJsonConfig.setSerializerFeatures(
                    SerializerFeature.QuoteFieldNames,
                    SerializerFeature.DisableCircularReferenceDetect,
                    SerializerFeature.WriteEnumUsingToString,
    //                SerializerFeature.WriteMapNullValue,
                    SerializerFeature.WriteDateUseDateFormat
            );
            fastConverter.setFastJsonConfig(fastJsonConfig);
            //将fastjson添加到视图消息转换器列表内
            converters.add(fastConverter);
    }

原以为成功了,但是调用接口时报了错:

java.lang.IllegalArgumentException: Content-Type cannot contain wildcard type '*'

参考这篇博客后,将配置信息修改为:

@Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        Iterator<HttpMessageConverter<?>> iterator = converters.iterator();
        while(iterator.hasNext()){
            HttpMessageConverter<?> converter = iterator.next();
            if(converter instanceof MappingJackson2HttpMessageConverter){
                iterator.remove();
            }
        }
        //创建fastJson消息转换器
        FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
        //升级最新版本需加=============================================================
        List<MediaType> supportedMediaTypes = new ArrayList<>();
        supportedMediaTypes.add(MediaType.APPLICATION_JSON);
        supportedMediaTypes.add(MediaType.APPLICATION_ATOM_XML);
        supportedMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED);
        supportedMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM);
        supportedMediaTypes.add(MediaType.APPLICATION_PDF);
        supportedMediaTypes.add(MediaType.APPLICATION_RSS_XML);
        supportedMediaTypes.add(MediaType.APPLICATION_XHTML_XML);
        supportedMediaTypes.add(MediaType.APPLICATION_XML);
        supportedMediaTypes.add(MediaType.IMAGE_GIF);
        supportedMediaTypes.add(MediaType.IMAGE_JPEG);
        supportedMediaTypes.add(MediaType.IMAGE_PNG);
        supportedMediaTypes.add(MediaType.TEXT_EVENT_STREAM);
        supportedMediaTypes.add(MediaType.TEXT_HTML);
        supportedMediaTypes.add(MediaType.TEXT_MARKDOWN);
        supportedMediaTypes.add(MediaType.TEXT_PLAIN);
        supportedMediaTypes.add(MediaType.TEXT_XML);
        fastConverter.setSupportedMediaTypes(supportedMediaTypes);
        //创建配置类
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        //修改配置返回内容的过滤
        //WriteNullListAsEmpty  :List字段如果为null,输出为[],而非null
        //WriteNullStringAsEmpty : 字符类型字段如果为null,输出为"",而非null
        //DisableCircularReferenceDetect :消除对同一对象循环引用的问题,默认为false(如果不配置有可能会进入死循环)
        //WriteNullBooleanAsFalse:Boolean字段如果为null,输出为false,而非null
        //WriteMapNullValue:是否输出值为null的字段,默认为false
        fastJsonConfig.setSerializerFeatures(
                SerializerFeature.QuoteFieldNames,
                SerializerFeature.DisableCircularReferenceDetect,
                SerializerFeature.WriteEnumUsingToString,
//                SerializerFeature.WriteMapNullValue,
                SerializerFeature.WriteDateUseDateFormat
        );
        fastConverter.setFastJsonConfig(fastJsonConfig);
        //将fastjson添加到视图消息转换器列表内
        converters.add(fastConverter);
    }

经过千辛万苦后终于过滤null值:
在这里插入图片描述

方法二:继承WebMvcConfigurationSupport

同样实现configureMessageConverters方法,配置与方法一的最终配置一样。但是考虑到使用WebMvcConfigurationSupport方式来实现会产生一些问题(如前所述),所以还是使用implements WebMvcConfigurer方式比较保险。

  • 3
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用Spring BootFastjson,如果有属性为null不返回的需求,可以通过以下几种方式来实现: 1. 使用JsonSerialize注解:在需要处理的属性上添加@JsonSerialize注解,并设置属性的nulls属性为Nulls.SKIP。例如: ```java import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.serializer.Nulls; public class MyObject { @JSONField(nulls = Nulls.SKIP) private String property; // 其他属性和方法... } ``` 这样当属性nullFastjson将会忽略该属性,不会返回给前端。 2. 使用JsonInclude注解:在类上添加@JsonInclude注解,并设置属性的为JsonInclude.Include.NON_NULL。例如: ```java import com.fasterxml.jackson.annotation.JsonInclude; @JsonInclude(JsonInclude.Include.NON_NULL) public class MyObject { private String property; // 其他属性和方法... } ``` 这样当属性nullFastjson将会忽略该属性,不会返回给前端。 3. 自定义返回结果:可以在返回结果的候手动去除属性为null的字段。例如: ```java import com.alibaba.fastjson.JSONObject; public JSONObject customizeResult(MyObject myObject) { JSONObject jsonObject = (JSONObject) JSONObject.toJSON(myObject); jsonObject.remove("property"); // 去除属性null的字段 return jsonObject; } ``` 在返回结果之前,通过JSONObject的remove方法将属性null的字段移除,然后返回给前端。 以上是三种常见的在使用Spring BootFastjson处理属性为null不返回的方式,可以根据具体需求选择其中一种来实现。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值