How to configure Jackson deserializer for Retrofit2 responses via Jackson2ObjectMapperBuilderCustomizer class?

huangapple go评论76阅读模式
英文:

How to configure Jackson deserializer for Retrofit2 responses via Jackson2ObjectMapperBuilderCustomizer class?

问题

我正在使用Retrofit2在Spring Batch应用程序中调用远程Web服务,为了反序列化JSON响应,我想通过Jackson2ObjectMapperBuilderCustomizer类配置全局Jackson反序列化器。

我的配置是:

  • Spring Boot版本3.0.6
  • Retrofit版本2.9.0
  • Jackson版本2.13.5

我已经尝试在Jackson2ObjectMapperBuilder对象中定义ObjectMapper配置,它可以工作,但我仍然需要在每个RetrofitBuilder()调用上指定.addConverter(JacksonConverterFactory.create(<builder>)

@Configuration
public class MyRestWSImpl {

    @Bean
    MyRestWS myRestWS (@Value("${url}") String url) {
        return new RetrofitBuilder()
            .url(url)
            .addConverter(JacksonConverterFactory.create(
                new Jackson2ObjectMapperBuilder()
                    .deserializers(new LocalDateTimeDeserializer(MY_DATE_TIME_FORMATTER))
                    .build()
            )
            .client()
            .configure()
            .build()
            .create(MyRestWS.class);
    }
}

我正在寻找更好的选项。是否有一种方法可以通过使用Jackson2ObjectMapperBuilderCustomizer功能接口来实现相同的结果?

我尝试定义一个类型为Jackson2ObjectMapperBuilderCustomizer的Bean,如此处所示,但似乎Retrofit2并没有考虑到这个Bean,尽管该Bean已经被创建:

@Configuration
public class JacksonConfig {

    @Bean
    Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() {
        return builder -> builder
            .deserializers(new LocalDateTimeDeserializer(MY_DATE_TIME_FORMATTER));
    }
}

控制台输出:

DefaultSingletonBeanRegistry  : Creating shared instance of singleton bean 'jsonCustomizer'
...
com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.time.LocalDateTime` from String "2023-05-26 17:04:52"
英文:

I am using Retrofit2 to call distant web services in a Spring Batch application, and for deserializing JSON responses I would like to configure a global Jackson deserializer via the Jackson2ObjectMapperBuilderCustomizer class.
My configuration is:

  • Spring Boot version 3.0.6
  • Retrofit version 2.9.0
  • Jackson version 2.13.5

I've already tried to define ObjectMapper configuration in a Jackson2ObjectMapperBuilder object and it works, but I still need to specify .addConverter(JacksonConverterFactory.create(<builder>) on each RetrofitBuilder() call:

@Configuration
public class MyRestWSImpl {

    @Bean
    MyRestWS myRestWS (@Value("${url}") String url) {
        return new RetrofitBuilder()
            .url(url)
            .addConverter(JacksonConverterFactory.create(
                new Jackson2ObjectMapperBuilder()
                    .deserializers(new LocalDateTimeDeserializer(MY_DATE_TIME_FORMATTER))
                    .build()
            )
            .client()
            .configure()
            .build()
            .create(MyRestWS.class);
    }
}

I'm searching for a better option.
Is there a way in which I can achieve the same result by using the Jackson2ObjectMapperBuilderCustomizer functional interface instead?

I tried to define a bean of type Jackson2ObjectMapperBuilderCustomizer as seen here, but it does not seem to be taken into account by Retrofit2, although the bean is created:

@Configuration
public class JacksonConfig {

    @Bean
    Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() {
        return builder -> builder
            .deserializers(new LocalDateTimeDeserializer(MY_DATE_TIME_FORMATTER));
    }
}

Console:

DefaultSingletonBeanRegistry  : Creating shared instance of singleton bean 'jsonCustomizer'
...
com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.time.LocalDateTime` from String "2023-05-26 17:04:52"

答案1

得分: 0

如果您想使用自定义器,您应该将 Jackson2ObjectMapperBuilder 注入到您的 bean 中,并使用它来构建对象映射器。

例如:

    @Bean
    SonarqubeClient sonarqubeClient(SonarqubeProperties sonarqubeProperties, Jackson2ObjectMapperBuilder objectMapperBuilder) {
        ObjectMapper objectMapper = objectMapperBuilder.build();
英文:

If you want to use the customizer, you should inject a Jackson2ObjectMapperBuilder into your bean and use it to build the object mapper.

e.g.

    @Bean
	SonarqubeClient sonarqubeClient(SonarqubeProperties sonarqubeProperties, Jackson2ObjectMapperBuilder objectMapperBuilder) {
		ObjectMapper objectMapper = objectMapperBuilder.build();

huangapple
  • 本文由 发表于 2023年7月14日 02:43:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/76682387.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定