Fré*_*ric 17 java json jackson deserialization
我的问题很简单:我有以下简单的类:
public class Foo {
private int id = -1;
public void setId(int _id){ this.id = _id; }
public int getId(){ return this.id; }
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试处理以下JSON:
{
"id": "blah"
}
Run Code Online (Sandbox Code Playgroud)
显然,这里有一个问题("blah"无法解析为int)
以前,Jackson会抛出类似org.codehaus.jackson.map.JsonMappingException的东西:无法从String值'blah'构造java.lang.Integer的实例:不是有效的Integer值
我同意这一点,但我想在某处注册一些允许忽略这种映射错误的东西.我尝试使用注册的DeserializationProblemHandler(参见此处),但它似乎只适用于未知属性而不是反序列化问题.
你对这个问题有什么线索吗?
Fré*_*ric 16
感谢Jack ML的Tatu,我成功地解决了我的问题.
我必须为Jackson中处理的每种原始类型使用自定义非阻塞反序列化器.像这个工厂的东西:
public class JacksonNonBlockingObjectMapperFactory {
/**
* Deserializer that won't block if value parsing doesn't match with target type
* @param <T> Handled type
*/
private static class NonBlockingDeserializer<T> extends JsonDeserializer<T> {
private StdDeserializer<T> delegate;
public NonBlockingDeserializer(StdDeserializer<T> _delegate){
this.delegate = _delegate;
}
@Override
public T deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
try {
return delegate.deserialize(jp, ctxt);
}catch (JsonMappingException e){
// If a JSON Mapping occurs, simply returning null instead of blocking things
return null;
}
}
}
private List<StdDeserializer> jsonDeserializers = new ArrayList<StdDeserializer>();
public ObjectMapper createObjectMapper(){
ObjectMapper objectMapper = new ObjectMapper();
SimpleModule customJacksonModule = new SimpleModule("customJacksonModule", new Version(1, 0, 0, null));
for(StdDeserializer jsonDeserializer : jsonDeserializers){
// Wrapping given deserializers with NonBlockingDeserializer
customJacksonModule.addDeserializer(jsonDeserializer.getValueClass(), new NonBlockingDeserializer(jsonDeserializer));
}
objectMapper.registerModule(customJacksonModule);
return objectMapper;
}
public JacksonNonBlockingObjectMapperFactory setJsonDeserializers(List<StdDeserializer> _jsonDeserializers){
this.jsonDeserializers = _jsonDeserializers;
return this;
}
}
Run Code Online (Sandbox Code Playgroud)
然后像这样调用它(仅作为反序列化器传递给你想要非阻塞的那些):
JacksonNonBlockingObjectMapperFactory factory = new JacksonNonBlockingObjectMapperFactory();
factory.setJsonDeserializers(Arrays.asList(new StdDeserializer[]{
// StdDeserializer, here, comes from Jackson (org.codehaus.jackson.map.deser.StdDeserializer)
new StdDeserializer.ShortDeserializer(Short.class, null),
new StdDeserializer.IntegerDeserializer(Integer.class, null),
new StdDeserializer.CharacterDeserializer(Character.class, null),
new StdDeserializer.LongDeserializer(Long.class, null),
new StdDeserializer.FloatDeserializer(Float.class, null),
new StdDeserializer.DoubleDeserializer(Double.class, null),
new StdDeserializer.NumberDeserializer(),
new StdDeserializer.BigDecimalDeserializer(),
new StdDeserializer.BigIntegerDeserializer(),
new StdDeserializer.CalendarDeserializer()
}));
ObjectMapper om = factory.createObjectMapper();
Run Code Online (Sandbox Code Playgroud)
您可能希望让控制器通过添加处理此特定异常的方法来处理问题
@ExceptionHandler(HttpMessageNotReadableException.class)
@ResponseBody
public String handleHttpMessageNotReadableException(HttpMessageNotReadableException ex)
{
JsonMappingException jme = (JsonMappingException) ex.getCause();
return jme.getPath().get(0).getFieldName() + " invalid";
}
Run Code Online (Sandbox Code Playgroud)
当然,行
JsonMappingException jme = (JsonMappingException) ex.getCause();
Run Code Online (Sandbox Code Playgroud)
某些情况下可能会抛出一个类强制转换异常,但我还没有遇到它们.
归档时间: |
|
查看次数: |
29291 次 |
最近记录: |