I have a JSON Data Object class as follows:
public class Plugins {
private String id;
private String name;
@JsonProperty("created_at")
private long createdAt;
}
Where createdAt
is the long timestamp of the creation date. I use this class to back up a Jackson ObjectMapper
object parsing JSON data from an external API call. I was wondering if it is possible to have Jackson convert created_at
automatically to a readable date format and store in Java as a String
or Date
flavour?
CodePudding user response:
if it is possible to have Jackson convert
created_at
automatically to a readable date format and store in Java as aString
orDate
flavour?
Date
is obsolete and discouraged to be used.
Since Java 8 (which was released about 10 years ago) we have modern Time API which includes Instant
, LocalDateTime
and other classes from the java.time
package.
You can change your POJO to make it store date-time information properly without the need to change the JSON payload. I.e. created_at
can be received as a long
value like 1665148545
and translated into ZonedDateTime
(or other date-time representations like Istant
, LocalDateTime
).
public class Plugins {
private String id;
private String name;
private ZonedDateTime createdAt;
public Plugins(@JsonProperty("id") String id,
@JsonProperty("name") String name,
@JsonProperty("created_at") long createdAt) {
this.id = id;
this.name = name;
this.createdAt = Instant.ofEpochSecond(createdAt)
.atZone(ZoneId.of("UTC"));
}
// getters, toString(), etc.
}
Usage example:
String json = """
{
"id": "1",
"name": "someName",
"created_at": 1665148545
}""";
ObjectMapper mapper = new ObjectMapper();
System.out.println(mapper.readValue(json, Plugins.class));
Output:
lugins{id='1', name='someName', createdAt=2022-10-07T13:15:45}
CodePudding user response:
Using Custom Deserialiser in jackson
You can achieve the date conversion from long to String or Date by using the custom deserialiser. This custom deserialiser will convert the long value from the json into the defined date format(either Date or String).
Please Note: Here, I have converted the epoch value into the String datatype. In case if Date datatype is needed, you can change the implementation of the deserialize method
of CustomDateSerializer
class accordingly.
You need to use the below annotation to the fields on which custom deserialisation is required.
@JsonDeserialize(using = CustomDateSerializer.class)
Please find the code below:
Plugins.java
public class Plugins {
private String id;
private String name;
@JsonDeserialize(using = CustomDateSerializer.class)
@JsonProperty("created_at")
private String createdAt;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCreatedAt() {
return createdAt;
}
public void setCreatedAt(String createdAt) {
this.createdAt = createdAt;
}
@Override
public String toString() {
return "Plugins{"
"id='" id '\''
", name='" name '\''
", createdAt='" createdAt '\''
'}';
}
}
CustomDateSerializer.java
public class CustomDateSerializer extends StdDeserializer<String> {
public static String pattern = "dd MMM yyyy hh:mm:ss";
public CustomDateSerializer() {
this(StdDeserializer.class);
}
protected CustomDateSerializer(Class<?> c) {
super(c);
}
@Override
public String deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
SimpleDateFormat formatter = new SimpleDateFormat(pattern);
return formatter.format(new Date(jsonParser.getLongValue()));//change the implementation of deserialise method if date format is needed.
}
}
Test.java
public class Test {
public static void main(String[] args) throws JsonProcessingException {
//For sample input json, here i have used Text Blocks feature available from JDK 15 to have the string in readable format.
String json = """
{
"id":"1",
"name":"test",
"created_at":1665158083000
}
""";
ObjectMapper mapper = new ObjectMapper();
Plugins test = mapper.readValue(json,Plugins.class);
System.out.println(test);
}
}
Output:
Plugins{id='1', name='test', createdAt='07 Oct 2022 09:24:43'}
CodePudding user response:
You just need to register JavaTimeModule
module and use required type from Java-8
time package. Take a look on below example:
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.Instant;
public class DateApp {
private final static JsonMapper JSON_MAPPER = JsonMapper.builder()
.enable(SerializationFeature.INDENT_OUTPUT)
.addModule(new JavaTimeModule())
.build();
public static void main(String[] args) throws Exception {
String json = "{\"id\": \"1\",\"name\":\"someName\",\"created_at\": 1665148545}";
Plugins plugins = JSON_MAPPER.readValue(json, Plugins.class);
System.out.println(plugins);
}
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class Plugins {
private String id;
private String name;
@JsonProperty("created_at")
private Instant createdAt;
}
Above code prints:
Plugins(id=1, name=someName, createdAt=2022-10-07T13:15:45Z)