Jackson Mapper - 如何在 null 或空值上失败
Jackson Mapper - how to fail on null or empty values
我们在代码中使用 Jackson JSON 映射器来反序列化一些配置对象。我们希望 Jackson 在特定字段缺失或为空时反序列化失败
Jackson 中支持此行为的唯一功能是针对基元的:
final DeserializationConfig.Feature failOnPremitives = DeserializationConfig.Feature.FAIL_ON_NULL_FOR_PRIMITIVES;
问题是有问题的字段主要是字符串
非常感谢任何帮助
你考虑过Bean Validation吗?
虽然 Jackson 专注于 JSON 解析,但 Bean 验证完全是关于对 bean 进行声明和执行验证。
您可以使用 @NotNull
or @NotBlank
from Hibernate Validator,Bean 验证参考实现。
或者您可以使用 JSON Schema。
必须创建特定于对象的自定义反序列化器。
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.io.IOException;
class JacksonDeserializerTest {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule("CustomPersonDeserializer", new Version(1, 0, 0, null, null, null));
module.addDeserializer(Person.class, new CustomPersonDeserializer());
mapper.registerModule(module);
String jsonString = "{ \"id\": 1, \"name\": \"User 1 \"}";
Person user = mapper.readValue(jsonString, Person.class);
System.out.println("User: " + user.toString());
jsonString = "{ \"id\": 1}";
user = mapper.readValue(jsonString, Person.class);
}
static class CustomPersonDeserializer extends StdDeserializer<Person> {
private static final long serialVersionUID = -4100181951833318756L;
public CustomPersonDeserializer() {
this(null);
}
public CustomPersonDeserializer(Class<?> vc) {
super(vc);
}
@Override
public Person deserialize(JsonParser parser, DeserializationContext deserializer) throws IOException, JsonProcessingException {
Person person = new Person();
ObjectCodec codec = parser.getCodec();
JsonNode node = codec.readTree(parser);
JsonNode idNode = node.get("id");
int id = idNode.asInt();
person.setId(id);
JsonNode nameNode = node.get("name");
if(nameNode == null){
throw new IOException("name must be provided");
}
String name = nameNode.asText();
if (name.trim().length() < 1){
throw new IOException("name can not be empty");
}
person.setName(name);
return person;
}
}
static class Person {
private int id;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", id=" + id +
'}';
}
}
}
有一个选项叫做:FAIL_ON_NULL_FOR_CREATOR_PARAMETERS
。
所以我假设它可以在以下位置访问:DeserializationConfig.Feature.FAIL_ON_NULL_FOR_CREATOR_PARAMETERS;
或在yml
中:
jackson:
serialization:
indent-output: false
deserialization:
fail-on-unknown-properties: true
fail-on-missing-creator-properties: true
fail-on-null-creator-properties: true
这适用于所有类型,字符串、整数、双精度等。
替代方式:
这也适用于对象
ObjectMapper mapper= new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
我们在代码中使用 Jackson JSON 映射器来反序列化一些配置对象。我们希望 Jackson 在特定字段缺失或为空时反序列化失败
Jackson 中支持此行为的唯一功能是针对基元的:
final DeserializationConfig.Feature failOnPremitives = DeserializationConfig.Feature.FAIL_ON_NULL_FOR_PRIMITIVES;
问题是有问题的字段主要是字符串
非常感谢任何帮助
你考虑过Bean Validation吗?
虽然 Jackson 专注于 JSON 解析,但 Bean 验证完全是关于对 bean 进行声明和执行验证。
您可以使用 @NotNull
or @NotBlank
from Hibernate Validator,Bean 验证参考实现。
或者您可以使用 JSON Schema。
必须创建特定于对象的自定义反序列化器。
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.core.Version;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.io.IOException;
class JacksonDeserializerTest {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
SimpleModule module = new SimpleModule("CustomPersonDeserializer", new Version(1, 0, 0, null, null, null));
module.addDeserializer(Person.class, new CustomPersonDeserializer());
mapper.registerModule(module);
String jsonString = "{ \"id\": 1, \"name\": \"User 1 \"}";
Person user = mapper.readValue(jsonString, Person.class);
System.out.println("User: " + user.toString());
jsonString = "{ \"id\": 1}";
user = mapper.readValue(jsonString, Person.class);
}
static class CustomPersonDeserializer extends StdDeserializer<Person> {
private static final long serialVersionUID = -4100181951833318756L;
public CustomPersonDeserializer() {
this(null);
}
public CustomPersonDeserializer(Class<?> vc) {
super(vc);
}
@Override
public Person deserialize(JsonParser parser, DeserializationContext deserializer) throws IOException, JsonProcessingException {
Person person = new Person();
ObjectCodec codec = parser.getCodec();
JsonNode node = codec.readTree(parser);
JsonNode idNode = node.get("id");
int id = idNode.asInt();
person.setId(id);
JsonNode nameNode = node.get("name");
if(nameNode == null){
throw new IOException("name must be provided");
}
String name = nameNode.asText();
if (name.trim().length() < 1){
throw new IOException("name can not be empty");
}
person.setName(name);
return person;
}
}
static class Person {
private int id;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", id=" + id +
'}';
}
}
}
有一个选项叫做:FAIL_ON_NULL_FOR_CREATOR_PARAMETERS
。
所以我假设它可以在以下位置访问:DeserializationConfig.Feature.FAIL_ON_NULL_FOR_CREATOR_PARAMETERS;
或在yml
中:
jackson:
serialization:
indent-output: false
deserialization:
fail-on-unknown-properties: true
fail-on-missing-creator-properties: true
fail-on-null-creator-properties: true
这适用于所有类型,字符串、整数、双精度等。
替代方式:
这也适用于对象
ObjectMapper mapper= new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);