211025-Gson之序列化指定忽略字段的写法

文章目录
  1. 1. transient关键字
  2. 2. expose注解
  3. 3. 自定义排查策略ExclusionStrategy
  • II. 其他
    1. 1. 一灰灰Blog: https://liuyueyi.github.io/hexblog
    2. 2. 声明
    3. 3. 扫描关注
  • 在我们日常使用json序列化框架过程中,经常会遇到在输出json字符串时,忽略某些字段,那么在Gson框架中,要想实现这种方式,可以怎么处理呢?

    本文介绍几种常见的姿势

    1. transient关键字

    最容易想到的case,就是直接借助jdk的transient关键字来修饰不希望输出的对象,如

    1
    2
    3
    4
    5
    6
    7
    8
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class GItem {
    private String user;
    // @IgnoreField
    private transient String pwd;
    }

    上面的对象中,pwd前面使用transient进行修饰,那么在输出json串时,默认会忽略

    1
    2
    3
    4
    5
    6
    @Test
    public void testPrint() {
    GItem item = new GItem("一灰灰", "yihui");
    String ans = new Gson().toJson(item);
    System.out.println(ans);
    }

    输出如

    1
    {"user":"一灰灰"}

    2. expose注解

    借助gson提供的expose注解,也可以实现上面的case,如在需要保留的字段上添加@Expose

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class GItem {
    @Expose
    private String user;
    // @IgnoreField
    private String pwd;
    }

    然后我们使用的地方,注意通过 GsonBuilder来创建Gson对象

    1
    2
    3
    4
    5
    6
    @Test
    public void testPrint() {
    GItem item = new GItem("一灰灰", "yihui");
    String ans = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create().toJson(item);
    System.out.println(ans);
    }

    上面这种使用姿势感觉有点怪怪的,在需要保留的字段上添加注解,这种使用方式并没有jackson的@JsonIgnore方式来得方便

    3. 自定义排查策略ExclusionStrategy

    除了上面两种方式之外,通过自定义的排除策略可以实现即使不修改bean,也能指定哪些字段不序列化

    一个简单的demo如下,如果包含自定义的注解,则不序列化,或者field_name == pwd也不序列化

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    @Target({ElementType.ANNOTATION_TYPE, ElementType.FIELD, ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface IgnoreField {
    }


    @Test
    public void testExclude() {
    Gson gson = new GsonBuilder().setExclusionStrategies(new ExclusionStrategy() {
    @Override
    public boolean shouldSkipField(FieldAttributes fieldAttributes) {
    if (fieldAttributes.getAnnotation(IgnoreField.class) != null) {
    // 包含这个注解的,直接忽略
    return true;
    }

    // 成员白名单
    if (fieldAttributes.getName().equalsIgnoreCase("pwd")) {
    return true;
    }
    return false;
    }

    @Override
    public boolean shouldSkipClass(Class<?> aClass) {
    if (aClass.isAnnotationPresent(IgnoreField.class)) {
    return true;
    }
    return false;
    }
    }).registerTypeAdapterFactory(new MyMapTypeAdapterFactory(new ConstructorConstructor(new HashMap<>()), false)).create();

    GItem item = new GItem();
    item.setUser("一灰灰");
    item.setPwd("123456");

    System.out.println(gson.toJson(item));
    }

    上面这种姿势,更适用于有自定义需求场景的case,那么问题来了,如果我希望序列化的对象,并不是JOPO对象,比如传入的是一个Map,也希望针对某些key进行忽略,可以怎么整呢?

    II. 其他

    1. 一灰灰Bloghttps://liuyueyi.github.io/hexblog

    一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛

    2. 声明

    尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激

    3. 扫描关注

    一灰灰blog

    QrCode

    # Gson

    评论

    Your browser is out-of-date!

    Update your browser to view this website correctly. Update my browser now

    ×