2
votes

I've implemented a rest controller method that receives an object at RequestBody param, which is a simple POJO (a dependency from another project).

public class SimplePOJO {
   private Date productionDate;
   private String description;
   //getters and setters
}

The json I'm receiving it's like this:

{"description":"something","productionDate":"10/03/2020"}

When I try to call the rest service, I get the error:

2020-07-11 15:23:09.274 WARN 3008 --- [nio-8441-exec-2] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type java.util.Date from String "10/03/2020": not a valid representation (error: Failed to parse Date value '10/03/2020': Cannot parse date "10/03/2020": not compatible with any of standard forms ("yyyy-MM-dd'T'HH:mm:ss.SSSX", "yyyy-MM-dd'T'HH:mm:ss.SSS", "EEE, dd MMM yyyy HH:mm:ss zzz", "yyyy-MM-dd")); nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type java.util.Date from String "10/03/2020": not a valid representation (error: Failed to parse Date value '10/03/2020': Cannot parse date "10/03/2020": not compatible with any of standard forms ("yyyy-MM-dd'T'HH:mm:ss.SSSX", "yyyy-MM-dd'T'HH:mm:ss.SSS", "EEE, dd MMM yyyy HH:mm:ss zzz", "yyyy-MM-dd"))

Unfortunately, it's not possible to add JsonFormat annotation at the productionDate field at SimplePOJO. Is there any other way to accept date in format "dd/MM/yyyy" in my service?

Thank you!

2
I recommend you don’t use Date. That class is poorly designed and long outdated. Instead use LocalDate from java.time, the modern Java date and time API. - Ole V.V.
Yes, agree with you, however I guess if she cannot include @JsonFormat it is not possible to change the type of property - doctore

2 Answers

0
votes

If no way to use JsonFormat annotation, you should include your own "global one". The following code works for me:

public class CustomJsonDateDeserializer extends JsonDeserializer<Date> {

  @Override
  public Date deserialize(JsonParser jsonParser,
                          DeserializationContext deserializationContext)
                             throws IOException, JsonProcessingException {

    SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy");
    String date = jsonParser.getText();
    try {
        return format.parse(date);
    } catch (ParseException e) {
        throw new RuntimeException(e);
    }
  }
}

And include the above one into the Web configuration, in this case, I have tested on Spring boot 2 using MVC:

@Configuration
@EnableWebMvc
public class WebConfiguration implements WebMvcConfigurer {

  ...

  @Override
  public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    JavaTimeModule module = new JavaTimeModule();
    module.addDeserializer(Date.class, new CustomJsonDateDeserializer());

    ObjectMapper mapper = new ObjectMapper();
    mapper.registerModule(module);

    // Add converter at the first one to use
    converters.add(0, new MappingJackson2HttpMessageConverter(mapper));
  }
}

And now, you can test it using a dummy endpoint:

@PostMapping("/test")
public ResponseEntity<Boolean> test(@RequestBody SimplePOJO simplePOJO) {
    return ResponseEntity.ok(true);
}

Take care with it, because this is a global Date deserializer, that is, you have to manage in CustomJsonDateDeserializer all allowed formats

0
votes

You can annotate your date property in POJO. This way it accepts the format dd/MM/YYYY you're sending and will be able to deserialize such string to date.

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd/MM/YYYY")
private Date productionDate