Home > database >  Converting JSON long to a date in Java via Jackson
Converting JSON long to a date in Java via Jackson

Time:10-08

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 a String or Date 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)
  • Related