我正在使用objectMapper,配置为:
protected ObjectMapper getCustomMapper() {
if (this.mapper == null) {
this.mapper = new ObjectMapper();
this.mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
this.mapper.setSerializationInclusion(Inclusion.NON_NULL);
}
return this.mapper;
}
我这样用它:
Email email = this.getCustomMapper().readValue(jsonResponse.toString(), Email.class)
我的问题是如果映射失败,那么ObjectMapper会返回一个新的电子邮件实例,其所有属性都为null。我想知道是否存在某种方式告诉ObjectMapper如果他不能映射json然后返回null,而不是对象的新实例。你知道怎么做吗?此致
编辑:关于案例成功的Json输入是:
{
"user_id":"542d5f15e4b090c7c78c5938",
"email":"test@gmail.com",
"is_primary":true,
"is_confirmed":true,
"creation_date":"2014-10-02T14:20:05Z",
"id":"542d5f15e4b090c7c78c5939"
}
我的Json输入案例失败是:
{
"code":40405,
"message":"Email not found"
}
我希望如果请求失败,那么我的电子邮件对象为空。现在,电子邮件响应不是空的,而且他目前的所有属性都是。
答案 0 :(得分:1)
Jackson不支持此功能,但您可以创建自定义反序列化程序,您可以在其中检查userName是否为null,并根据它返回null对象或转换后的对象。或者您可以选择其他字段或字段集。 在此解决方案中,每次在Email类中添加/更新/删除字段时都不需要更新反序列化器。
自定义反序列化器:
class EmailDeserializer extends JsonDeserializer<Email> {
private JsonDeserializer<Email> delegate;
EmailDeserializer(JsonDeserializer<Email> delegate) {
this.delegate = delegate;
}
@Override
public Email deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
Email result = delegate.deserialize(jp, ctxt);
if (result.getUserId() == null) {
return null;
}
return result;
}
}
如果您不想实现完全反序列化,则需要将委托反序列化器传递给构造函数。在这种情况下,每次更改/添加/删除Email类中的字段时,都不需要更新自定义反序列化程序。由于您正在传递构造函数参数,因此无法使用@JsonDeserialire注释,您需要直接注册它:
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.setSerializationInclusion(JsonSerialize.Inclusion.NON_NULL);
SimpleType simpleType = SimpleType.constructUnsafe(Email.class);
DeserializationConfig deserializationConfig = objectMapper.getDeserializationConfig();
JsonDeserializer deserializer = objectMapper.getDeserializerProvider().findTypedValueDeserializer(deserializationConfig, simpleType, null);
SimpleModule module = new SimpleModule("customModuleName", Version.unknownVersion());
module.addDeserializer(Email.class, new EmailDeserializer(deserializer));
objectMapper.registerModule(module);
答案 1 :(得分:1)
我宁愿将有效电子邮件和错误对象的反序列化分开。
有可能从代码中提到的jsonResponse
变量中获取请求的状态。因此,如果状态代码是错误的(对于HTTP请求大于400),则输入JSON被视为错误,否则它被视为有效的电子邮件。
如果上述情况不可行,我会尝试根据某些属性的存在来猜测对象类型。这是一个例子:
public class JacksonDetectError {
public static final String SUCCESS_JSON = "{ \n" +
" \"user_id\":\"542d5f15e4b090c7c78c5938\",\n" +
" \"email\":\"test@gmail.com\" \n" +
"}";
public static final String ERROR_JSON = "{ \n" +
" \"code\":40405,\n" +
" \"message\":\"Email not found\"\n" +
"}";
public static class Email {
@JsonProperty("user_id")
public String userId;
public String email;
@Override
public String toString() {
return "Email{" +
"userId='" + userId + '\'' +
", email='" + email + '\'' +
'}';
}
}
public static class Error {
public int code;
public String message;
@Override
public String toString() {
return "Error{" +
"code=" + code +
", message='" + message + '\'' +
'}';
}
}
private static Object readJson(String jsonString) throws IOException {
final ObjectMapper mapper = new ObjectMapper();
final JsonNode json = mapper.readTree(jsonString);
if (json.has("code")) {
return mapper.readValue(json.traverse(), Error.class);
}
return mapper.convertValue(json, Email.class);
}
public static void main(String[] args) throws IOException {
System.out.println(readJson(ERROR_JSON));
System.out.println(readJson(SUCCESS_JSON));
}
}
输出:
Error{code=40405, message='Email not found'}
Email{userId='542d5f15e4b090c7c78c5938', email='test@gmail.com'}