Reputation: 83
I have been looking for implementing a custom deserializer using LocalTimeDeserializer class of Jackson API.
However, I am getting below error while actually deserializing properties using this class.
com.fasterxml.jackson.databind.JsonMappingException: Class com.dspim.api.common.LocalTimeWithStringDeserializer has no default (no arg) constructor
I am using the custom implementation as below for deserializing inside the bean class.
@JsonProperty @JsonDeserializer(using=LocalTimeWithStringDeserializer.class) private LocalTime packaging_time; //It will hold value for time i.e. 13:24 (01:24 PM).
I have implemented the deserializer class as follows.
package com.testapp.test;
import java.io.IOException;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
public class LocalTimeWithStringDeserializer extends com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer{
public LocalTimeWithStringDeserializer(DateTimeFormatter formatter) {
super(formatter);
}
private static final long serialVersionUID = 1L;
@Override
public LocalTime deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException,
JsonProcessingException {
return LocalTime.parse(jp.getText());
}
}
The default constructor (with no arguments) in the parent class is private, thus I cannot add a default constructor (with no arguments) to my class implementation as I get compile time error.
Please suggest a solution for this issue.
Please Note: I have two different projects (having dependency on each other added to the classpath) of a client in which I cannot use the built in Jackson deserializer due to dependency version conflicts, that's why I have been compelled to use custom deserializer.
Upvotes: 0
Views: 755
Reputation: 1672
I use LocalTime deserializer in my project and link it for the JSOG/JSON to deserialize when API layer gets called. I declare it using an annotation in the model layer above the field i want to deserialize. I use jackson.databind.JsonDeserializer
and it works well for me`.
Here is the code I use:
import java.io.IOException;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
public class CustomJacksonLocalTimeDeserializer extends JsonDeserializer<LocalTime> {
@Override
public LocalTime deserialize(JsonParser jsonparser, DeserializationContext context)
throws IOException, JsonProcessingException {
String dateAsString = jsonparser.getText();
try {
return LocalTime.parse(dateAsString, DateTimeFormatter.ISO_LOCAL_TIME);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
You also need to annotate it on the field as follows:
@JsonDeserialize(using = CustomJacksonLocalTimeDeserializer.class)
@JsonSerialize(using = CustomJacksonLocalTimeSerializer.class)
@Column(columnDefinition = "TIMESTAMP")
private LocalTime origHardScheduledTime;
I know, you did not ask for it, but for the completion's sake, a serializer would also look similar.
import java.io.IOException;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
public class CustomJacksonLocalTimeSerializer extends JsonSerializer<LocalTime> {
@Override
public void serialize(LocalTime date, JsonGenerator jsonGenerator, SerializerProvider serializers)
throws IOException, JsonProcessingException {
jsonGenerator.writeString(date.format(DateTimeFormatter.ISO_LOCAL_TIME));
}
}
Upvotes: 0
Reputation: 7808
Maybe you don't need your own deserializer. All you need to do is to anotate your LocalTime member with the following anotation:
static class Entity {
LocalTime time;
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "HH:mm:ss")
public LocalTime getTime() {
return time;
}
}
This should work. See the answer to this question: Spring Data JPA - ZonedDateTime format for json serialization
Upvotes: 0
Reputation: 17955
If the parent class has a private no-args constructor, that does not prohibit you from having a no-args constructor yourself:
public class LocalTimeWithStringDeserializer extends com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer{
private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy MM dd");
public LocalTimeWithStringDeserializer() {
super(formatter);
}
// ...
}
Upvotes: 3