SpringBoot设置Json返回字段为非空问题

 更新时间:2024年08月09日 11:21:29   作者:小Y先生。  
这篇文章主要介绍了SpringBoot设置Json返回字段为非空问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

前言

各位同学可能遇到过下述问题,在项目开发中,后端是以Json格式的数据返回给前端,但是对于数据为空的字段,可能出现NULL,这让前端同学很痛苦,于是他们想,针对那些为null的字段,后端能不能把String类型的数据返回空字符串,int类型的数据返回0,集合和数组返回[],这样多方便呢!

OK,既然这样的话就满足他们的要求,本文利用Spring自带的Json转化器,将返回给前端的数据进行处理,见下文所示。

一、编写Json数据转化器

/**
 * @作者 yangs
 * @日期 2022/1/20
 * @描述 json数据转化器
 */
public class JacksonHttpMessageConverter extends MappingJackson2HttpMessageConverter {

    /**
     * 处理数组类型的null值
     */
    public class NullArrayJsonSerializer extends JsonSerializer<Object> {

        @Override
        public void serialize(Object value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
            if (value == null) {
                jgen.writeStartArray();
                jgen.writeEndArray();
            }
        }
    }


    /**
     * 处理字符串类型的null值
     */
    public class NullStringJsonSerializer extends JsonSerializer<Object> {

        @Override
        public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
            jsonGenerator.writeString(StringUtils.EMPTY);
        }
    }

    /**
     * 处理数字类型的null值
     */
    public class NullNumberJsonSerializer extends JsonSerializer<Object> {

        @Override
        public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
            jsonGenerator.writeNumber(0);
        }
    }

    /**
     * 处理布尔类型的null值
     */
    public class NullBooleanJsonSerializer extends JsonSerializer<Object> {

        @Override
        public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
            jsonGenerator.writeBoolean(false);
        }
    }


    public class MyBeanSerializerModifier extends BeanSerializerModifier {

        @Override
        public List<BeanPropertyWriter> changeProperties(SerializationConfig config, BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) {
            //循环所有的beanPropertyWriter
            for (Object beanProperty : beanProperties) {
                BeanPropertyWriter writer = (BeanPropertyWriter) beanProperty;
                //判断字段的类型,如果是array,list,set则注册nullSerializer
                if (isArrayType(writer)) {
                    //给writer注册一个自己的nullSerializer
                    writer.assignNullSerializer(new NullArrayJsonSerializer());
                } else if (isNumberType(writer)) {
                    writer.assignNullSerializer(new NullNumberJsonSerializer());
                } else if (isBooleanType(writer)) {
                    writer.assignNullSerializer(new NullBooleanJsonSerializer());
                } else if (isStringType(writer)) {
                    writer.assignNullSerializer(new NullStringJsonSerializer());
                }
            }
            return beanProperties;
        }

        /**
         * 是否是数组
         */
        private boolean isArrayType(BeanPropertyWriter writer) {
            Class<?> clazz = writer.getType().getRawClass();
            return clazz.isArray() || Collection.class.isAssignableFrom(clazz);
        }

        /**
         * 是否是string
         */
        private boolean isStringType(BeanPropertyWriter writer) {
            Class<?> clazz = writer.getType().getRawClass();
            return CharSequence.class.isAssignableFrom(clazz) || Character.class.isAssignableFrom(clazz);
        }


        /**
         * 是否是int
         */
        private boolean isNumberType(BeanPropertyWriter writer) {
            Class<?> clazz = writer.getType().getRawClass();
            return Number.class.isAssignableFrom(clazz);
        }

        /**
         * 是否是boolean
         */
        private boolean isBooleanType(BeanPropertyWriter writer) {
            Class<?> clazz = writer.getType().getRawClass();
            return clazz.equals(Boolean.class);
        }

    }

    public JacksonHttpMessageConverter() {
        getObjectMapper().setSerializerFactory(getObjectMapper().getSerializerFactory().withSerializerModifier(new MyBeanSerializerModifier()));
    }

}

二、编写MVC配置文件

接下来我们要写一个MVC的配置类,继承WebMvcConfigurationSupport类,并重写configureMessageConverters()方法,在这里方法中,我们要把上面定义的Json转换工具加载进来,来实现我们想要的功能。

/**
 * @作者 yangs
 * @日期 2022/1/20
 * @描述 MVC的配置类
 */
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {

    // 文件映射路径
    @Value("${fileMappingPath}")
    private String fileMappingPath;

    /**
     * @作者 yangs
     * @日期 2022/1/20
     * @描述 返回给前端的json格式转化器
     */
    @Override
    protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        super.configureMessageConverters(converters);
        converters.add(new JacksonHttpMessageConverter());
    }
    
}

到目前为止,我们已经实现了想要的功能,把String类型的null转成"",把Integer类型的null转成0,把空集合和数组转成[]。

但是继承WebMvcConfigurationSupport后,可能会出现一些坑,比如静态资源获取的问题。

