asi*_*swt 8 java json jackson deserialization
杰克逊在处理反序列化映射过程中出现的异常怪异的行为:它抛出一个JsonMappingException,其.getCause()返回异常链的最里面.
//in main
ObjectMapper jsonMapper = new ObjectMapper();
String json = "{\"id\": 1}";
try {
Q q = jsonMapper.readValue(json, Q.class);
} catch (JsonMappingException e) {
System.out.println(e.getCause()); //java.lang.RuntimeException: ex 2
}
//class Q
public class Q {
@JsonCreator
public Q(@JsonProperty("id") int id) {
throw new RuntimeException("ex 0",
new RuntimeException("ex 1",
new RuntimeException("ex 2")));
}
}
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,我使用jsonMapper.readValue(..)将String映射json到类的实例,Q其构造函数标记为@JsonCreator抛出一个链RuntimeException:"ex 0", "ex 1", "ex 2".当映射失败时,我预计该行将System.out.println(e.getCause());打印出来ex 0,但它会打印出来ex 2.
为什么杰克逊决定这样做,有没有办法配置它,以便它不丢弃我的ex 0?我试过了
jsonMapper.configure(DeserializationFeature.WRAP_EXCEPTIONS, false);
Run Code Online (Sandbox Code Playgroud)
但它没有做任何事情.
StdValueInstantiator在反序列化期间抛出异常时,Jackson的内部会触发此方法:
protected JsonMappingException wrapException(Throwable t)
{
while (t.getCause() != null) {
t = t.getCause();
}
if (t instanceof JsonMappingException) {
return (JsonMappingException) t;
}
return new JsonMappingException("Instantiation of "+getValueTypeDesc()+" value failed: "+t.getMessage(), t);
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,这将迭代嵌套运行时异常的每个"级别",并设置它命中的最后一个作为JsonMappingException它返回的原因.
以下是我需要的代码:
将新模块注册到ObjectMapper.
@Test
public void testJackson() {
ObjectMapper jsonMapper = new ObjectMapper();
jsonMapper.registerModule(new MyModule(jsonMapper.getDeserializationConfig()));
String json = "{\"id\": \"1\"}";
try {
Q q = jsonMapper.readValue(json, Q.class);
System.out.println(q.getId());
} catch (JsonMappingException e) {
System.out.println(e.getCause()); //java.lang.RuntimeException: ex 2
} catch (JsonParseException e) {
} catch (IOException e) {
}
}
Run Code Online (Sandbox Code Playgroud)创建自定义模块类.
public class MyModule extends SimpleModule {
public MyModule(DeserializationConfig deserializationConfig) {
super("MyModule", ModuleVersion.instance.version());
addValueInstantiator(Q.class, new MyValueInstantiator(deserializationConfig, Q.class));
addDeserializer(Q.class, new CustomDeserializer());
}
}
Run Code Online (Sandbox Code Playgroud)创建ValueInstantiator要覆盖的自定义类wrapException(...).将实例化器添加到模块.
public class MyValueInstantiator extends StdValueInstantiator {
public MyValueInstantiator(DeserializationConfig config, Class<?> valueType) {
super(config, valueType);
}
@Override
protected JsonMappingException wrapException(Throwable t) {
if (t instanceof JsonMappingException) {
return (JsonMappingException) t;
}
return new JsonMappingException("Instantiation of "+getValueTypeDesc()+" value failed: "+t.getMessage(), t);
}
}
Run Code Online (Sandbox Code Playgroud)创建自定义反序列化器以使模块正常工作.将此类添加到模块初始化中.
public class CustomDeserializer extends StdScalarDeserializer<Q> {
public CustomDeserializer() {
super(Q.class);
}
@Override
public Q deserialize(JsonParser jp, DeserializationContext context) throws IOException {
JsonNode node = jp.getCodec().readTree(jp);
return new Q(node.get("id").asText());
}
@Override
public Object deserializeWithType(JsonParser jp, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws IOException {
return deserialize(jp, ctxt);
}
}
Run Code Online (Sandbox Code Playgroud)| 归档时间: |
|
| 查看次数: |
7933 次 |
| 最近记录: |