springcloud feign服务之间调用,date类型转换错误的问题

  1. 引言

在使用 Spring Cloud Feign 调用服务时,常常会遇到日期类型转换错误的问题。因为在服务之间传递日期类型时,很多时候并不使用标准的时间格式(如 ISO 8601),而是使用自定义的日期格式。本篇文章将介绍如何使用 SpringBoot 的自动配置机制来解决这个问题。

  1. 问题描述

假设我们有一个服务 A 和一个服务 B,A 通过 Feign 调用 B。在传递请求参数时,A 将日期格式转换为自定义格式:

@RestController
public class ServiceAController {
    @Autowired
    private ServiceBClient serviceBClient;

    @GetMapping("test")
    public String test() {
        return serviceBClient.test(new Date());
    }
}

@FeignClient("service-b")
public interface ServiceBClient {
    @GetMapping("test")
    String test(@RequestParam("date") String date);
}

我们使用这样的方式来调用服务 B 中的 test() 方法。但是,如果服务 B 是使用默认的 Jackson 序列化方式进行 JSON 传递的,则服务 B 则无法正确地进行日期类型的反序列化。最终导致出现类似以下的错误:

com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.time.LocalDate` from String "2021-01-01 00:00:00": Failed to deserialize java.time.LocalDate: (java.time.format.DateTimeParseException) Text '2021-01-01 00:00:00' could not be parsed, unable to obtain LocalDateTime from TemporalAccessor: {MinuteOfHour=0, SecondOfMinute=0, NanoOfSecond=0, MicroOfSecond=0, MilliOfSecond=0, HourOfAmPm=0}, ISO resolved to 2021-01-01 of type java.time.format.Parsed
  1. 解决方案

为了解决该问题,我们需要对 Feign 的请求参数进行自定义序列化和反序列化。具体实现可以通过 SpringBoot 的自动配置机制来实现。

首先,我们需要创建一个实现了Spring 官方提供的ConditionalOnClass和 ConditionalOnMissingBean注解的自动配置类:

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ ObjectMapper.class, Feign.class })
@EnableConfigurationProperties(FeignDateTimeProperties.class)
public class FeignDateTimeFormatConfiguration {

    @Autowired(required = false)
    private List<Module> jacksonModules = Collections.emptyList();

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(value = "feign.date-format.enabled", havingValue = "true", matchIfMissing = false)
    public Encoder feignEncoder(ObjectMapper objectMapper, FeignDateTimeProperties properties) {
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(Date.class, new DateSerializer(properties.getDateFormat()));
        objectMapper.registerModule(simpleModule);
        objectMapper.registerModules(jacksonModules);
        return new JacksonEncoder(objectMapper);
    }

    @Bean
    @ConditionalOnMissingBean
    @ConditionalOnProperty(value = "feign.date-format.enabled", havingValue = "true", matchIfMissing = false)
    public Decoder feignDecoder(ObjectMapper objectMapper, FeignDateTimeProperties properties) {
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addDeserializer(Date.class, new DateDeserializer(properties.getDateFormat()));
        objectMapper.registerModule(simpleModule);
        objectMapper.registerModules(jacksonModules);
        return new JacksonDecoder(objectMapper);
    }
}

通过这个配置类,我们可以使用自定义序列化和反序列化器来处理 Feign 请求中传递的日期类型参数。在实现自定义序列化和反序列化器时,我们需要定义两个类:DateSerializer 和 DateDeserializer。

public class DateSerializer extends JsonSerializer<Date> {

    private final SimpleDateFormat formatter;

    public DateSerializer(String dateFormatPattern) {
        this.formatter = new SimpleDateFormat(dateFormatPattern);
    }

    @Override
    public void serialize(Date value, JsonGenerator gen, SerializerProvider provider)
            throws IOException {
        gen.writeString(formatter.format(value));
    }
}

public class DateDeserializer extends JsonDeserializer<Date> {

    private final SimpleDateFormat formatter;

    public DateDeserializer(String dateFormatPattern) {
        this.formatter = new SimpleDateFormat(dateFormatPattern);
    }

    @Override
    public Date deserialize(JsonParser p, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {
        try {
            return formatter.parse(p.getText());
        } catch (ParseException e) {
            throw new RuntimeException(e);
        }
    }
}

这样,我们就可以使用自己定义的序列化和反序列化器处理日期类型参数了。配置文件中需要设置一下自定义的日期格式:

## service-b
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
feign.date-format.enabled=true
feign.date-format.date-format-pattern=${spring.jackson.date-format}

最后,我们需要在 feign client 中添加上configuration配置

@FeignClient(value = "service-b", configuration = {FeignDateTimeFormatConfiguration.class})
public interface ServiceBClient {

    @RequestMapping(method = RequestMethod.GET, value = "/test")
    String test(@RequestParam("date") Date date);

}
  1. 示例说明

请参考示例代码:springcloud-feign-date-conversion-demo

该示例中包含了调用服务 A 和服务 B 的完整业务代码,以及如何使用 SpringBoot 自动配置机制解决服务之间日期类型转换问题的示例代码。

  1. 总结

本篇文章介绍了如何使用 SpringBoot 的自动配置机制解决 Feign 服务间传递日期类型参数出现的转换错误问题。首先,我们需要创建一个自动配置类,定义自定义的序列化器和反序列化器来处理日期类型参数。其次,需要在配置文件中设置日期格式。最后,我们需要在 Feign Client 中添加 configuration 配置,来使用自定义的序列化器和反序列化器。

注意:该解决方案只适用于使用 JSR-310 或者 Java 8 日期类库之前的版本。如果当前已使用这些日期类库,建议一定要使用标准的时间格式进行传输。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:springcloud feign服务之间调用,date类型转换错误的问题 - Python技术站

(0)
上一篇 2023年5月13日
下一篇 2023年5月13日

相关文章

  • Vue项目报错:parseComponent问题及解决

    以下是关于“Vue项目报错:parseComponent问题及解决”的完整攻略: 问题描述 在使用Vue开发Web应用时,可能会遇到“parseComponent”的错误。这个错误通常是由于组件文件中存在语法错误或格式错误导致的。 解决步骤 以下是解决“parseComponent”的步骤: 步骤一:了解问题 首先,需要了解这个问题的原因。这个问题通常是由于…

    http 2023年5月13日
    00
  • HTTPS的工作原理是什么?

    HTTP是一种基于传输控制协议(TCP)的应用层协议,其主要用于Web浏览器和Web服务器之间的通信。但是,HTTP协议传输的内容不加密,因此容易被拦截、窃取或篡改,为了保证通信的安全性,人们引入了HTTPS协议。 HTTPS全称为超文本传输安全协议,是一个基于TLS/SSL协议的加密协议。具体来说,HTTPS协议通过使用SSL/TLS协议中的加密机制,对数…

    云计算 2023年4月27日
    00
  • Android WebView如何判定网页加载的错误

    当使用Android WebView加载网页时,可能会出现网页无法正常加载的情况。这种情况下需要对错误进行判定以便进行相应的处理。 以下是详细的Android WebView如何判定网页加载错误的攻略: 1. 设置 WebViewClient 首先,需要在使用 WebView 前先设置 WebViewClient。WebViewClient 中有许多回调方法…

    http 2023年5月13日
    00
  • springboot读取application.yml报错问题及解决

    “SpringBoot读取application.yml报错问题及解决”主要是由于读取到的配置属性与代码中使用的属性不一致导致的,下面给出详细的解决攻略。 问题描述 SpringBoot项目中使用application.yml作为配置文件,但是运行时却遇到了以下报错: Caused by: org.springframework.boot.context.p…

    http 2023年5月13日
    00
  • create-react-app常用自定义配置教程示例

    创建React应用的过程需要配置很多东西,create-react-app就是专门为我们搭建React应用而设计的CLI工具,可以帮助我们快速构建React应用,省去了很多配置的麻烦。但是有时候我们也需要在create-react-app的基础上进行一些自定义配置,本文将详细讲解create-react-app常用自定义配置教程示例。 1. 添加SASS支持…

    http 2023年5月13日
    00
  • 高并发下restTemplate的错误分析方式

    我们来讲解一下“高并发下restTemplate的错误分析方式”这个话题。 高并发下的问题 在高并发的情况下,restTemplate 可能会出现一些问题,如连接超时、请求超时、连接池被占满等问题。 这些问题可能会导致服务不可用或响应变慢,需要我们做一些分析和优化工作来避免这些问题的出现。 错误分析的方式 抓包分析 抓包分析可以帮助我们查看网络请求的详细信息…

    http 2023年5月13日
    00
  • 一文教你解决Vue所有报错

    下面我将详细讲解“一文教你解决Vue所有报错”的完整攻略。 一、前言 在学习和使用Vue的过程中,我们难免会遇到各种各样的报错。有些错误可能十分简单,只需要翻看官方文档就能轻松解决,而另一些错误可能会令我们疑惑不解。本篇文章将覆盖大多数Vue出现的报错情况,并提供解决这些问题的方法。 二、报错分类 基于Vue的报错内容,我们可以将其分为以下几类: 语法错误 …

    http 2023年5月13日
    00
  • CentOS8使用阿里云yum源异常问题及解决方法

    以下是关于“CentOS8使用阿里云yum源异常问题及解决方法”的完整攻略: 简介 CentOS是一款流行的Linux操作系统,可以用于服务器和桌面应用程序。在OS时,我们通常会使用包管理器来安装和更新软件包。阿里云提供了一些yum源,可以加速软件的下载和安装。但是,在使用阿里云yum时,有时会遇到异常问题。本文将介绍如何解决CentOS8使用里云yum源异…

    http 2023年5月13日
    00
合作推广
合作推广
分享本页
返回顶部