Commit 162e4da7 authored by Hallvard Trætteberg's avatar Hallvard Trætteberg
Browse files

Serialisering/deserialisering (#3)

parent fbe5699e
......@@ -16,6 +16,19 @@
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-core -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.11.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-databind -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.2</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
......
......@@ -5,6 +5,11 @@ public class TodoItem {
private String text;
private boolean checked;
@Override
public String toString() {
return String.format("[TodoItem text=%s checked=%s]", getText(), isChecked());
}
public String getText() {
return text;
}
......
package todolist.json;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.TreeNode;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.BooleanNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.fasterxml.jackson.databind.node.TextNode;
import todolist.core.TodoItem;
public class TodoItemDeserializer extends JsonDeserializer<TodoItem> {
@Override
public TodoItem deserialize(JsonParser parser, DeserializationContext ctxt) throws IOException, JsonProcessingException {
TreeNode treeNode = parser.getCodec().readTree(parser);
return deserialize((JsonNode) treeNode);
}
public TodoItem deserialize(JsonNode jsonNode) {
if (jsonNode instanceof ObjectNode) {
ObjectNode objectNode = (ObjectNode) jsonNode;
TodoItem item = new TodoItem();
JsonNode textNode = objectNode.get("text");
if (textNode instanceof TextNode) {
item.setText(((TextNode) textNode).asText());
}
JsonNode checkedNode = objectNode.get("checked");
if (checkedNode instanceof BooleanNode) {
item.setChecked(((BooleanNode) checkedNode).asBoolean(false));
}
return item;
}
return null;
}
}
\ No newline at end of file
package todolist.json;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import todolist.core.TodoItem;
public class TodoItemSerializer extends JsonSerializer<TodoItem> {
/*
* format: { "text": "...", "checked": false }
*/
@Override
public void serialize(TodoItem item, JsonGenerator jGen, SerializerProvider serializerProvider) throws IOException {
jGen.writeStartObject();
jGen.writeStringField("text", item.getText());
jGen.writeBooleanField("checked", item.isChecked());
jGen.writeEndObject();
}
}
package todolist.json;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.TreeNode;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import todolist.core.TodoItem;
import todolist.core.TodoList;
public class TodoListDeserializer extends JsonDeserializer<TodoList> {
private TodoItemDeserializer todoItemDeserializer = new TodoItemDeserializer();
/*
* format: { "items": [ ... ] }
*/
@Override
public TodoList deserialize(JsonParser parser, DeserializationContext ctxt) throws IOException, JsonProcessingException {
TreeNode treeNode = parser.getCodec().readTree(parser);
if (treeNode instanceof ObjectNode) {
ObjectNode objectNode = (ObjectNode) treeNode;
TodoList list = new TodoList();
JsonNode itemsNode = objectNode.get("items");
if (itemsNode instanceof ArrayNode) {
for (JsonNode elementNode : ((ArrayNode) itemsNode)) {
TodoItem item = todoItemDeserializer.deserialize(elementNode);
if (item != null) {
list.addTodoItem(item);
}
}
}
return list;
}
return null;
}
}
\ No newline at end of file
package todolist.json;
import java.io.IOException;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import todolist.core.TodoItem;
import todolist.core.TodoList;
public class TodoListSerializer extends JsonSerializer<TodoList> {
/*
* format: { "items": [ ... ] }
*/
@Override
public void serialize(TodoList list, JsonGenerator jGen, SerializerProvider serializerProvider) throws IOException {
jGen.writeStartObject();
jGen.writeArrayFieldStart("items");
for (TodoItem item : list) {
jGen.writeObject(item);
}
jGen.writeEndArray();
jGen.writeEndObject();
}
}
package todolist.json;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.util.VersionUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import todolist.core.TodoItem;
import todolist.core.TodoList;
public class TodoModule extends SimpleModule {
private static final String NAME = "TodoModule";
private static final VersionUtil VERSION_UTIL = new VersionUtil() {
};
public TodoModule() {
super(NAME, VERSION_UTIL.version());
addSerializer(TodoItem.class, new TodoItemSerializer());
addSerializer(TodoList.class, new TodoListSerializer());
addDeserializer(TodoItem.class, new TodoItemDeserializer());
addDeserializer(TodoList.class, new TodoListDeserializer());
}
public static void main(String[] args) {
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new TodoModule());
TodoList list = new TodoList();
TodoItem item1 = new TodoItem();
item1.setText("item1");
TodoItem item2 = new TodoItem();
item2.setText("item2");
item2.setChecked(true);
list.addTodoItem(item1);
list.addTodoItem(item2);
try {
String json = mapper.writeValueAsString(list);
TodoList list2 = mapper.readValue(json, TodoList.class);
for (TodoItem item : list2) {
System.out.println(item);
}
} catch (JsonProcessingException e) {
System.err.println("Virket ikke");
e.printStackTrace();
}
}
}
\ No newline at end of file
package todolist.json;
import static org.junit.jupiter.api.Assertions.fail;
import java.util.Iterator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.BeforeAll;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.junit.jupiter.api.Test;
import todolist.core.TodoItem;
import todolist.core.TodoList;
public class TodoModuleTest {
// {"items":[{"text":"item1","checked":false},{"text":"item2","checked":true}]}
private static ObjectMapper mapper;
@BeforeAll
public static void setUp() {
mapper = new ObjectMapper();
mapper.registerModule(new TodoModule());
}
private final static String todoListWithTwoItems = "{\"items\":[{\"text\":\"item1\",\"checked\":false},{\"text\":\"item2\",\"checked\":true}]}";
@Test
public void testSerializers() {
TodoList list = new TodoList();
TodoItem item1 = new TodoItem();
item1.setText("item1");
TodoItem item2 = new TodoItem();
item2.setText("item2");
item2.setChecked(true);
list.addTodoItem(item1);
list.addTodoItem(item2);
try {
assertEquals(todoListWithTwoItems, mapper.writeValueAsString(list));
} catch (JsonProcessingException e) {
fail();
}
}
static void checkTodoItem(TodoItem item, String text, boolean checked) {
assertEquals(text, item.getText());
assertTrue(checked == item.isChecked());
}
static void checkTodoItem(TodoItem item1, TodoItem item2) {
checkTodoItem(item1, item2.getText(), item2.isChecked());
}
@Test
public void testDeserializers() {
try {
TodoList list = mapper.readValue(todoListWithTwoItems, TodoList.class);
Iterator<TodoItem> it = list.iterator();
assertTrue(it.hasNext());
checkTodoItem(it.next(), "item1", false);
assertTrue(it.hasNext());
checkTodoItem(it.next(), "item2", true);
assertFalse(it.hasNext());
} catch (JsonProcessingException e) {
fail();
}
}
@Test
public void testSerializersDeserializers() {
TodoList list = new TodoList();
TodoItem item1 = new TodoItem();
item1.setText("item1");
TodoItem item2 = new TodoItem();
item2.setText("item2");
item2.setChecked(true);
list.addTodoItem(item1);
list.addTodoItem(item2);
try {
String json = mapper.writeValueAsString(list);
TodoList list2 = mapper.readValue(json, TodoList.class);
Iterator<TodoItem> it = list2.iterator();
assertTrue(it.hasNext());
checkTodoItem(it.next(), item1);
assertTrue(it.hasNext());
checkTodoItem(it.next(), item2);
assertFalse(it.hasNext());
} catch (JsonProcessingException e) {
fail();
}
}
}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment