rest - FeignClient 正在更改传递给它的 LocalDate 的格式

标签 rest spring-cloud-feign localdate

我的应用程序中有一个 @FeignClient:

@FeignClient(name="${mongo.service.id}", url="${mongo.service.url}")
public interface MongoCustomerClaimInterface {
    @GetMapping(path = "/api/customerClaim/countClaims/{businessDate}")
    List<TransactionClaimStatusData> countClaimsByStatusToBusinessDate(
    @PathVariable @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) 
    LocalDate businessDate);
}

我调用 feign 方法并将格式化的 LocalDate 变量传递给它,并将其打印到日志中:

LocalDate businessDate = getBusinessDate();
LocalDate formattedDate = LocalDate.parse(businessDate.toString(), 
                                          DateTimeFormatter.ISO_DATE);
log.info("formattedDate: " + formattedDate);
claimStatusDataList = mongoCustomerClaimInterface.countClaims(formattedDate);

调用生成 404 错误和日志:

2020-24-02 18:10:25.433 INFO  DashboardServiceImpl - formattedDate: 2020-02-23
2020-24-02 18:10:25.440 DEBUG
RequestMappingHandlerMapping:
Looking up handler method for path /api/customerClaim/countClaims/2/23/20
RequestMappingHandlerMapping:
Did not find handler method for [/api/customerClaim/countClaims/2/23/20]

尽管我以 yyyy-mm-dd 格式传递日期,所以它会匹配:

  • @DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
  • 假装以某种方式更改日期,然后找不到匹配的 url

如何防止 Feign 这样做并配置统一的格式化程序?

最佳答案

很明显,Feign 并未使用所有 SpringMvc 注释。 @DateTimeFormat,尽管它很棒,但它是一个 SpringMvc 注释而不是 FeignClient 注释。 我通过做几件事解决了这个问题:

  1. 在我的 MvcConfig 类中创建了一个 MessageConvertersConfiguration 类。 在其中,我创建了一个 LocalDate 和 LocalDateTime 转换器 bean,并将其添加到此配置器在 http 消息到达时使用的转换器列表中:
@Configuration
public class MvcConfig {
    
    @Configuration
    @EnableWebMvc
    public class MessageConvertersConfiguration implements WebMvcConfigurer {
        @Override
        public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
          converters.add(new MappingJackson2HttpMessageConverter(localDateTimeConverter()));
        }

        @Bean
        public ObjectMapper localDateTimeConverter() {
            ObjectMapper mapper = new ObjectMapper();
            SimpleModule localDateTimeModule = new SimpleModule();

            DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd-MM-yyyy'T'HH:mm:ss");
            localDateTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(dateTimeFormatter));
            localDateTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(dateTimeFormatter));

            DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            localDateTimeModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(dateFormatter));
            localDateTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(dateFormatter));

            mapper.registerModules(localDateTimeModule);

            return mapper;
        }
    }
}
  1. 为我的虚拟客户端创建了一个配置类。在其中,我实例化了一个 SpringMvcContract。因为 Feign 是在 SpringMvc 之前创建的,所以我们刚刚定义的转换器不会影响没有此契约的 feign:
@Configuration
public class FeignConfig {
    @Bean
    public Contract feignContract() {
        return new SpringMvcContract();
    }
}
  1. 最后,我将配置属性添加到我的 FeignClient:
@FeignClient(name="${mongo.service.id}", url="${mongo.service.url}", configuration = FeignConfig.class)
public interface MongoCustomerClaimInterface {
    @GetMapping(path = "/api/customerClaim/countClaimsByStatusToBusinessDate/{businessDate}")
    List<TransactionClaimStatusData> countClaimsByStatusToBusinessDate(@PathVariable @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate businessDate);
}

关于rest - FeignClient 正在更改传递给它的 LocalDate 的格式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60380148/

相关文章:

java - 如何在Java 8中查找下个月的第一个星期日?

java - 有没有办法在实现 @Path 的方法内部获得 REST Api 的完整 API 签名

azure - 如何在响应中将两个变量合并为一个?

spring-security - 微服务之间的安全性

spring-boot - springboot找不到feignclient

java - 计算包括两个给定日期的天数

java - 日期时间解析异常 : Text could not be parsed: Unable to obtain LocalDateTime from TemporalAccessor

java - Assets 目录内的 Dropwizard 服务目录

java - 使用不同的 QueryParams 重载 REST 端点

java - Spring Data JPA 和 Feign 的组合映射