FeignClient 正在更改传递给它的 LocalDate 的格式
FeignClient is changing the format of LocalDate passed to it
我的应用程序中有一个 @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)
- Feign 以某种方式更改了日期,然后找不到匹配的 url
如何防止 Feign 这样做并配置统一的格式化程序?
很明显,Feign 并未使用所有 SpringMvc 注释。 @DateTimeFormat
,尽管它很棒,但它是 SpringMvc 注释而不是 FeignClient 注释。
我通过做几件事解决了这个问题:
- 在我的 MvcConfig class 中创建了一个 MessageConvertersConfiguration class。
在其中,我创建了一个 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;
}
}
}
- 为我的虚拟客户端创建了配置 class。在其中,我实例化了一个 SpringMvcContract。因为Feign是在之前 SpringMvc创建的,所以我们刚刚定义的转换器不会影响没有这个契约的feign:
@Configuration
public class FeignConfig {
@Bean
public Contract feignContract() {
return new SpringMvcContract();
}
}
- 最终,我将配置属性添加到我的 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);
}
我的应用程序中有一个 @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)
- Feign 以某种方式更改了日期,然后找不到匹配的 url
如何防止 Feign 这样做并配置统一的格式化程序?
很明显,Feign 并未使用所有 SpringMvc 注释。 @DateTimeFormat
,尽管它很棒,但它是 SpringMvc 注释而不是 FeignClient 注释。
我通过做几件事解决了这个问题:
- 在我的 MvcConfig class 中创建了一个 MessageConvertersConfiguration class。 在其中,我创建了一个 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;
}
}
}
- 为我的虚拟客户端创建了配置 class。在其中,我实例化了一个 SpringMvcContract。因为Feign是在之前 SpringMvc创建的,所以我们刚刚定义的转换器不会影响没有这个契约的feign:
@Configuration
public class FeignConfig {
@Bean
public Contract feignContract() {
return new SpringMvcContract();
}
}
- 最终,我将配置属性添加到我的 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);
}