我在努力学习Gson,我在与场排除作斗争。这是我的课程
public class Student {
private Long id;
private String firstName = "Philip";
private String middleName = "J.";
private String initials = "P.F";
private String lastName = "Fry";
private Country country;
private Country countryOfBirth;
}
public class Country {
private Long id;
private String name;
private Object other;
}
我可以使用GsonBuilder,并为字段名如firstName或country添加一个ExclusionStrategy,但我似乎无法排除某些字段的属性,如country.name。
使用方法public boolean shouldSkipField(FieldAttributes fa), FieldAttributes不包含足够的信息来匹配像country.name这样的过滤器。
附注:我想避免使用注释,因为我想改进这一点,并使用RegEx过滤字段。
编辑:我试着看看是否有可能模拟Struts2 JSON插件的行为
使用Gson
<interceptor-ref name="json">
<param name="enableSMD">true</param>
<param name="excludeProperties">
login.password,
studentList.*\.sin
</param>
</interceptor-ref>
编辑:
我重新提出这个问题,补充如下:
我添加了第二个具有相同类型的字段,以进一步澄清这个问题。基本上我想要排除country。name而不是countrofbirth。name。我也不想把Country排除在外。
所以类型是一样的我想要精确定位和排除的对象图中的实际位置。
我提出了一个类工厂来支持这个功能。传入想要排除的字段或类的任何组合。
public class GsonFactory {
public static Gson build(final List<String> fieldExclusions, final List<Class<?>> classExclusions) {
GsonBuilder b = new GsonBuilder();
b.addSerializationExclusionStrategy(new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes f) {
return fieldExclusions == null ? false : fieldExclusions.contains(f.getName());
}
@Override
public boolean shouldSkipClass(Class<?> clazz) {
return classExclusions == null ? false : classExclusions.contains(clazz);
}
});
return b.create();
}
}
为了使用,创建两个列表(每个列表都是可选的),并创建你的GSON对象:
static {
List<String> fieldExclusions = new ArrayList<String>();
fieldExclusions.add("id");
fieldExclusions.add("provider");
fieldExclusions.add("products");
List<Class<?>> classExclusions = new ArrayList<Class<?>>();
classExclusions.add(Product.class);
GSON = GsonFactory.build(null, classExclusions);
}
private static final Gson GSON;
public String getSomeJson(){
List<Provider> list = getEntitiesFromDatabase();
return GSON.toJson(list);
}
我遇到了这个问题,在这个问题中,我只想从序列化中排除少量字段,所以我开发了一个相当简单的解决方案,使用带有自定义排除策略的Gson的@Expose注释。
使用@Expose的唯一内置方法是设置GsonBuilder.excludeFieldsWithoutExposeAnnotation(),但正如名称所示,没有显式@Expose的字段将被忽略。由于我只有几个想要排除的字段,我发现将注释添加到每个字段非常麻烦。
实际上,我想要的是相反的,其中所有内容都包括在内,除非我显式地使用@Expose来排除它。我使用了以下排除策略来实现这一点:
new GsonBuilder()
.addSerializationExclusionStrategy(new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes fieldAttributes) {
final Expose expose = fieldAttributes.getAnnotation(Expose.class);
return expose != null && !expose.serialize();
}
@Override
public boolean shouldSkipClass(Class<?> aClass) {
return false;
}
})
.addDeserializationExclusionStrategy(new ExclusionStrategy() {
@Override
public boolean shouldSkipField(FieldAttributes fieldAttributes) {
final Expose expose = fieldAttributes.getAnnotation(Expose.class);
return expose != null && !expose.deserialize();
}
@Override
public boolean shouldSkipClass(Class<?> aClass) {
return false;
}
})
.create();
现在,我可以很容易地用@Expose(serialize = false)或@Expose(deserialize = false)注释排除一些字段(注意,这两个@Expose属性的默认值都是true)。当然,您可以使用@Expose(serialize = false, deserialize = false),但是通过声明字段transient(使用这些自定义排除策略仍然有效)可以更简洁地实现这一点。