Skip to content

Commit

Permalink
Add InstantEpochTimeSerializer (#505)
Browse files Browse the repository at this point in the history
  • Loading branch information
sleberknight authored Feb 18, 2021
1 parent 3f01582 commit 620de63
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package org.kiwiproject.jackson.ser;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;

import java.io.IOException;
import java.time.Instant;

/**
* Jackson serializer that converts an {@link Instant} into milliseconds since the epoch.
*/
public class InstantEpochTimeSerializer extends StdSerializer<Instant> {

/**
* Create a new instance that serializes {@link Instant} to epoch millis.
*/
public InstantEpochTimeSerializer() {
super(Instant.class);
}

@Override
public void serialize(Instant value,
JsonGenerator jsonGenerator,
SerializerProvider provider) throws IOException {

jsonGenerator.writeNumber(value.toEpochMilli());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package org.kiwiproject.jackson.ser;

import static org.assertj.core.api.Assertions.assertThat;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.module.SimpleModule;
import lombok.Builder;
import lombok.Value;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.io.StringWriter;
import java.time.Instant;
import java.util.Map;

@DisplayName("InstantEpochTimeSerializer")
class InstantEpochTimeSerializerTest {

private InstantEpochTimeSerializer serializer;
private JsonGenerator jsonGenerator;
private StringWriter writer;
private Instant now;

@BeforeEach
void setUp() throws IOException {
serializer = new InstantEpochTimeSerializer();

writer = new StringWriter();
var jsonFactory = new JsonFactory();
jsonGenerator = jsonFactory.createGenerator(writer);

now = Instant.now();
}

@Test
void shouldSerializeToEpochMillis() throws IOException {
serializer.serialize(now, jsonGenerator, null);
jsonGenerator.close();

var serializedValue = Long.parseLong(writer.toString());
assertThat(serializedValue).isEqualTo(now.toEpochMilli());
}

@Test
void shouldSerializeWhenRegisteredOnObjectMapper() throws JsonProcessingException {
var entry = Entry.builder()
.name("Diane")
.text("Today we went sledding in the snow...")
.createdAt(now)
.build();

var module = new SimpleModule().addSerializer(serializer);
var objectMapper = new ObjectMapper().registerModule(module);
var json = objectMapper.writeValueAsString(entry);

assertSerializesCreatedAtToEpochMillis(json, objectMapper, now);
}

@Test
void shouldSerializeWhenUsingJsonSerializeAnnotationOnClass() throws IOException {
var post = Post.builder()
.name("Carlos")
.text("Yesterday we went fishing...")
.createdAt(now)
.build();

var objectMapper = new ObjectMapper();
var json = objectMapper.writeValueAsString(post);

assertSerializesCreatedAtToEpochMillis(json, objectMapper, now);
}

private static void assertSerializesCreatedAtToEpochMillis(String json, ObjectMapper mapper, Instant expected)
throws JsonProcessingException {

var map = mapper.readValue(json, Map.class);
var createdAt = (long) map.get("createdAt");
assertThat(createdAt).isEqualTo(expected.toEpochMilli());
}

@Value
@Builder
private static class Entry {
String name;
String text;
Instant createdAt;
}

@Value
@Builder
private static class Post {
String name;
String text;

@JsonSerialize(using = InstantEpochTimeSerializer.class)
Instant createdAt;
}
}

0 comments on commit 620de63

Please sign in to comment.