我正在使用Gson序列化自定义对象。我已经定义了一个排除策略 -
public class HumidityExclusionStrategy implements ExclusionStrategy {
@Override
public boolean shouldSkipField(FieldAttributes f) {
System.out.println(f.getName());
boolean result = (f.getAnnotation(Expose.class) == null)
|| (f.getName().equalsIgnoreCase("humidity")
&& UserInputThread.shouldExcludeHumidity);
System.out.println(result);
return result;
}
@Override
public boolean shouldSkipClass(Class<?> clazz) {
return false;
}
}
我在另一个类中初始化Gson实例 -
private static final Gson GSON = new GsonBuilder()
.setExclusionStrategies(new HumidityExclusionStrategy())
.create();
UserInputThread.shouldExcludeHumidity
是一个基于某些用户输入修改的布尔值。当我第一次使用Gson对象进行序列化(GSON.toJson(sensor)
)时,策略的shouldSkipField()
方法中的print语句可以正常工作,并且我得到了预期的输出。
但是当UserInputThread.shouldExcludeHumidity
的值发生变化时,下一次序列化的结果与第一次相同 - 包含湿度字段。此外,print语句不会向控制台打印任何内容。为什么会这样?
我检查了布尔值UserInputThread.shouldExcludeHumidity
的值,这是我所期望的。
答案 0 :(得分:0)
我找到了这个问题的原因。在内部,gson使用地图在Gson.java
类中缓存排除策略的结果。
为了获得预期的结果,我每次需要序列化时都必须初始化一个新的Gson对象。此解决方案可能会造成性能问题,但对于我的情况,性能并不是真正的问题,并且此方法有效。
我没有创建全局Gson对象并在必要时使用它,而是使用以下方法调用 -
private Gson getGson() {
return new GsonBuilder()
.excludeFieldsWithoutExposeAnnotation()
.setExclusionStrategies(strat)
.create();
}
旧 -
private final Gson gson = new .....;
public static void main(String[] args) {
..... gson.toJson(...); .....
}
新 -
public static void main(String[] args) {
..... getGson().toJson(...); .....
}