Feign client doesn't serialize java.time.LocalDate's correctly

See original GitHub issue

I filed this issue at Spring first and they redirected me here. But I’m expecting you guys to rebuff me as well and argue this issue is caused by some bad Spring cloud integration…

I’m using Spring boot 1.3.6, Spring Cloud Brixton.SR3, Java 1.8. It is no longer possible to use a Feign client accepting a java.time.LocalDate as a method param where it is supposed to comply with a given format like @DateTimeFormat(iso = ISO.DATE).

If you do, you get a java.time.format.DateTimeParseException: Text '7/11/16' could not be parsed at index 0", where it’s clear the serialization format is NOT the requested ISO-8601 uuuu-MM-dd but M/d/uu. I put the whole stacktrace below.

I made a stripped project to reproduce the issue: https://github.com/fabmars/feign-localdate-bug Just import, run ApplicationServer, ApplicationClient, they are supposed to query a local eureka server, and hit http://localhost:8080/bug

It’s worth noticing that LocalDate’s used to be serialized correctly back in spring-cloud-netflix:1.0.7, you may even try it in my example project. So there is a strong suspiscion there is a regression since spring-cloud-netflix:1.1.0 at least (before Brixton, even).

2016-07-11 21:48:32.838 ERROR 9398 --- [nio-8080-exec-7] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is com.netflix.hystrix.exception.HystrixRuntimeException: getTomorrow failed and no fallback available.] with root cause

feign.FeignException: status 400 reading TimeClient#getTomorrow(LocalDate,String); content:
{"timestamp":1468266512745,"status":400,"error":"Bad Request","exception":"org.springframework.web.method.annotation.MethodArgumentTypeMismatchException","message":"Failed to convert value of type [java.lang.String] to required type [java.time.LocalDate]; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@org.springframework.web.bind.annotation.RequestParam @org.springframework.format.annotation.DateTimeFormat java.time.LocalDate] for value '7/11/16'; nested exception is java.time.format.DateTimeParseException: Text '7/11/16' could not be parsed at index 0","path":"/tomorrow"}
    at feign.FeignException.errorStatus(FeignException.java:62) ~[feign-core-8.16.2.jar:8.16.2]
    at feign.codec.ErrorDecoder$Default.decode(ErrorDecoder.java:91) ~[feign-core-8.16.2.jar:8.16.2]
    at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:134) ~[feign-core-8.16.2.jar:8.16.2]
    at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:76) ~[feign-core-8.16.2.jar:8.16.2]
    at feign.hystrix.HystrixInvocationHandler$1.run(HystrixInvocationHandler.java:97) ~[feign-hystrix-8.16.2.jar:8.16.2]
    at com.netflix.hystrix.HystrixCommand$1.call(HystrixCommand.java:293) ~[hystrix-core-1.5.3.jar:1.5.3]
    at com.netflix.hystrix.HystrixCommand$1.call(HystrixCommand.java:289) ~[hystrix-core-1.5.3.jar:1.5.3]
    at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:46) ~[rxjava-1.1.5.jar:1.1.5]
    at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:35) ~[rxjava-1.1.5.jar:1.1.5]
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:50) ~[rxjava-1.1.5.jar:1.1.5]
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) ~[rxjava-1.1.5.jar:1.1.5]
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:50) ~[rxjava-1.1.5.jar:1.1.5]
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) ~[rxjava-1.1.5.jar:1.1.5]
    at rx.Observable.unsafeSubscribe(Observable.java:8460) ~[rxjava-1.1.5.jar:1.1.5]
    at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:51) ~[rxjava-1.1.5.jar:1.1.5]
    at rx.internal.operators.OnSubscribeDefer.call(OnSubscribeDefer.java:35) ~[rxjava-1.1.5.jar:1.1.5]
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:50) ~[rxjava-1.1.5.jar:1.1.5]
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) ~[rxjava-1.1.5.jar:1.1.5]
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:50) ~[rxjava-1.1.5.jar:1.1.5]
    at rx.internal.operators.OnSubscribeLift.call(OnSubscribeLift.java:30) ~[rxjava-1.1.5.jar:1.1.5]
    at rx.Observable.unsafeSubscribe(Observable.java:8460) ~[rxjava-1.1.5.jar:1.1.5]
    at rx.internal.operators.OperatorSubscribeOn$1.call(OperatorSubscribeOn.java:94) ~[rxjava-1.1.5.jar:1.1.5]
    at com.netflix.hystrix.strategy.concurrency.HystrixContexSchedulerAction$1.call(HystrixContexSchedulerAction.java:56) ~[hystrix-core-1.5.3.jar:1.5.3]
    at com.netflix.hystrix.strategy.concurrency.HystrixContexSchedulerAction$1.call(HystrixContexSchedulerAction.java:47) ~[hystrix-core-1.5.3.jar:1.5.3]
    at com.netflix.hystrix.strategy.concurrency.HystrixContexSchedulerAction.call(HystrixContexSchedulerAction.java:69) ~[hystrix-core-1.5.3.jar:1.5.3]
    at rx.internal.schedulers.ScheduledAction.run(ScheduledAction.java:55) ~[rxjava-1.1.5.jar:1.1.5]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[na:1.8.0_72]
    at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_72]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_72]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.8.0_72]
    at java.lang.Thread.run(Thread.java:745) [na:1.8.0_72]

