How do I call the default deserializer from a custom deserializer in Jackson

前端 未结 11 1046
野趣味
野趣味 2020-11-22 14:26

I have a problem in my custom deserializer in Jackson. I want to access the default serializer to populate the object I am deserializing into. After the population I will do

11条回答
  •  逝去的感伤
    2020-11-22 15:07

    A simpler solution for me was to just add another bean of ObjectMapper and use that to deserialize the object (thanks to https://stackoverflow.com/users/1032167/varren comment) - in my case I was interested to either deserialize to its id (an int) or the whole object https://stackoverflow.com/a/46618193/986160

    import com.fasterxml.jackson.annotation.JsonAutoDetect;
    import com.fasterxml.jackson.annotation.PropertyAccessor;
    import com.fasterxml.jackson.core.JsonParser;
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.*;
    import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
    import org.springframework.context.annotation.Bean;
    
    import java.io.IOException;
    
    public class IdWrapperDeserializer extends StdDeserializer {
    
        private Class clazz;
    
        public IdWrapperDeserializer(Class clazz) {
            super(clazz);
            this.clazz = clazz;
        }
    
        @Bean
        public ObjectMapper objectMapper() {
            ObjectMapper mapper = new ObjectMapper();
            mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            mapper.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, true);
            mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
            mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE);
            mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
            return mapper;
        }
    
        @Override
        public T deserialize(JsonParser jp, DeserializationContext dc) throws IOException, JsonProcessingException {
            String json = jp.readValueAsTree().toString();
              // do your custom deserialization here using json
              // and decide when to use default deserialization using local objectMapper:
              T obj = objectMapper().readValue(json, clazz);
    
              return obj;
         }
    }
    

    for each entity that needs to be going through custom deserializer we need to configure it in the global ObjectMapper bean of the Spring Boot App in my case (e.g for Category):

    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper mapper = new ObjectMapper();
                    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
                mapper.configure(MapperFeature.DEFAULT_VIEW_INCLUSION, true);
                mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
                mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE);
                mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
        SimpleModule testModule = new SimpleModule("MyModule")
                .addDeserializer(Category.class, new IdWrapperDeserializer(Category.class))
    
        mapper.registerModule(testModule);
    
        return mapper;
    }
    

提交回复
热议问题