【问题标题】:Exclude fields from Gson serialization at runtime在运行时从 Gson 序列化中排除字段
【发布时间】:2015-12-02 06:17:54
【问题描述】:

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

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

【问题讨论】:

  • 如果我错了,请纠正我,但是 TypeAdapter 是在进行序列化,它不会修改结果,因为它本身正在形成结果(JSON),不是吗?
  • @nickb 我在 SO 上看到了一个示例,其中默认序列化由 TypeAdapter 委托给库,然后由 TypeAdapter 编辑结果以在返回最终结果之前删除排除的字段。
  • 有意思,有链接吗?如果您可以提供您所描述的实现以及对其缺点的解释,它可能有助于更好地解释您的问题。
  • @nickb 我想通了。但感谢您的回复。

标签: gson


【解决方案1】:

好的,通过一些实验和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);
    }

}

【讨论】:

    猜你喜欢
    • 2013-01-12
    • 2017-04-16
    • 1970-01-01
    • 2012-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-15
    相关资源
    最近更新 更多