FeignClient меняет формат LocalDate, переданного ему - PullRequest
2 голосов
/ 24 февраля 2020

У меня есть @FeignClient в моем приложении:

@FeignClient(name="${mongo.service.id}", url="${mongo.service.url}")
public interface MongoCustomerClaimInterface {
    @GetMapping(path = "/api/customerClaim/countClaimsByStatusToBusinessDate/{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.countClaimsByStatusToBusinessDate(formattedDate);

При вызове генерируется ошибка 404, и это мой журнал:

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

Хотя я передаю дату в формат "гггг-мм-дд", так что он будет соответствовать аннотации @DateTimeFormat(iso = DateTimeFormat.ISO.DATE), feign каким-то образом изменяет дату , а затем соответствующий URL не найден.

как я могу предотвратить Делаете это или даже лучше, настраиваете единый форматер?

1 Ответ

0 голосов
/ 26 февраля 2020

Так что, очевидно, Feign не работает со всеми аннотациями Spring Mvc. @DateTimeFormat, как бы она ни была, является аннотацией Spring Mvc, а НЕ аннотацией FeignClient. Я решил это, выполнив несколько вещей:

  1. Создал MessageConvertersConfiguration класс в моем классе MvcConfig. В нем я создал bean-компонент конвертера LocalDate & LocalDateTime и добавил его в список конвертеров, который этот конфигуратор использует при получении сообщения http:
@Configuration
public class MvcConfig {

    @Configuration
    @EnableWebMvc
    public class MessageConvertersConfiguration implements WebMvcConfigurer {
        @Override
        public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
          converters.add(newMappingJackson2HttpMessageConverter(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;
        }
    }
}
Создан класс конфигурации для моего симулированного клиента. В нем я создал экземпляр SpringMvcContract. Поскольку Feign создается за до Spring Mvc, преобразователи, которые мы только что определили, не будут влиять на 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);
}
...