OpenFeign

发布时间:2025-09-06 09:20

创建时间:2024-10-08

本文适用的依赖版本:
spring-boot-starter-parent:3.3.3
spring-cloud-starter-openfeign:4.1.3

一、场景

在 REST API 的查询接口中,日期查询参数 的格式一般是标准(ISO 8601)的日期字符串,比如:2024-10-04。常见的查询参数一般为:开始日期(beginDate),结束日期(endDate)。

数据类中日期类型一般使用 LocalDate 或者 Date,但是远程接口中接收的是字符串类型的日期。在使用OpenFeign调用远程接口时,FeignClient中的查询接口需要传递日期类型的查询参数,此时日期参数的参数类型,应该如何处理?

其中一种方法时,直接将FeignClient中的日期类型定为 String,然后在调用FeignClient接口的位置,将 LocalDate 或 Date 转为日期字符串。不过这种方法需要每次调用接口前都要做一次转换,比较繁琐,不够简洁,不推荐使用。

另一种是在FeignClient中的接口,使用 LocalDate 或 Date 类型表示日期,然后在实际调用远程接口时,由Feign框架将LocalDate或Date类型转为字符串类型的日期,此时需要使用@DateTimeFormat注解进行日期格式化。下面主要介绍这种方法。

二、@DateTimeFormat格式化日期

FeignClient

使用 @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) 修饰日期查询参数,可以将日期类型转为字符串类型的日期。

@DateTimeFormat(iso = DateTimeFormat.ISO.DATE) ,代表指定的日期格式是 ISO 的日期格式。使用 @DateTimeFormat(pattern = “yyyy-MM-dd”),还可以指定其他的日期格式。

package com.example.hello_feign_client.feign.client; import com.example.hello_common.model.query.LocalDateQuery; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.cloud.openfeign.SpringQueryMap; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import java.time.LocalDate; import java.util.Date; @FeignClient(contextId = "dateFeignClient", name = "hello-feign-server", url = "${service.hello-feign-server.url}", path = "/date") public interface DateFeignClient { @GetMapping("/localDate") String getDate(@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate localDate); @GetMapping("/localDateQuery") String getDateQuery(@SpringQueryMap LocalDateQuery localDateQuery); @GetMapping("/date") String getDate(@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) Date date); }

java

运行

调用FeignClient

package com.example.hello_feign_client.web.date.controller; import com.example.hello_common.model.query.LocalDateQuery; import com.example.hello_feign_client.feign.client.DateFeignClient; import lombok.RequiredArgsConstructor; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.time.LocalDate; import java.util.Date; @RestController @RequestMapping("/date") @RequiredArgsConstructor public class DateController { private final DateFeignClient dateFeignClient; @GetMapping("/localDate") public String getDate(@DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate localDate) { return dateFeignClient.getDate(localDate); } @GetMapping("/localDateQuery") public String getDateQuery(LocalDateQuery localDateQuery) { return dateFeignClient.getDateQuery(localDateQuery); } @GetMapping("/date") public String getDate(@DateTimeFormat(iso = DateTimeFormat.ISO.DATE) Date date) { return dateFeignClient.getDate(date); } }

java

运行

LocalDateQuery

package com.example.hello_common.model.query; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDate; @Data public class LocalDateQuery { @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) private LocalDate beginDate; @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) private LocalDate endDate; }

java

运行

远程接口

package com.example.hello_feign_server.web.date.controller; import com.example.hello_common.model.query.LocalDateQuery; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.time.LocalDate; import java.util.Date; @RestController @RequestMapping("/date") public class DateController { @GetMapping("/localDate") public String getDate(@DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate localDate) { return "根据日期(LocalDate)查询数据。查询参数:" + localDate; } @GetMapping("/localDateQuery") public String getDateQuery(LocalDateQuery localDateQuery) { return "根据日期Query(LocalDateQuery)查询数据。查询参数:" + localDateQuery; } @GetMapping("/date") public String getDate(@DateTimeFormat(iso = DateTimeFormat.ISO.DATE) Date date) { return "根据日期(Date)查询数据。查询参数:" + date; } }

java

运行

三、接口调用效果

远程接口

在这里插入图片描述
在这里插入图片描述

FeignClient调用远程接口效果

@RequestParam 直接传递请求参数

在这里插入图片描述

FeignClient接口调用日志:

在这里插入图片描述

@SpringQueryMap传递请求参数对象

在这里插入图片描述

FeignClient接口调用日志:

在这里插入图片描述

四、Date与@DateTimeFormat

@RequestParam + @DateTimeFormat + Date,有效

FeignClient 和 调用FeignClient 的代码,在上面的代码中已经给出。

调用效果:

在这里插入图片描述

FeignClient日志:

在这里插入图片描述

@SpringQueryMap + @DateTimeFormat + Date,无效

注意,在 @SpringQueryMap 修饰的参数对象中,如果使用了 java.util.Date 类型的字段,此时 @DateTimeFormat 是无效的。

比如下面代码中的 endDate

package com.example.hello_common.model.query; import lombok.Data; import org.springframework.format.annotation.DateTimeFormat; import java.time.LocalDate; import java.util.Date; @Data public class LocalDateQuery { @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) private LocalDate beginDate; @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) private Date endDate; }

java

运行

报错如下:

在这里插入图片描述
在这里插入图片描述

五、@DateTimeFormat在Feign低版本无效

经过测试,在 SpringBoot1.5 中,@RequestParam + @DateTimeFormat + Date是无效的。

请参考:

https://blog.csdn.net/hysxchina/article/details/102907861

在这里插入图片描述

网址:OpenFeign https://www.yuejiaxmz.com/news/view/1277935

相关内容

完整springcloudalibaba项目搭建教程(新手入门)
老衲的少女心i/小猪优选

随便看看