如何告诉 Jackson 在反序列化时跳过无效记录?

huangapple go评论65阅读模式
英文:

How can I tell Jackson to skip invalid records during deserialization?

问题

我有一个包含数百万条记录的JSON文件。我想使用Jackson迭代器逐条读取记录,并针对每条记录执行操作。以下是目前的代码。

MappingIterator<MyClass> iterator = new ObjectMapper()
        .readerFor(MyClass.class)
        .readValues(file);

while (iterator.hasNext()) {
    MyClass object = iterator.next();
    ...
}

问题是,一些记录由于缺少引号或非法字符而无效。这导致Jackson抛出异常并退出。我该如何告诉Jackson跳过这些记录并继续解析其余有效的记录?

英文:

I have a JSON file containing millions of records. I'd like to use a Jackson iterator to read the records one at a time and perform an action for each one. Here's the code so far.

MappingIterator&lt;MyClass&gt; iterator = new ObjectMapper()
        .readerFor(MyClass.class)
        .readValues(file);

while (iterator.hasNext()) {
    MyClass object = iterator.next();
    ...
}

The problem is that a few of the records are invalid due to missing quotes or illegal characters. This causes Jackson to throw an exception and quit. How can I tell Jackson to skip these records and continue to parse the remaining valid records?

答案1

得分: 1

尝试使用 @JsonIgnoreProperties(ignoreUnknown = true),或者你可能需要使用 JsonFilter 或自定义序列化。

示例代码:

> @JsonInclude(JsonInclude.Include.NON_NULL)
> @JsonDeserialize(using = UserDeserializer.class)
> public class User {
>     private Long id;
>     private String name;
>     private User() {}
>     构造函数settergetter
> }

public class UserDeserializer extends JsonDeserializer<User> {
    @Override
    public User deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException {
        try {
            ObjectCodec oc = jsonParser.getCodec();
            JsonNode node = oc.readTree(jsonParser);
            final Long id = node.get("id").asLong();
            final String name = node.get("name").asText();
            return new User(id, name);
        } catch (JsonParseException ex) {
        } catch (Exception e) {}
        return null;
    }
}

public static void main(String[] args) throws IOException {
    String input = "[{\"id\": 1, \"name\": \"valid\"}," +
            " {\"id\": 2, \"name\": invalid}," +
            " {\"id\": 3, \"name\": \"valid\"}]";

    ObjectMapper objectMapper = new ObjectMapper();
    List<User> users = objectMapper.readValue(input, objectMapper.getTypeFactory().constructCollectionType(List.class, User.class));
    users.forEach(System.out::println);
}

输出:

1 valid
null
null
3 valid

这样你就可以在集合中忽略/过滤掉null值。

英文:

try @JsonIgnoreProperties(ignoreUnknown = true) or you may need
JsonFilter or customize serialization

> @JsonInclude(JsonInclude.Include.NON_NULL)
> @JsonDeserialize(using = UserDeserializer.class)
> public class User {
> private Long id;
> private String name;
> private User() {}
> constructor, setter, getter
> }

public class UserDeserializer extends JsonDeserializer&lt;User&gt; {
    @Override
    public User deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException {
        try {
            ObjectCodec oc = jsonParser.getCodec();
            JsonNode node = oc.readTree(jsonParser);
            final Long id = node.get(&quot;id&quot;).asLong();
            final String name = node.get(&quot;name&quot;).asText();
            return new User(id, name);
        } catch (JsonParseException ex) {
        } catch (Exception e) {}
        return null;
    }
}


    public static void main(String[] args) throws IOException {
    String input = &quot;[{\&quot;id\&quot;: 1, \&quot;name\&quot;: \&quot;valid\&quot;},&quot; +
            &quot; {\&quot;id\&quot;: 2, \&quot;name\&quot;: invalid},&quot; +
            &quot; {\&quot;id\&quot;: 3, \&quot;name\&quot;: \&quot;valid\&quot;}]&quot;;

    ObjectMapper objectMapper = new ObjectMapper();
    List&lt;User&gt; users = objectMapper.readValue(input, objectMapper.getTypeFactory().constructCollectionType(List.class, User.class));
    users.forEach(System.out::println);
}

Output

1 valid
null
null
3 valid

So you just ignore/filter null in collection

huangapple
  • 本文由 发表于 2020年9月11日 03:27:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/63836456.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定