继续往下看,没准可以防止埋雷。

三、防雷警告

继承WebMvcConfigurationSupport类会使application.yml中配置的静态资源映射失效,如果你在配置文件中配置了如下代码

一定要警惕:

spring:
  mvc:
    static-path-pattern: /image/**
  resources:
    static-locations: file:E:/picture/

当我们继承WebMvcConfigurationSupport类时,会是配置文件的静态资源映射失效,所以我们需要另一种解决方法,只需在WebMvcConfigurationSupport的子类中重写addResourceHandlers()方法即可

如下所示:

/**
 * @作者 yangs
 * @日期 2022/1/20
 * @描述 MVC的配置类
 */
@Configuration
public class WebMvcConfig extends WebMvcConfigurationSupport {

    /**
     * @作者 yangs
     * @日期 2022/1/20
     * @描述 返回给前端的json格式转化器
     */
    @Override
    protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        super.configureMessageConverters(converters);
        converters.add(new JacksonHttpMessageConverter());
    }

    // 文件映射路径
    @Value("${fileMappingPath}")
    private String fileMappingPath;

    /**
     * @作者 yangs
     * @日期 2022/1/20
     * @描述 配置静态资源访问路径
     */
    @Override
    protected void addResourceHandlers(ResourceHandlerRegistry registry) {
        //通过image获取静态资源
        registry.addResourceHandler("/image/**").addResourceLocations(fileMappingPath);
    }
}

你也可以查看我的另一篇文章,查阅如何在SpringBoot中访问本地的静态资源,SpringBoot访问本地静态资源

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Linux配置jdk1.8与jdk17兼容并存并启动jar包指定jdk版本

    Linux配置jdk1.8与jdk17兼容并存并启动jar包指定jdk版本

    JDK是Java语言的软件开发工具包,主要用于移动设备、嵌入式设备上的java应用程序,这篇文章主要给大家介绍了关于Linux配置jdk1.8与jdk17兼容并存并启动jar包指定jdk版本的相关资料,需要的朋友可以参考下
    2024-08-08
  • Compare And Swap底层原理及代码示例详解

    Compare And Swap底层原理及代码示例详解

    这篇文章主要介绍了Compare And Swap底层原理及代码示例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • Maven的几个常用plugin

    Maven的几个常用plugin

    本文主要介绍了Maven的几个常用plugin。具有一定的参考价值,下面跟着小编一起来看下吧
    2017-01-01
  • SpringBoot中的统一异常处理详细解析

    SpringBoot中的统一异常处理详细解析

    这篇文章主要介绍了SpringBoot中的统一异常处理详细解析,该注解可以把异常处理器应用到所有控制器,而不是单个控制器,借助该注解,我们可以实现:在独立的某个地方,比如单独一个类,定义一套对各种异常的处理机制,需要的朋友可以参考下
    2024-01-01
  • 详解springboot WebTestClient的使用

    详解springboot WebTestClient的使用

    WebClient是一个响应式客户端,它提供了RestTemplate的替代方法。这篇文章主要介绍了详解springboot WebTestClient的使用, 具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-11-11
  • JAVA设计模式之备忘录模式原理与用法详解

    JAVA设计模式之备忘录模式原理与用法详解

    这篇文章主要介绍了JAVA设计模式之备忘录模式,简单说明了备忘录模式的概念、原理并结合实例形式分析了java备忘录模式的具体定义及使用方法,需要的朋友可以参考下
    2017-08-08
  • Spring中@RabbitHandler和@RabbitListener的区别详析

    Spring中@RabbitHandler和@RabbitListener的区别详析

    @RabbitHandler是用于处理消息的方法注解,它与@RabbitListener注解一起使用,这篇文章主要给大家介绍了关于Spring中@RabbitHandler和@RabbitListener区别的相关资料,需要的朋友可以参考下
    2024-02-02
  • Spring Boot项目打包指定包名实现示例

    Spring Boot项目打包指定包名实现示例

    这篇文章主要为大家介绍了Spring Boot项目打包指定包名实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-11-11
  • Java基础篇之serialVersionUID用法及注意事项详解

    Java基础篇之serialVersionUID用法及注意事项详解

    这篇文章主要给大家介绍了关于Java基础篇之serialVersionUID用法及注意事项的相关资料,SerialVersionUID属性是用于序列化/反序列化可序列化类的对象的标识符,我们可以用它来记住可序列化类的版本,以验证加载的类和序列化对象是否兼容,需要的朋友可以参考下
    2024-02-02
  • Java字符串常见的操作(比较,查找,替换等)

    Java字符串常见的操作(比较,查找,替换等)

    在Java当中,为字符串类提供了丰富的操作方法,对于字符串,我们常见的操作就是:字符串的比较、查找、替换、拆分、截取以及其他的一些操作,本文就详细的介绍一下,感兴趣的可以了解一下
    2022-01-01

最新评论