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

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

问题描述

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

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)

以前,Jackson 抛出类似 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?

推荐答案

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

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

我不得不为 Jackson 中处理的每个原始类型使用自定义的非阻塞反序列化器.像这个工厂的东西:

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

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

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