我的问题很简单:我有以下简单的类:
- public class Foo {
- private int id = -1;
- public void setId(int _id){ this.id = _id; }
- public int getId(){ return this.id; }
- }
我正在尝试处理以下JSON:
- {
- "id": "blah"
- }
显然,这里有一个问题(“blah”不能解析为int)
以前,杰克逊抛出像org.codehaus.jackson.map.JsonMappingException这样的东西:不能从String值’blah’构造java.lang.Integer的实例:不是有效的整数值
我同意这一点,但我想在某处允许忽略这种类型的映射错误.
我尝试使用一个DeserializationProblemHandler注册(见here),但它似乎只适用于未知属性而不是反序列化问题.
你有任何关于这个问题的线索吗?
解决方法
我成功地解决了我的问题,谢谢
Tatu from Jackson ML.
我不得不为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,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;
- }
- }
然后以这种方式调用它(作为解串器传递只有那些你想要阻止的):
- 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,new StdDeserializer.CharacterDeserializer(Character.class,new StdDeserializer.LongDeserializer(Long.class,new StdDeserializer.FloatDeserializer(Float.class,new StdDeserializer.DoubleDeserializer(Double.class,new StdDeserializer.NumberDeserializer(),new StdDeserializer.BigDecimalDeserializer(),new StdDeserializer.BigIntegerDeserializer(),new StdDeserializer.CalendarDeserializer()
- }));
- ObjectMapper om = factory.createObjectMapper();