Gson排除策略的问题

时间:2016-05-05 11:43:19

标签: java serialization gson

我正在使用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的值,这是我所期望的。

1 个答案:

答案 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(...); .....
}