3

I try to create the following api:

    @GetMapping("/workerslist")
    public List<Worker> getWorkersList(
            @RequestParam(name = "lastPollBefore", required = false) OffsetDateTime lastPollBefore,
            @RequestParam(name = "lastPollAfter", required = false) OffsetDateTime lastPollAfter){
        return workerService.getWorkers(lastPollBefore, lastPollAfter);
    }

But when I call it I get the following error:

{
  "_type": "ValidationError",
  "key": "validation-error",
  "message": "Failed to convert value of type 'java.lang.String' to required type 'java.time.OffsetDateTime'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [@org.springframework.web.bind.annotation.RequestParam java.time.OffsetDateTime] for value '2020-07-01T11:52:57.152Z'; nested exception is java.lang.IllegalArgumentException: Parse attempt failed for value [2020-07-01T11:52:57.152Z]",
  "constraints": [
    
  ]
}

I found solutions for localDateTime but they don't seem to work for offsetDateTime,

Robert Stevens
  • 488
  • 1
  • 7
  • 21
  • *"I found solutions for localDateTime"* Like what? You mean like this one? [How to use LocalDateTime RequestParam in Spring? I get “Failed to convert String to LocalDateTime”](https://stackoverflow.com/q/40274353/5221149) --- Did you try adding dependency `jackson-datatype-jsr310`? Did you try adding `@DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)` to the parameter? Or `@DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSX")`? – Andreas Jul 01 '20 at 12:41

1 Answers1

7

You need to add the @DateTimeFormat annotation for the OffsetDateTime arguments in the controller. eg.

    @GetMapping("/workerslist")
    public List<Worker> getWorkersList(
            @RequestParam(name = "lastPollBefore", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)OffsetDateTime lastPollBefore,
            @RequestParam(name = "lastPollAfter", required = false) @DateTimeFormat(iso = DateTimeFormat.ISO.DATE_TIME)OffsetDateTime lastPollAfter){
        return workerService.getWorkers(lastPollBefore, lastPollAfter);
    }

And you may want to override the Spring's default Object Mapper by your own custom mapper.

Something like this:

@Configuration
public class JsonConfiguration {

  private static final ObjectMapper OBJECT_MAPPER =
      new ObjectMapper().registerModule(new JavaTimeModule())
          .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
          .disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE)
          .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);

  @Bean
@Primary
  public static ObjectMapper getObjectMapper() {
    return OBJECT_MAPPER;
  }
}
Abhinaba Chakraborty
  • 3,488
  • 2
  • 16
  • 37