杰克逊反序列化错误处理 [英] Jackson deserialization error handling

查看:448
本文介绍了杰克逊反序列化错误处理的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的问题很简单:我有以下简单的类:

My problem is fairly simple : I have the following simple class:

public class Foo {
   private int id = -1;
   public void setId(int _id){ this.id = _id; }
   public int getId(){ return this.id; }
}

我正在尝试处理以下JSON:

And I am trying to process following JSON:

{
  "id": "blah"
}

显然,这里有一个问题(blah无法解析为int)

Obviously, there is a problem here ("blah" cannot be parsed to an int)

以前,杰克逊抛出org.codehaus.jackson.map.JsonMappingException之类的东西:无法从字符串值'blah'构造java.lang.Integer的实例:不是有效的整数值

Formerly, Jackson throws something like org.codehaus.jackson.map.JsonMappingException: Can not construct instance of java.lang.Integer from String value 'blah': not a valid Integer value

我同意这一点,但我想在某处注册一些允许忽略这种映射错误的东西。
我尝试注册DeserializationProblemHandler(请参阅此处),但似乎只适用于未知属性而不是反序列化问题。

I agree with this, but I'd like to register something somewhere allowing to ignore this type of mapping errors. I tried with a DeserializationProblemHandler registered (see here) but it seems to only work on unknown properties and not deserialization problems.

你对这个问题有什么线索吗?

Have you any clue on this issue?

推荐答案

我成功解决了我的问题,感谢来自Jackson ML的Tatu

I succeeded to solve my problem, thanks to Tatu from Jackson ML.

我必须为每个人使用自定义非阻塞反序列化器杰克逊处理的原始类型。
像这个工厂这样的东西:

I had to use custom non blocking deserializers for every primitive types handled in Jackson. Something like this factory :

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;
    }
}

然后以这种方式调用它(仅作为反序列化器传递)你想要非阻塞的那些):

Then calling it like this way (pass as deserializers only those you want to be non blocking) :

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();

这篇关于杰克逊反序列化错误处理的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