阅读 335

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

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

本文介绍几种常见的姿势

1. transient关键字

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

@Data @AllArgsConstructor @NoArgsConstructor public static class GItem {     private String user;     // @IgnoreField     private transient String pwd; } 复制代码

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

@Test 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

@Data @AllArgsConstructor @NoArgsConstructor public static class GItem {     @Expose     private String user;     // @IgnoreField     private String pwd; } 复制代码

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

@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也不序列化

@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. 一灰灰Blog: liuyueyi.github.io/hexblog

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

2. 声明

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


作者:一灰灰
链接:https://juejin.cn/post/7022955479923949599


文章分类
后端
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