Issue Analytics

  • State:closed
  • Created 7 years ago
  • Comments:21 (4 by maintainers)

github_iconTop GitHub Comments

18reactions
uguycommented, Jul 13, 2016

It look s like when the Feign expander is called, it has no info on the @DateTimeFormat annotation (or any other ?) so no ways to apply custom conversion ? ReflectiveFeign, line 205 :

value = indexToExpander.get(i).expand(value);

Then Spring Expander call the conversion service to get a String representation of the value.

Applying ISO DATE format to all feign cliens as default is workaround to format date but not a fix :

@Bean
public FeignFormatterRegistrar localDateFeignFormatterRegistrar() {
    return new FeignFormatterRegistrar() {
        @Override
        public void registerFormatters(FormatterRegistry formatterRegistry) {
            DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
            registrar.setUseIsoFormat(true);
            registrar.registerFormatters(formatterRegistry);
        }
    };
}
8reactions
igorbljahhincommented, Apr 25, 2017

Same issue here. Feign version is 9.3.1, Spring Cloud 1.2.6

Feign client is following:

    @FeignClient(name = "pricing-service", url = "${modules.pricing.url}")
    public interface SailPricesResource {
        @RequestMapping(value = "/api/v1/prices/{date}/{time}", method = RequestMethod.GET)
        GetSailPricesResponseDTO getSailPricesForDeparture(final @PathVariable("date") LocalDate date, final @PathVariable("time") LocalTime time);
    }

The date gets formatted as “D/M/YY” and time gets formatted as “hh:mm a”, although there are custom converters defined in

@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {
    @Override
    public void addFormatters(FormatterRegistry registry) {
        registry.addConverter(new LocalDateToStringConverter());
        registry.addConverter(new StringToLocalDateConverter());
        registry.addConverter(new LocalTimeToStringConverter());
        registry.addConverter(new StringToLocalTimeConverter());
        registry.addConverter(new LocalDateTimeToStringConverter());
        registry.addConverter(new StringToLocalDateTimeConverter());
    }
}

After debugging I discovered that Feigh clients are created before the conversion service is updated with my custom converters. The issue has gone only after I added

@Configuration
public class FeignConfiguration {

    @Bean
    public Contract feignContract() {
        return new SpringMvcContract();
    }
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

Feign client doesn't serialize java.time.LocalDate's correctly ...
I'm using Spring boot 2.4.5, Spring Cloud 2020.0.3, Java 11. Is there a way to use a Feign client accepting a java.time.LocalDate as...
Read more >
Feign client doesn't serialize java.time.LocalDate's correctly
I'm using Spring boot 1.3.6, Spring Cloud Brixton.SR3, Java 1.8. It is no longer possible to use a Feign client accepting a java.time.LocalDate...
Read more >
How to return LocalDateTime from FeignClient endpoint?
Spring MVC using deserialize will make to an Array. But Feign call the object method with ArrayList. so you can not deserialize LocalDate....
Read more >
Feign Client — Configure Date & Time Format for Request ...
In this article, we have learned how to configure LocalDate, LocalTime and LocalDateTime format pattern for request parameters in FeignClient at ...
Read more >
Serializing LocalDate to JSON in Spring Boot - Reflectoring
Today, I stumbled (once again) over LocalDate in a Spring Boot application. LocalDate came with Java 8 and is part of the new...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found