Eugene Podoliako Eugene Podoliako - 2 months ago 18
Java Question

Store string time in sql.Time through spring @RequestBody

I need to store time (hours and minutes) in backend. The data comes from UI in json and have the following view "10:00" as expamle. In backend I decided to keep this time in

sql.Time
type. The time comes to class through spring
@RequestBody
and consiquntly lead to exception:
org.springframework.http.converter.HttpMessageNotReadableException: Could not read document: Instantiation of [simple type, class java.sql.Time] value failed: null (through reference chain: biz.models.CarWash["firstShift"]);


How to put my time in sql.Time field through
@RequestBody
annotation?
And are that good ideas to keep time in
sql.Time
type and send it from UI in json as "10:00" ?

My controller:

@RequestMapping(value = "/carwash/add", method = RequestMethod.PUT, produces = "application/json;charset=UTF-8")
@ResponseStatus(HttpStatus.OK)
@ResponseBody
public Long addCarWashPUT(@RequestBody CarWash carWash) throws ParseException {
System.out.println(carWash);
return 999L;
}

Answer

Problem is in that Jackson (by default used in Spring MVC) doesn't know how to transform "10:00" -> java.sql.Time, it is not obvious. You can define custom deserializer to do the transformation from string to java object:

public final class SqlTimeDeserializer extends JsonDeserializer<java.sql.Time> {

    @Override
    public java.sql.Time deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        ObjectCodec oc = jsonParser.getCodec();
        JsonNode node = oc.readTree(jsonParser);
        String time = node.get("firstShift").textValue();
        return // convert java.sql.Time from string
    }

....

}

To use this deserializer just put

@JsonDeserialize(using = SqlTimeDeserializer.class)

above firstShift field in class CarWash

Comments