最近项目组用feign调用远程服务,消费端报了如下一个异常
feign-localDateTime异常.png
从异常信息可以得出localdatime反序列化出了异常,而这个异常又是因为jackson无法处理导致。因此我们可以为jackson的ObjectMapper适配一下

1、在pom.xml引入

    <dependency>
                <groupId>com.fasterxml.jackson.datatype</groupId>
                <artifactId>jackson-datatype-jsr310</artifactId>
                <version>${jackson.version}</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.datatype</groupId>
                <artifactId>jackson-datatype-jdk8</artifactId>
                <version>${jackson.version}</version>
            </dependency>

注: jackson-datatype-jsr310这是用来支持jsr310规范的时间,jackson-datatype-jdk8用来支持新的特定于JDK8的类型,例如Optional

2、替换默认的ObjectMapper

@Configuration
public class LocalDateTimeConfig  {
    public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(new Jdk8Module());
        objectMapper.setDateFormat(new SimpleDateFormat(DEFAULT_DATE_TIME_FORMAT));
        objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        objectMapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)));
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)));
        objectMapper.registerModule(javaTimeModule).registerModule(new ParameterNamesModule());
        return objectMapper;

疑问点:为什么替换了默认的ObjectMapper后,feign就可以处理LocalDateTime

@Configuration(proxyBeanMethods = false)
public class FeignClientsConfiguration {
	@Autowired
	private ObjectFactory<HttpMessageConverters> messageConverters;
	@Bean
	@ConditionalOnMissingBean
	public Decoder feignDecoder() {
		return new OptionalDecoder(
				new ResponseEntityDecoder(new SpringDecoder(this.messageConverters)));

而messageConverters默认的转换器是根据HttpMessageConvertersAutoConfiguration而来

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(HttpMessageConverter.class)
@Conditional(NotReactiveWebApplicationCondition.class)
@AutoConfigureAfter({ GsonAutoConfiguration.class, JacksonAutoConfiguration.class, JsonbAutoConfiguration.class })
@Import({ JacksonHttpMessageConvertersConfiguration.class, GsonHttpMessageConvertersConfiguration.class,
		JsonbHttpMessageConvertersConfiguration.class })
public class HttpMessageConvertersAutoConfiguration {
	static final String PREFERRED_MAPPER_PROPERTY = "spring.http.converters.preferred-json-mapper";
	@Bean
	@ConditionalOnMissingBean
	public HttpMessageConverters messageConverters(ObjectProvider<HttpMessageConverter<?>> converters) {
		return new HttpMessageConverters(converters.orderedStream().collect(Collectors.toList()));

ObjectProvider具有延迟加载的功能,会根据实际情况加载。springboot的web模块默认会引入Jackson相关包。官网上有这么一段话
在这里插入图片描述
这个就说明默认的HttpMessageConverter为MappingJackson2HttpMessageConverter,而MappingJackson2HttpMessageConverter会利用objectMapper来进行序列化和反序列化

上面的的话用代码整理如下

 public static final String DEFAULT_DATE_TIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
    @Bean
    public Decoder feignDecoder() {
        return new ResponseEntityDecoder(new SpringDecoder(messageConverters()));
    public ObjectFactory<HttpMessageConverters> messageConverters() {
        return () -> new HttpMessageConverters(mappingJackson2HttpMessageConverter());
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
        return new MappingJackson2HttpMessageConverter(objectMapper());
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.registerModule(new Jdk8Module());
        objectMapper.setDateFormat(new SimpleDateFormat(DEFAULT_DATE_TIME_FORMAT));
        objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        objectMapper.disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE);
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)));
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DEFAULT_DATE_TIME_FORMAT)));
        objectMapper.registerModule(javaTimeModule).registerModule(new ParameterNamesModule());
        return objectMapper;
                    前言最近项目组用feign调用远程服务,消费端报了如下一个异常从异常信息可以得出localdatime反序列化出了异常,而这个异常又是因为jackson无法处理导致。因此我们可以为jackson的ObjectMapper适配一下解决方法1、在pom.xml引入    &lt;dependency&gt;                &lt;groupId&gt;com.fasterxml.jackson.datatype&lt;/groupId&gt;                &
				
场景描述:前端入参的时间格式是字符串,ex:"createTime":"2022-03-08"或者 "createTime":"2022-03-08 16:03:50",后端接受的是Date类型, jackson会报序列异常,这是正常现象,正常思路是要求前后端安装约定参数名和参数类型来交互的,,前端不配合,后端只能 脱裤子妥协了,我们兼容你们前端的任性,还有全局返回的时间格式也统一是字符串,来下面开始 就是请求的时间格式是"createTime":"2022-03-08 16:03:50",响应的
String say(@RequestParam("time")LocalDateTime time); 在处理jsr310规定的LocalDate、LocalDateTime时,feign默认的序列化方式是相当于进行.toString()。 以LocalDateTime为例子,参数实际序列化后的样式是类似以下样式的 201...
通过feign传输localdatetime字段的时候丢失精度的问题通过feign传输localdatetime字段的时候丢失精度的问题总结 通过feign传输localdatetime字段的时候丢失精度的问题 场景:A服务调用到B服务操作,通过Feign需要传递string参数和localdatetime参数过去,在测试的时候发现时间始终对不上。通过dubug后发现A服务传递的localdatetime参数正常,但是B服务接收到localdatetime参数缺失了"秒" 请求侧A服务原代码: Spring Cloud通过Feign客户端调用HTTP接口,如果返回值中包含LocalDateTime类型(包括其他JSR-310中java.time包的时间类),在客户端可能会出现序列化失败的错误。错误信息如下: Caused by:com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `java.time.LocalDateTime` (no Creators
Feign是一个声明式的Web服务客户端,它可以简化HTTP API的调用。在使用Feign进行序列化和序列化配置时,可以采取以下步骤: 首先,根据引用中的描述,最近在Kotlin和Java之间的调用出现了非空字段不能忽略、空串被转换为null以及时间格式无法正确序列化等问题。针对这些问题,我们可以通过自定义Feign序列化和序列化配置来解决。 其次,Feign默认使用Jackson进行序列化和序列化。因此,可以使用Jackson的配置来解决这些问题。根据引用提到的,默认的Feign配置类是FeignClientsConfiguration,其中包含了Jackson的相关配置。 具体来说,可以通过在应用程序的配置类中自定义一个Bean来覆盖Feign的默认配置,如下所示: ```java @Configuration public class FeignConfig { @Autowired private Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder; @Bean public Encoder feignEncoder() { return new JacksonEncoder(jackson2ObjectMapperBuilder.build()); @Bean public Decoder feignDecoder() { return new JacksonDecoder(jackson2ObjectMapperBuilder.build()); 在上述代码中,我们注入了Jackson2ObjectMapperBuilder,并将其用于构建Feign的编码器和解码器。这样就可以使用自定义的Jackson配置来处理序列化和序列化。 需要注意的是,为了使Feign能够使用上述自定义配置,需要将FeignConfig类添加到应用程序的组件扫描路径中。 综上所述,通过自定义Feign序列化和序列化配置,可以解决空串转换为null、非空字段不能忽略和时间格式无法正确序列化等问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Jackson feign调用时序列化配置类](https://blog.csdn.net/weixin_44583244/article/details/125485999)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [自定义 feign 序列化时间字符格式](https://blog.csdn.net/weixin_42116847/article/details/112824286)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]