在运行时排除Gson序列化中的字段

时间:2015-12-02 06:17:55

标签: gson

我在SO上看到了在运行时从序列化中排除字段的示例。我需要这样做,但我想让Gson处理所有未被排除的字段的序列化。

复杂的部分是我不能让Gson先进行序列化,然后让TypeAdapter修改结果。我需要先以某种方式排除,然后将剩下的序列化。这甚至可能吗?

1 个答案:

答案 0 :(得分:0)

好的,通过一些实验和this helpful post,我能够拼凑出一种有条件地排除模拟字段的方法。

我遇到所有这些麻烦的原因是开箱即用的Gson在遭遇Spock模拟字段时抛出异常。

对于Spock,我检查确定某个字段是否被模拟是为了查看它引用的值的类名是否包含子字符串EnhancerByCGLib

下面,ResizingArrayQueueOfStrings.arrayFactory是可能会或可能不会被嘲笑的字段。

值得庆幸的是,对于需要这种处理的所有类,我可以使用单个JsonSerializer。理想情况下,我不必为每个可能被嘲笑的课程注册序列化器......但那是另一天的战斗。

当模拟字段并且ResizingArrayQueueOfStrings被序列化时,生成的JSON是

queue {
  "arrayFactory": "** mocked **",     
}

否则,它是

queue {
  "arrayFactory": {},
}

希望这有助于其他有类似需求的人。

public class MockSerializer implements JsonSerializer<Object> {

    @Override
    public JsonElement serialize(Object src, Type typeOfSrc, JsonSerializationContext context) {
        Gson gson = new Gson();
        String className = src.getClass().getName();
        boolean isMocked = className.contains("EnhancerByCGLIB");
        if (isMocked) return new JsonPrimitive("** mocked **");
        else return gson.toJsonTree(src);
    }

}

public class ResizingArrayQueueOfStrings {

    private ArrayFactory arrayFactory;

    public String toString() {
        Gson gson = new GsonBuilder()
                .registerTypeAdapter(ArrayFactory.class, new MockSerializer())
                .setPrettyPrinting()
                .create();
        return gson.toJson(this);
    }

}