zoukankan      html  css  js  c++  java
  • Java开发中POJO和JSON互转时如何忽略隐藏字段

    1. 前言

    Java开发中有时候某些敏感信息我们需要屏蔽掉,不能被消费这些数据的客户端知道。通常情况下我们会将其设置为null或者空字符 "",其实还有其它办法,如果你使用了Jackson的话。接下来我将以一个实际场景来告诉你可以怎么做。

    2. Jackson如何忽略字段

    这里都以JSON序列化为例。假如我们在业务中需要返回用户信息,已有的POJO是这样的:

    import lombok.Data;
    
    /**
     * @author felord.cn
     */
    @Data
    public class UserInfo {
        /**
         * userid
         */
        private String userId;
        /**
         * 用户名
         */
        private String username;
        /**
         * 密钥串
         */
        private String secret;
        /**
         * 地址信息
         */
        private String address;
    }
    

    业务场景:第三方通过用户的userId来获取用户的信息,但是密钥串secret显然不能让第三方知道,通常最容易想到的方法是将secret字段设置为null或者""。如果业务需要批量提供用户信息,即List<UserInfo>,我们总不能每次都要遍历一遍吧。Spring Boot内置的Jackson可以很方便的帮我们处理这个问题。

    使用@JsonIgnore注解

    Jackson提供了一个@JsonIgnore注解,将它标记到需要被忽略的字段上或者对应的getter方法或者setter方法上就可以实现对该字段的屏蔽。就像下面这样标记:

         @JsonIgnore
        private String secret;
       // 对应json 样例  {"userId":"100000","username":"felord.cn","address":"cn"}
    

    无论是序列化(将POJO转为JSON)还是反序列化((将JSON转为POJO),secret都会被忽略。

    使用@JsonIgnoreProperties注解

    这个注解比@JsonIgnore更加强大一些,通常该注解标记到POJO之上,它有更多的能力:

    • 忽略多个字段,配置value属性即可。
    • 忽略未知的属性,配置ignoreUnknowntrue,默认不忽略。
    • 允许忽略字段被序列化,配置allowGetterstrue,序列化的时候不会被忽略。
    • 允许忽略字段被反序列化,配置allowSetterstrue,反序列化的时候不会被忽略。

    例如我们要忽略UserInfo中的secretaddress,我们可以这样配置:

    @JsonIgnoreProperties({"secret", "address"})
    

    使用@JsonProperty注解

    需要Jackson版本不低于2.6

    这个注解出镜率还是非常高的,通常为了给JSON的字段起别名或者设置默认值使用。比如UserInfo中的userId想对应JSON中的user_id,我们可以:

    @JsonProperty(value = "user_id")
    private String userId;
    

    在2.6版本以后,这个注解也能实现忽略字段的作用。它有个access属性,用来指定在序列化(“读取”)和反序列化(“写”)期间访问权限(这里的读写是以属性为视角)。它由枚举Access定义:

    public enum Access
    {
        /**
         * 无论是序列化还是反序列化都会根据配置自动的处理,默认值。
         */
        AUTO,
    
        /**
         * 意味着该属性只能在进行序列化时读取(通过“ getter”方法访问的值,或者从字段中读取),而在反序列化      * 期间不能写入(设置)。换句话说,这将反映“只读POJO”,其中包含的值可以读取但不能写入。
         */
        READ_ONLY,
    
        /**
         * 意味着该属性只能作为反序列化的一部分写入(设置)(使用“ setter”方法,或分配给Field,或作为          * Creator参数传递),而不会被读取(获取)以进行序列化,即,该属性的值不包括在序列化中。
         */
        WRITE_ONLY,
    
        /**
         * 可读可写,READ_ONLY与WRITE_ONLY的合并效果。
         */
        READ_WRITE;
    }
    

    从这个注解中我们可以知道,如果你想在POJOJSON时忽略secret字段,就可以这么写:

    @JsonProperty( access = JsonProperty.Access.WRITE_ONLY)
    private String secret;
    

    使用@JsonIgnoreType注解

    这个注解是用来直接忽略类型的,如果上面的UserInfo是另外一个POJO的属性,我们不希望它被序列化和反序列化,那么就可以:

    @JsonIgnoreType
    public class UserInfo {
       // 省略
    }
    

    3. 总结

    目前大概可知的Jackson有这么四种的忽略属性的方式,它们有各自的使用场景,你可以根据自己的情况选择使用。好了今天的分享就到这里,多多关注:码农小胖哥,获取更多的编程干货。

    关注公众号:Felordcn 获取更多资讯

    个人博客:https://felord.cn

    博主:码农小胖哥
    出处:felord.cn
    本文版权归原作者所有,不可商用,转载需要声明出处,否则保留追究法律责任的权利。如果文中有什么错误,欢迎指出。以免更多的人被误导。
  • 相关阅读:
    nodejs微服务健康检查方案
    RabbitMQ inequivalent arg 'durable' for exchange 'csExchange' in vhost '/': received
    python 虚拟环境
    gulp-babel使用
    node-schedule定时任务
    微信小程序分包(附微信小程序开发学习手册)
    抖音、腾讯、京东、阿里等大厂性能优化方案总结(含项目实战分析及视频)
    微信小程序绘制二维码(附微信小程序开发学习手册)
    【纯干货分享】拒绝卡顿,揭秘盒马鲜生 APP Android 短视频秒播优化方案
    碰壁五次!我闭关28天啃完这些书,再战拿下腾讯,爱奇艺,小红书,快手等10家大厂!化身offer收割机!
  • 原文地址:https://www.cnblogs.com/felordcn/p/14365709.html
Copyright © 2011-2022 走看看