Java – deserialization error handling

My question is simple: I have the following simple classes:

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

I'm trying to handle the following JSON:

{
  "id": "blah"
}

Obviously, there is a problem ("blah" cannot be resolved to int)

Before, Jackson threw something like org codehaus. jackson. map. Things like jsonmappingexception: you can't construct Java from string value 'blah' Instance of lang. integer: not a valid integer value

I agree with this, but I think somewhere it is allowed to ignore this type of mapping error I tried to register with a deserializationproblemhandler (see here), but it seems to apply only to unknown attributes rather than deserialization problems

Do you have any clues about this problem?

Solution

I successfully solved my problem. Thank you Tatu from Jackson ml

I had to use a custom non blocking deserializer for each primitive type processed in Jackson Factories like this:

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

Then call it this way (pass only those you want to block as a deserializer):

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();
The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>