3

I am trying to use Java 8 LocalTime as an attribute in a request object. It seems JSON parsing is not working properly and I get a HTTPStatus 400. My model object:

import java.time.LocalTime;

public class Location {
private String name;
private LocalTime openTime;
....
    }

I am using Swagger to document and use the REST apis. This is how the model object looks in Swagger.

{
 "name": "string",
"openTime": {
  "hour": 8,
  "minute": 0,
  "nano": 0,
  "second": 0
 }
}

I am using JSR310 dependency for jackson

   <dependency>
        <groupId>com.fasterxml.jackson.datatype</groupId>
        <artifactId>jackson-datatype-jsr310</artifactId>
    </dependency>

Spring Boot version is 1.5.9.RELEASE

I have the following questions:

  1. How do I make the parsing work?

  2. I just need hour and minute. How can I configure it?

  3. How do I get more detail about the nature of the exception here. My application logs are clean. I have an RestControllerAdvice configured for exception handling, which does not handle it

    @RestControllerAdvice
    public class CustomResponseEntityExceptionHandler extends ResponseEntityExceptionHandler{
    @ExceptionHandler({ JsonMappingException.class })
    @ResponseStatus(HttpStatus.BAD_REQUEST)
      public List<ApplicationErrorDto> handle(JsonMappingException exception) {
      ApplicationErrorDto applicationErrorDto =  new ApplicationErrorDto();
      applicationErrorDto.setMessage("Request body is malformed");
      logger.info("Request body is malformed: " ,exception);
      return Arrays.asList(applicationErrorDto);
    }
    //methods for other exceptions
    }
    

    I tried following a similar link, but unable to solve it for myself so far: JSON Java 8 LocalDateTime format in Spring Boot

EDIT-1------------------------------------------------------------

I took @JBNizet's advice, returned Locatime from an controller(not an object containing LocalTime). This is what I get:

[
  13,
  42,
  38,
  550000000
]

That's my local time. Then I used the following property in application.properties

spring.jackson.serialization.write_dates_as_timestamps=false

Using the property helped me to change the localtime to a more readable format: "13:48:04.207"

However, a POST endpoint that expects a LocalTime object, is interpreted by Swagger as:

{
 "hour": 0,
 "minute": 0,
 "nano": 0,
 "second": 0
}

Using this schema to POST a LocalTime throws the same 400 error. So, I just copied the structure I was getting in my GET URL and it started working. Both of the following work:

  1. "13:48:04.207"
  2. "13:48"
Noa
  • 315
  • 1
  • 7
  • 31
de_xtr
  • 882
  • 2
  • 10
  • 21
  • https://github.com/FasterXML/jackson-datatype-jsr310: it's deprecated. You shouldn't use that module. The newer module has documentation, too: https://github.com/FasterXML/jackson-modules-java8/tree/master/datetime. Even without documentation, why don't you just experiment? Return an object containing a LocalTime from one of your controllers, and see how it's being serialized. – JB Nizet Apr 07 '18 at 17:12
  • From my experience 400 (bad request) also occurs when something more general is a problem. Please provide you controller code and the client code accessing it (the generated stuff when you use swagger codegen). – Steffen Harbich Apr 08 '18 at 08:02
  • @SteffenHarbich Swagger is not showing any response body, just the 400. I'm providing further updates in my original post. – de_xtr Apr 08 '18 at 08:15
  • So, what is your question now? The question you asked in your title is answered isn't it? You know what to send in the request body to your endpoint. – JB Nizet Apr 08 '18 at 08:34
  • @JBNizet Question 1 and 2 are answered. Thanks. Question 3, I still dont have an answer yet. I am also interested to know why Swagger interprets the RequestBody wrongly. May be I will do some digging around that. – de_xtr Apr 08 '18 at 10:19
  • answers should be contained in the answers section, and you should have one answerable question per topic. Voting to close until this is clarified. – eis Oct 14 '18 at 19:14

0 Answers0