杰克逊:反序列化列表时捕获单个项目的异常
jackson: catch exceptions for single items when deserializing a list
我遇到以下问题:有一个 REST API returns 一个 JSON 字符串,我想将其映射到列表。 MyObject 有几个字段,其中一些 int/double。让我们考虑一下 API 可能会为某些 MyObjects 的其中一个字段返回字符串而不是 ints/doubles,其余的没问题。
现在我希望映射器在丢弃有问题的 MyObjects 的同时仍将其映射到列表。但是,调用
objectMapper.readValue(jsonString, TypeFactory.defaultInstance().constructCollectionType(List.class, MyObject.class));
如果所有 MyObjects 都正常就会成功,或者在遇到第一个问题时完全失败。
我希望找到一个映射器迭代 JSON-MyObjects 列表并将它们一一映射到 Java-MyObjects 的位置。这样我就可以覆盖该行为,并可能用 try-catch 块包围它并捕获映射单个 MyObject 时发生的任何异常。到目前为止运气不好,但也许我只是瞎了眼。
非常感谢任何关于如何使用 jackson 完成此操作的想法。
我能够通过使用 Jackson 的自定义反序列化器实现这一点:
这是我的 MyObject 目标 class。它有一个注释,它与一个自定义反序列化器相关联:
@JsonDeserialize(using = MyObjectDeserializer.class)
public class MyObject
{
public int num;
public String str;
@Override
public String toString()
{
return "{" + num + "," + str + "}";
}
}
这是自定义反序列化器。它检查 "num" 属性 的类型是否为 int 类型:
public class MyObjectDeserializer extends JsonDeserializer<MyObject>
{
// read current MyObject json node
JsonNode myObjectNode = jp.getCodec().readTree(jp);// this will read
// read "num" property into JsonNode and check what subclass was created
JsonNode numNode = myObjectNode.get("num");
if (numNode instanceof IntNode) { // test if value of num is int indeed
MyObject o = new MyObject();
o.num = ((IntNode)numNode).intValue(); // read int value
o.str = ((TextNode)myObjectNode.get("str")).asText(); // this is how to read string typed property
return o;
} else {
return null; // or any default/error value
}
}
现在假设以下输入,请注意第二个对象有一个字符串类型 "num" 属性:
[{"num":1,"str":"n1"}, {"num":"s","str":"n2"}, {"num":3,"str":"n3"}]
如果没有自定义反序列化器,您会遇到异常。并得到输出:
[{1,n1}, null, {3,n3}]
我遇到以下问题:有一个 REST API returns 一个 JSON 字符串,我想将其映射到列表。 MyObject 有几个字段,其中一些 int/double。让我们考虑一下 API 可能会为某些 MyObjects 的其中一个字段返回字符串而不是 ints/doubles,其余的没问题。
现在我希望映射器在丢弃有问题的 MyObjects 的同时仍将其映射到列表。但是,调用
objectMapper.readValue(jsonString, TypeFactory.defaultInstance().constructCollectionType(List.class, MyObject.class));
如果所有 MyObjects 都正常就会成功,或者在遇到第一个问题时完全失败。
我希望找到一个映射器迭代 JSON-MyObjects 列表并将它们一一映射到 Java-MyObjects 的位置。这样我就可以覆盖该行为,并可能用 try-catch 块包围它并捕获映射单个 MyObject 时发生的任何异常。到目前为止运气不好,但也许我只是瞎了眼。
非常感谢任何关于如何使用 jackson 完成此操作的想法。
我能够通过使用 Jackson 的自定义反序列化器实现这一点:
这是我的 MyObject 目标 class。它有一个注释,它与一个自定义反序列化器相关联:
@JsonDeserialize(using = MyObjectDeserializer.class)
public class MyObject
{
public int num;
public String str;
@Override
public String toString()
{
return "{" + num + "," + str + "}";
}
}
这是自定义反序列化器。它检查 "num" 属性 的类型是否为 int 类型:
public class MyObjectDeserializer extends JsonDeserializer<MyObject>
{
// read current MyObject json node
JsonNode myObjectNode = jp.getCodec().readTree(jp);// this will read
// read "num" property into JsonNode and check what subclass was created
JsonNode numNode = myObjectNode.get("num");
if (numNode instanceof IntNode) { // test if value of num is int indeed
MyObject o = new MyObject();
o.num = ((IntNode)numNode).intValue(); // read int value
o.str = ((TextNode)myObjectNode.get("str")).asText(); // this is how to read string typed property
return o;
} else {
return null; // or any default/error value
}
}
现在假设以下输入,请注意第二个对象有一个字符串类型 "num" 属性:
[{"num":1,"str":"n1"}, {"num":"s","str":"n2"}, {"num":3,"str":"n3"}]
如果没有自定义反序列化器,您会遇到异常。并得到输出:
[{1,n1}, null, {3,n3}]