Java 如何告诉Jackson在反序列化过程中跳过无效记录?
我有一个包含数百万条记录的JSON文件。我想使用Jackson迭代器一次读取一条记录,并对每条记录执行一个操作。这是到目前为止的代码Java 如何告诉Jackson在反序列化过程中跳过无效记录?,java,jackson,Java,Jackson,我有一个包含数百万条记录的JSON文件。我想使用Jackson迭代器一次读取一条记录,并对每条记录执行一个操作。这是到目前为止的代码 MappingIterator<MyClass> iterator = new ObjectMapper() .readerFor(MyClass.class) .readValues(file); while (iterator.hasNext()) { MyClass object = iterator.n
MappingIterator<MyClass> iterator = new ObjectMapper()
.readerFor(MyClass.class)
.readValues(file);
while (iterator.hasNext()) {
MyClass object = iterator.next();
...
}
MappingIterator迭代器=新的ObjectMapper()
.readerFor(MyClass.class)
.readValues(文件);
while(iterator.hasNext()){
MyClass对象=迭代器。下一步();
...
}
问题是,由于缺少引号或非法字符,一些记录无效。这会导致Jackson抛出异常并退出。如何告诉Jackson跳过这些记录并继续解析剩余的有效记录?试试
@JsonIgnoreProperties(ignoreUnknown=true)
,或者您可能需要
JsonFilter或自定义序列化
- 即:
因此,您只需忽略集合中的/filter null数据中没有任何未知属性。唯一的问题是JSON格式不好。我明白了,所以您必须使用这个注释@JsonDeserialize(使用=YourCuztomeDeserializer.class)自定义反序列化因此,使用try/catch块,您可以跳过所有引发异常的行,因为JSON格式不正确。您可以按照以下示例查看它们如何自定义序列化--我尝试了自定义反序列化程序,但它也没有帮助。在反序列化程序中捕获异常后,Jackson然后尝试解析文件中第一个非法字符之后开始的下一条记录,这不是新记录的开始。这会导致迭代器.hasNext()引发异常。我只是添加了我的示例,可能有助于uTry将
{\'id\':2,\'name\':invalid}
替换为{\'id\':2,\'name:\'invalid\'}
(缺少结束引号)您将看到这种方法不起作用的原因。是否要添加try-catch来处理RuntimeJsonMappingException
?如果它导致JsonMappingException
,请跳过它?我尝试过了。我从迭代器.next()中得到了一个异常。然后我从迭代器.hasNext()中再次得到了相同的异常。这使得无法继续分析该文件。
@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<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