gpt4 book ai didi

java - Spring Boot 升级后 Jackson 序列化不起作用

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:23:56 58 4
gpt4 key购买 nike

昨天我开始从 Spring Brussels-SR3 升级到 Spring Brussels-SR6。
Spring Boot 从 1.5.4 开始。到 1.5.9,Jackson 从 2.8.8 到 2.8.10)。我正在使用 HATEOAS 和 HAL 链接。这意味着我的 Jackson 配置如下所示:

@Configuration
public class JacksonConfiguration {

private static final String SPRING_HATEOAS_OBJECT_MAPPER = "_halObjectMapper";

@Autowired
@Qualifier(SPRING_HATEOAS_OBJECT_MAPPER)
private ObjectMapper springHateoasObjectMapper;

@Primary
@Bean(name = "objectMapper")
ObjectMapper objectMapper() {
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(ZonedDateTime.class, new ZonedDateTimeSerializer(DateTimeFormatter.ISO_INSTANT));

springHateoasObjectMapper.registerModules(javaTimeModule);

springHateoasObjectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
springHateoasObjectMapper.disable(DeserializationFeature.READ_DATE_TIMESTAMPS_AS_NANOSECONDS);

springHateoasObjectMapper.disable(SerializationFeature.WRITE_DATE_TIMESTAMPS_AS_NANOSECONDS);
springHateoasObjectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
springHateoasObjectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);

springHateoasObjectMapper.enable(SerializationFeature.INDENT_OUTPUT);

springHateoasObjectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
return springHateoasObjectMapper;
}
}

这意味着我正在重用 _halObjectMapper bean 并添加更多配置。在我开始升级之前,它一直在工作。

怎么了?

问题是升级后我所有的序列化自定义和 HAL 约定都没有应用 - 日期时间格式,缩进 HAL “_links” JSON 字段更改为“links”......所以_halObjectMapper 不再用于序列化。

任何线索可能是什么问题,或者我应该在哪里挖掘以找出问题所在?

一些调试后的附加信息:

我发现使用 _halObjectMapper 的 TypeConstrainedMappingJackson2HttpMessageConverter 不再用于转换为 json。原因是启动spring的时候没有到达converters的集合。看起来它不是为 RequestMappingHandlerAdapter bean 创建的,因为当 Jackson2HalModule 已经在其他转换器(在本例中为 ProjectingJackson2HttpMessageConverter)中注册时,某些条件会跳过创建。

知道可能是什么原因或在哪里可以弄清楚为什么 spring boot 启动以不同方式进行吗?

更多调试后的附加信息:

我在升级前后看到的区别是,在升级之前,ProjectingJackson2HttpMessageConverter 填充了 ObjectMapper 的新实例。但是在升级之后,ObjectMapper 是从容器中解析出来的,所以选择了 _halObjectMapper。因此,ProjectingJackson2HttpMessageConverter 匹配为具有已注册 halModule 的转换器,并且 TypeConstrainedMappingJackson2HttpMessageConverter 的创建被 RequestMappingHandlerAdapter 省略。

更有趣的是,我升级了两个微服务。不同之处在于,一个有同样的问题,一个正在工作。正在工作的那个具有不同的 spring security 和 oauth2 设置。正在运行的微服务中未定义类 OAuth2RestTemplate 的 Bean。带有 OAuth2RestTemplate 的微服务有问题。我之所以指出这一点,是因为这两种情况下的初始化行为不同。 OAuth2RestTemplate rest 模板也填充了这些转换器,它可能会影响初始化过程。

临时解决方案

作为临时修补程序,我已将 spring-data-commons 从 1.13.6.RELEASE 降级为 1.13.6.RELEASE。然而,较新的代码对我来说更有意义。

我仍在努力获得更好的理解并找出正确的方法

最佳答案

我不知道它是否对你有帮助,但我在将 Spring Boot 从版本 2.0.3 升级到 2.0.4 时遇到了非常相似的问题。我仍然不知道到底是什么导致了这个问题,但解决方案是为我使用的每个模块创建 Bean,而不是替换默认的 ObjectMapper。在您的情况下,它看起来像这样:

    @Configuration
public class JacksonConfiguration {

@Bean
JavaTimeModule javaTimeModule () {
JavaTimeModule javaTimeModule = new JavaTimeModule();
javaTimeModule.addSerializer(ZonedDateTime.class, new ZonedDateTimeSerializer(DateTimeFormatter.ISO_INSTANT));
return javaTimeModule;
}
}

所有功能都可以通过 applications.properties 文件进行设置,如下所示:

spring.jackson.deserialization.FAIL_ON_UNKNOWN_PROPERTIES=false
spring.jackson.deserialization.READ_DATE_TIMESTAMPS_AS_NANOSECONDS=false

等等。有关如何配置默认对象映射器而不实际替换它的更多信息,请参阅 https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#howto-customize-the-jackson-objectmapperhttps://docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html

关于java - Spring Boot 升级后 Jackson 序列化不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47845755/

58 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com