当前位置: 代码网 > it编程>编程语言>Java > SpringBoot设置Json返回字段为非空问题

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

2024年08月09日 Java 我要评论
前言各位同学可能遇到过下述问题,在项目开发中,后端是以json格式的数据返回给前端,但是对于数据为空的字段,可能出现null,这让前端同学很痛苦,于是他们想,针对那些为null的字段,后端能不能把st

前言

各位同学可能遇到过下述问题,在项目开发中,后端是以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访问本地静态资源

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com