英文:
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<MyClass> 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() {}
> 构造函数,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
这样你就可以在集合中忽略/过滤掉null值。
英文:
try @JsonIgnoreProperties(ignoreUnknown = true)
or you may need
JsonFilter or customize serialization
- https://www.baeldung.com/jackson-serialize-field-custom-criteria
- https://stackoverflow.com/questions/35359430/how-to-make-jackson-ignore-properties-if-the-getters-throw-exceptions
ie:
> @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);
}
Output
1 valid
null
null
3 valid
So you just ignore/filter null in collection
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论