在我们日常使用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; 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); }
输出如
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; 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. 其他 一灰灰的个人博客,记录所有学习和工作中的博文,欢迎大家前去逛逛
2. 声明 尽信书则不如,以上内容,纯属一家之言,因个人能力有限,难免有疏漏和错误之处,如发现bug或者有更好的建议,欢迎批评指正,不吝感激
3. 扫描关注 一灰灰blog