服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - Java教程 - Gson序列化指定忽略字段的三种写法详解

Gson序列化指定忽略字段的三种写法详解

2022-03-01 00:27一灰灰 Java教程

在我们日常使用json序列化框架过程中,经常会遇到在输出json字符串时,忽略某些字段,那么在Gson框架中,要想实现这种方式,可以怎么处理呢,本文就来介绍一下

在我们日常使用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串时,默认会忽略
@Test

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

输出如

{"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进行忽略,可以怎么整呢?

到此这篇关于Gson序列化指定忽略字段的三种写法详解的文章就介绍到这了,更多相关Gson序列化指定忽略字段内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家! 

原文链接:https://juejin.cn/post/7022955479923949599

延伸 · 阅读

精彩推荐