【问题标题】:Spring Jackson custom Deserializer does not calledSpring Jackson 自定义反序列化器不调用
【发布时间】:2021-11-07 15:18:33
【问题描述】:

我有一个 Spring 项目,我尝试添加一个自定义反序列化器来反序列化 Date 属性,具体取决于它们的格式。 如果我将它用作 Date 属性的注释,它可以正常工作。 但是如果我将反序列化器添加到我的对象映射器中,杰克逊反序列化日期时不会调用它。

我尝试像这样应用我的自定义反序列化器:

    @Bean
public ObjectMapper objectMapper() {
    ObjectMapper mapper = new ObjectMapper();
    SimpleModule module = new SimpleModule();
    module.addDeserializer(Date.class, new DateDeserializer());
    mapper.registerModule(module);
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    mapper.configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false);
    mapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false);
    mapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false);
    mapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);
    return mapper;
}

我不想每次都在 Date 属性上应用注释,我想默认使用这个反序列化器。 我做错了什么?

【问题讨论】:

    标签: spring jackson json-deserialization


    【解决方案1】:

    感谢大家的帮助。 终于在spring.io找到了答案。

    @Configuration
    @EnableWebMvc
    public class WebConfiguration extends WebMvcConfigurerAdapter {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        builder.deserializerByType(Date.class, new DateDeserializer());
        converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
       }
    }
    

    【讨论】:

    • 太棒了!如果答案对您有帮助,您可以投票赞成;)
    【解决方案2】:

    如果您在 Date 属性的注释中使用反序列化器,那么我会说这个 ObjectMapper 没有用于反序列化。请尝试以下操作:

    @Bean
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(ObjectMapper objectMapper) {
       MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter();
       jsonConverter.setObjectMapper(objectMapper);
       return jsonConverter;
    }
    

    【讨论】:

    • 你可能是对的,也许杰克逊没有使用我在我的配置类中定义的那个 ObjectMapper。所以我添加了你建议的 Bean,但是当杰克逊反序列化一个日期时,我的反序列化器仍然没有被调用。
    • 好吧,那么唯一的选择是您在 ObjectMapper 中导入的 Date 与模型中的 Date 不同。这种情况不太可能发生,但你能仔细检查一下吗?无关紧要的小细节:您的配置中有 mapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false); 重复。
    【解决方案3】:

    我怀疑您如何尝试在应用程序中使用此 ObjectMapper bean。

    我相信您已经知道需要在 Configuration 类中创建这个 bean。如果不是,您的 bean 将不会在上下文中注册。比如这样,

    @Configuration
    public class MapperConfig {
        
        @Bean
        public ObjectMapper objectMapper() {
            ObjectMapper mapper = new ObjectMapper();
            SimpleModule module = new SimpleModule();
            module.addDeserializer(Date.class, new DateDeserializer());
            mapper.registerModule(module);
            mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
            mapper.configure(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES, false);
            mapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false);
            mapper.configure(DeserializationFeature.FAIL_ON_INVALID_SUBTYPE, false);
            mapper.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);
            return mapper;
        }
    }
    

    第二个问题可能是你如何尝试使用这个ObjectMapper bean。如果您像这样ObjectMapper objectMapper = new ObjectMapper(); 创建ObjectMapper 的新实例,则该实例将没有您的自定义反序列化器和东西。你可以做的是@Autowire你已经创建的ObjectMapper实例。

    【讨论】:

    • 我在“@Configuration”类中定义了 ObjectMapper bean。我不想“手动”使用 ObjectMapper,有人告诉我杰克逊使用 Bean 定义的 ObjectMapper。但它似乎没有。
    • 您能否为您的DateDeserializer 添加代码并添加您反序列化的位置。
    • 还要确保你的配置类在同一个base-package
    猜你喜欢
    • 2017-09-10
    • 2023-04-10
    • 2016-02-13
    • 2011-04-12
    • 2017-02-14
    • 2016-01-29
    • 1970-01-01
    • 1970-01-01
    • 2017-08-10
    相关资源
    最近更新 更多