加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – 杰克逊反序列化错误处理

发布时间:2020-12-14 16:32:12 所属栏目:Java 来源:网络整理
导读:我的问题很简单:我有以下简单的类: 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”不能解析为i
我的问题很简单:我有以下简单的类:
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();

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读