From b609d50214d05a528cbad3bcd234a33af7c7792a Mon Sep 17 00:00:00 2001 From: Graham Cox Date: Fri, 21 Feb 2020 20:07:58 +0000 Subject: [PATCH] Examples for Moshi Json (#8753) * Examples for Moshi Json * Renamed Moshi tests to BDD style * Updated some indents * Minor code tweak to prefer ternary over if/else --- libraries-3/pom.xml | 12 +- .../moshi/AlternativeAdapterUnitTest.java | 105 ++++++++++++++ .../com/baeldung/moshi/ArrayUnitTest.java | 36 +++++ .../moshi/ComplexAdapterUnitTest.java | 94 +++++++++++++ .../com/baeldung/moshi/DefaultUnitTest.java | 68 +++++++++ .../com/baeldung/moshi/PrimitiveUnitTest.java | 77 +++++++++++ .../com/baeldung/moshi/RenameUnitTest.java | 68 +++++++++ .../baeldung/moshi/SimpleAdapterUnitTest.java | 129 ++++++++++++++++++ .../com/baeldung/moshi/TransientUnitTest.java | 66 +++++++++ 9 files changed, 654 insertions(+), 1 deletion(-) create mode 100644 libraries-3/src/test/java/com/baeldung/moshi/AlternativeAdapterUnitTest.java create mode 100644 libraries-3/src/test/java/com/baeldung/moshi/ArrayUnitTest.java create mode 100644 libraries-3/src/test/java/com/baeldung/moshi/ComplexAdapterUnitTest.java create mode 100644 libraries-3/src/test/java/com/baeldung/moshi/DefaultUnitTest.java create mode 100644 libraries-3/src/test/java/com/baeldung/moshi/PrimitiveUnitTest.java create mode 100644 libraries-3/src/test/java/com/baeldung/moshi/RenameUnitTest.java create mode 100644 libraries-3/src/test/java/com/baeldung/moshi/SimpleAdapterUnitTest.java create mode 100644 libraries-3/src/test/java/com/baeldung/moshi/TransientUnitTest.java diff --git a/libraries-3/pom.xml b/libraries-3/pom.xml index 5dccebd196..4bb1a4fba1 100644 --- a/libraries-3/pom.xml +++ b/libraries-3/pom.xml @@ -73,6 +73,16 @@ ${cache2k.version} pom + + com.squareup.moshi + moshi + ${moshi.version} + + + com.squareup.moshi + moshi-adapters + ${moshi.version} + com.jcabi @@ -135,7 +145,7 @@ 0.43 2.7.2 1.2.3.Final - + 1.9.2 0.22.6 1.9.2 0.14.1 diff --git a/libraries-3/src/test/java/com/baeldung/moshi/AlternativeAdapterUnitTest.java b/libraries-3/src/test/java/com/baeldung/moshi/AlternativeAdapterUnitTest.java new file mode 100644 index 0000000000..63d80bfe58 --- /dev/null +++ b/libraries-3/src/test/java/com/baeldung/moshi/AlternativeAdapterUnitTest.java @@ -0,0 +1,105 @@ +package com.baeldung.moshi; + +import java.io.IOException; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.time.Instant; + +import com.squareup.moshi.FromJson; +import com.squareup.moshi.JsonAdapter; +import com.squareup.moshi.JsonQualifier; +import com.squareup.moshi.Moshi; +import com.squareup.moshi.ToJson; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.junit.Test; + +public class AlternativeAdapterUnitTest { + @Test + public void whenSerializing_thenAlternativeAdapterUsed() { + Moshi moshi = new Moshi.Builder() + .add(new EpochMillisAdapter()) + .build(); + JsonAdapter jsonAdapter = moshi.adapter(Post.class); + + String json = jsonAdapter.toJson(new Post("Introduction to Moshi Json", "Baeldung", Instant.now())); + System.out.println(json); + } + + @Test + public void whenDeserializing_thenAlternativeAdapterUsed() throws IOException { + Moshi moshi = new Moshi.Builder() + .add(new EpochMillisAdapter()) + .build(); + JsonAdapter jsonAdapter = moshi.adapter(Post.class); + + String json = "{\"author\":\"Baeldung\",\"posted\":1582095269204,\"title\":\"Introduction to Moshi Json\"}"; + Post post = jsonAdapter.fromJson(json); + System.out.println(post); + + } + + public static class Post { + String title; + String author; + @EpochMillis Instant posted; + + public Post() { + } + + public Post(String title, String author, Instant posted) { + this.title = title; + this.author = author; + this.posted = posted; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public Instant getPosted() { + return posted; + } + + public void setPosted(Instant posted) { + this.posted = posted; + } + + @Override + public String toString() { + return new ToStringBuilder(this).append("title", title).append("author", author).append("posted", posted) + .toString(); + } + } + @Retention(RetentionPolicy.RUNTIME) + @Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD}) + @JsonQualifier + public @interface EpochMillis { + } + + public static class EpochMillisAdapter { + @ToJson + public Long toJson(@EpochMillis Instant input) { + return input.toEpochMilli(); + } + @FromJson + @EpochMillis + public Instant fromJson(Long input) { + return Instant.ofEpochMilli(input); + } + + } +} diff --git a/libraries-3/src/test/java/com/baeldung/moshi/ArrayUnitTest.java b/libraries-3/src/test/java/com/baeldung/moshi/ArrayUnitTest.java new file mode 100644 index 0000000000..83bb2bb128 --- /dev/null +++ b/libraries-3/src/test/java/com/baeldung/moshi/ArrayUnitTest.java @@ -0,0 +1,36 @@ +package com.baeldung.moshi; + +import java.io.IOException; +import java.lang.reflect.Type; +import java.util.Arrays; +import java.util.List; + +import com.squareup.moshi.JsonAdapter; +import com.squareup.moshi.Moshi; +import com.squareup.moshi.Types; +import org.junit.Test; + +public class ArrayUnitTest { + @Test + public void whenSerializingList_thenJsonArrayProduced() { + Moshi moshi = new Moshi.Builder() + .build(); + Type type = Types.newParameterizedType(List.class, String.class); + JsonAdapter> jsonAdapter = moshi.adapter(type); + + String json = jsonAdapter.toJson(Arrays.asList("One", "Two", "Three")); + System.out.println(json); + } + + @Test + public void whenDeserializingJsonArray_thenListProduced() throws IOException { + Moshi moshi = new Moshi.Builder() + .build(); + Type type = Types.newParameterizedType(List.class, String.class); + JsonAdapter> jsonAdapter = moshi.adapter(type); + + String json = "[\"One\",\"Two\",\"Three\"]"; + List result = jsonAdapter.fromJson(json); + System.out.println(result); + } +} diff --git a/libraries-3/src/test/java/com/baeldung/moshi/ComplexAdapterUnitTest.java b/libraries-3/src/test/java/com/baeldung/moshi/ComplexAdapterUnitTest.java new file mode 100644 index 0000000000..f0f8e9a95d --- /dev/null +++ b/libraries-3/src/test/java/com/baeldung/moshi/ComplexAdapterUnitTest.java @@ -0,0 +1,94 @@ +package com.baeldung.moshi; + +import java.io.IOException; +import java.time.LocalDate; +import java.time.LocalTime; +import java.time.ZoneId; +import java.time.ZonedDateTime; + +import com.squareup.moshi.FromJson; +import com.squareup.moshi.JsonAdapter; +import com.squareup.moshi.Moshi; +import com.squareup.moshi.ToJson; +import org.junit.Test; + +public class ComplexAdapterUnitTest { + @Test + public void whenSerializing_thenCorrectJsonProduced() { + Moshi moshi = new Moshi.Builder() + .add(new JsonDateTimeAdapter()) + .build(); + JsonAdapter jsonAdapter = moshi.adapter(ZonedDateTime.class); + + String json = jsonAdapter.toJson(ZonedDateTime.now()); + System.out.println(json); + } + + @Test + public void whenDeserializing_thenCorrectJsonConsumed() throws IOException { + Moshi moshi = new Moshi.Builder() + .add(new JsonDateTimeAdapter()) + .build(); + JsonAdapter jsonAdapter = moshi.adapter(ZonedDateTime.class); + + String json = "{\"date\":\"2020-02-17\",\"time\":\"07:53:27.064\",\"timezone\":\"Europe/London\"}"; + ZonedDateTime now = jsonAdapter.fromJson(json); + System.out.println(now); + + } + + public static class JsonDateTimeAdapter { + @ToJson + public JsonDateTime toJson(ZonedDateTime input) { + String date = input.toLocalDate().toString(); + String time = input.toLocalTime().toString(); + String timezone = input.getZone().toString(); + return new JsonDateTime(date, time, timezone); + } + @FromJson + public ZonedDateTime fromJson(JsonDateTime input) { + LocalDate date = LocalDate.parse(input.getDate()); + LocalTime time = LocalTime.parse(input.getTime()); + ZoneId timezone = ZoneId.of(input.getTimezone()); + return ZonedDateTime.of(date, time, timezone); + } + } + public static class JsonDateTime { + private String date; + private String time; + private String timezone; + + public JsonDateTime() { + } + + public JsonDateTime(String date, String time, String timezone) { + this.date = date; + this.time = time; + this.timezone = timezone; + } + + public String getDate() { + return date; + } + + public void setDate(String date) { + this.date = date; + } + + public String getTime() { + return time; + } + + public void setTime(String time) { + this.time = time; + } + + public String getTimezone() { + return timezone; + } + + public void setTimezone(String timezone) { + this.timezone = timezone; + } + } +} diff --git a/libraries-3/src/test/java/com/baeldung/moshi/DefaultUnitTest.java b/libraries-3/src/test/java/com/baeldung/moshi/DefaultUnitTest.java new file mode 100644 index 0000000000..0b4ecc23a5 --- /dev/null +++ b/libraries-3/src/test/java/com/baeldung/moshi/DefaultUnitTest.java @@ -0,0 +1,68 @@ +package com.baeldung.moshi; + +import java.io.IOException; +import java.time.Instant; + +import com.squareup.moshi.JsonAdapter; +import com.squareup.moshi.Moshi; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.junit.Test; + +public class DefaultUnitTest { + + @Test + public void whenDeserializing_thenFieldsGetDefaultValues() throws IOException { + Moshi moshi = new Moshi.Builder() + .build(); + JsonAdapter jsonAdapter = moshi.adapter(Post.class); + + String json = "{\"title\":\"My Post\"}"; + Post post = jsonAdapter.fromJson(json); + System.out.println(post); + } + public static class Post { + private String title; + private String author; + private String posted; + + public Post() { + posted = Instant.now().toString(); + } + + public Post(String title, String author, String posted) { + this.title = title; + this.author = author; + this.posted = posted; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getPosted() { + return posted; + } + + public void setPosted(String posted) { + this.posted = posted; + } + + @Override + public String toString() { + return new ToStringBuilder(this).append("title", title).append("author", author).append("posted", posted) + .toString(); + } + } +} diff --git a/libraries-3/src/test/java/com/baeldung/moshi/PrimitiveUnitTest.java b/libraries-3/src/test/java/com/baeldung/moshi/PrimitiveUnitTest.java new file mode 100644 index 0000000000..e26e93ba8c --- /dev/null +++ b/libraries-3/src/test/java/com/baeldung/moshi/PrimitiveUnitTest.java @@ -0,0 +1,77 @@ +package com.baeldung.moshi; + +import java.io.IOException; + +import com.squareup.moshi.JsonAdapter; +import com.squareup.moshi.Moshi; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.junit.Test; + +public class PrimitiveUnitTest { + @Test + public void whenSerializing_thenCorrectJsonProduced() { + Moshi moshi = new Moshi.Builder() + .build(); + JsonAdapter jsonAdapter = moshi.adapter(Post.class); + + Post post = new Post("My Post", "Baeldung", "This is my post"); + String json = jsonAdapter.toJson(post); + System.out.println(json); + } + + @Test + public void whenDeserializing_thenCorrectJsonConsumed() throws IOException { + Moshi moshi = new Moshi.Builder() + .build(); + JsonAdapter jsonAdapter = moshi.adapter(Post.class); + + String json = "{\"author\":\"Baeldung\",\"text\":\"This is my post\",\"title\":\"My Post\"}"; + Post post = jsonAdapter.fromJson(json); + System.out.println(post); + } + + public static class Post { + private String title; + private String author; + private String text; + + public Post() { + } + + public Post(String title, String author, String text) { + this.title = title; + this.author = author; + this.text = text; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + @Override + public String toString() { + return new ToStringBuilder(this).append("title", title).append("author", author).append("text", text) + .toString(); + } + } +} diff --git a/libraries-3/src/test/java/com/baeldung/moshi/RenameUnitTest.java b/libraries-3/src/test/java/com/baeldung/moshi/RenameUnitTest.java new file mode 100644 index 0000000000..2118538a19 --- /dev/null +++ b/libraries-3/src/test/java/com/baeldung/moshi/RenameUnitTest.java @@ -0,0 +1,68 @@ +package com.baeldung.moshi; + +import java.io.IOException; + +import com.squareup.moshi.Json; +import com.squareup.moshi.JsonAdapter; +import com.squareup.moshi.Moshi; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.junit.jupiter.api.Test; + +public class RenameUnitTest { + + @Test + public void whenSerializing_thenFieldsGetRenamed() { + Moshi moshi = new Moshi.Builder() + .build(); + JsonAdapter jsonAdapter = moshi.adapter(Post.class); + + Post post = new Post("My Post", "Baeldung"); + String json = jsonAdapter.toJson(post); + System.out.println(json); + } + + @Test + public void whenSerializing_thenRenamedFieldsGetConsumed() throws IOException { + Moshi moshi = new Moshi.Builder() + .build(); + JsonAdapter jsonAdapter = moshi.adapter(Post.class); + + String json = "{\"authored_by\":\"Baeldung\",\"title\":\"My Post\"}"; + Post post = jsonAdapter.fromJson(json); + System.out.println(post); + } + public static class Post { + private String title; + @Json(name = "authored_by") + private String author; + + public Post() { + } + + public Post(String title, String author) { + this.title = title; + this.author = author; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + @Override + public String toString() { + return new ToStringBuilder(this).append("title", title).append("author", author).toString(); + } + } +} diff --git a/libraries-3/src/test/java/com/baeldung/moshi/SimpleAdapterUnitTest.java b/libraries-3/src/test/java/com/baeldung/moshi/SimpleAdapterUnitTest.java new file mode 100644 index 0000000000..e0be2f8a66 --- /dev/null +++ b/libraries-3/src/test/java/com/baeldung/moshi/SimpleAdapterUnitTest.java @@ -0,0 +1,129 @@ +package com.baeldung.moshi; + +import java.io.IOException; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import com.squareup.moshi.FromJson; +import com.squareup.moshi.JsonAdapter; +import com.squareup.moshi.Moshi; +import com.squareup.moshi.ToJson; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.junit.Test; + +public class SimpleAdapterUnitTest { + @Test + public void whenSerializing_thenAdapterUsed() { + Moshi moshi = new Moshi.Builder() + .add(new AuthorAdapter()) + .build(); + JsonAdapter jsonAdapter = moshi.adapter(Post.class); + + Post post = new Post("My Post", new Author("Baeldung", "baeldung@example.com"), "This is my post"); + String json = jsonAdapter.toJson(post); + System.out.println(json); + } + + @Test + public void whenDeserializing_thenAdapterUsed() throws IOException { + Moshi moshi = new Moshi.Builder() + .add(new AuthorAdapter()) + .build(); + JsonAdapter jsonAdapter = moshi.adapter(Post.class); + + String json = "{\"author\":\"Baeldung \",\"text\":\"This is my post\",\"title\":\"My Post\"}"; + Post post = jsonAdapter.fromJson(json); + System.out.println(post); + } + public static class AuthorAdapter { + private Pattern pattern = Pattern.compile("^(.*) <(.*)>$"); + @ToJson + public String toJson(Author author) { + return author.name + " <" + author.email + ">"; + } + + @FromJson + public Author fromJson(String author) { + Matcher matcher = pattern.matcher(author); + return matcher.find() ? new Author(matcher.group(1), matcher.group(2)) : null; + } + } + + public static class Author { + private String name; + private String email; + + public Author() { + } + + public Author(String name, String email) { + this.name = name; + this.email = email; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + @Override + public String toString() { + return new ToStringBuilder(this).append("name", name).append("email", email).toString(); + } + } + public static class Post { + private String title; + private Author author; + private String text; + + public Post() { + } + + public Post(String title, Author author, String text) { + this.title = title; + this.author = author; + this.text = text; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public Author getAuthor() { + return author; + } + + public void setAuthor(Author author) { + this.author = author; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + @Override + public String toString() { + return new ToStringBuilder(this).append("title", title).append("author", author).append("text", text) + .toString(); + } + } +} diff --git a/libraries-3/src/test/java/com/baeldung/moshi/TransientUnitTest.java b/libraries-3/src/test/java/com/baeldung/moshi/TransientUnitTest.java new file mode 100644 index 0000000000..2554e937b3 --- /dev/null +++ b/libraries-3/src/test/java/com/baeldung/moshi/TransientUnitTest.java @@ -0,0 +1,66 @@ +package com.baeldung.moshi; + +import java.io.IOException; + +import com.squareup.moshi.JsonAdapter; +import com.squareup.moshi.Moshi; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.junit.jupiter.api.Test; + +public class TransientUnitTest { + + @Test + public void whenSerializing_thenTransientFieldIgnored() { + Moshi moshi = new Moshi.Builder() + .build(); + JsonAdapter jsonAdapter = moshi.adapter(Post.class); + + Post post = new Post("My Post", "Baeldung"); + String json = jsonAdapter.toJson(post); + System.out.println(json); + } + + @Test + public void whenDeserializing_thenTransientFieldIgnored() throws IOException { + Moshi moshi = new Moshi.Builder() + .build(); + JsonAdapter jsonAdapter = moshi.adapter(Post.class); + + String json = "{\"authored_by\":\"Baeldung\",\"title\":\"My Post\"}"; + Post post = jsonAdapter.fromJson(json); + System.out.println(post); + } + public static class Post { + private String title; + private transient String author; + + public Post() { + } + + public Post(String title, String author) { + this.title = title; + this.author = author; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getAuthor() { + return author; + } + + public void setAuthor(String author) { + this.author = author; + } + + @Override + public String toString() { + return new ToStringBuilder(this).append("title", title).append("author", author).toString(); + } + } +}