diff --git a/json-modules/json-3/src/main/java/com/baeldung/pojomapping/Address.java b/json-modules/json-3/src/main/java/com/baeldung/pojomapping/Address.java new file mode 100644 index 000000000000..400827d1a785 --- /dev/null +++ b/json-modules/json-3/src/main/java/com/baeldung/pojomapping/Address.java @@ -0,0 +1,22 @@ +package com.baeldung.pojomapping; + +public class Address { + private String city; + private String postalCode; + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getPostalCode() { + return postalCode; + } + + public void setPostalCode(String postalCode) { + this.postalCode = postalCode; + } +} \ No newline at end of file diff --git a/json-modules/json-3/src/main/java/com/baeldung/pojomapping/Animal.java b/json-modules/json-3/src/main/java/com/baeldung/pojomapping/Animal.java new file mode 100644 index 000000000000..bf9d20257591 --- /dev/null +++ b/json-modules/json-3/src/main/java/com/baeldung/pojomapping/Animal.java @@ -0,0 +1,49 @@ +package com.baeldung.pojomapping; + +import com.fasterxml.jackson.annotation.JsonSubTypes; +import com.fasterxml.jackson.annotation.JsonTypeInfo; + +@JsonTypeInfo( + use = JsonTypeInfo.Id.NAME, + include = JsonTypeInfo.As.PROPERTY, + property = "type" +) +@JsonSubTypes({ + @JsonSubTypes.Type(value = Dog.class, name = "dog"), + @JsonSubTypes.Type(value = Cat.class, name = "cat") +}) +abstract class Animal { + private String name; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} + +class Dog extends Animal { + private int barkVolume; + + public int getBarkVolume() { + return barkVolume; + } + + public void setBarkVolume(int barkVolume) { + this.barkVolume = barkVolume; + } +} + +class Cat extends Animal { + private boolean likesFish; + + public boolean isLikesFish() { + return likesFish; + } + + public void setLikesFish(boolean likesFish) { + this.likesFish = likesFish; + } +} \ No newline at end of file diff --git a/json-modules/json-3/src/main/java/com/baeldung/pojomapping/JsonToPojoMapper.java b/json-modules/json-3/src/main/java/com/baeldung/pojomapping/JsonToPojoMapper.java new file mode 100644 index 000000000000..a96b099f06ec --- /dev/null +++ b/json-modules/json-3/src/main/java/com/baeldung/pojomapping/JsonToPojoMapper.java @@ -0,0 +1,37 @@ +package com.baeldung.pojomapping; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; +import org.json.JSONObject; + +public class JsonToPojoMapper { + + public static User mapManually(JSONObject jsonObject) { + User user = new User(); + user.setName(jsonObject.getString("name")); + user.setAge(jsonObject.getInt("age")); + user.setEmail(jsonObject.getString("email")); + + JSONObject addressObject = jsonObject.getJSONObject("address"); + Address address = new Address(); + address.setCity(addressObject.getString("city")); + address.setPostalCode(addressObject.getString("postalCode")); + user.setAddress(address); + + return user; + } + + public static User mapWithJackson(JSONObject jsonObject) { + ObjectMapper mapper = new ObjectMapper(); + try { + return mapper.readValue(jsonObject.toString(), User.class); + } catch (Exception e) { + return null; + } + } + + public static User mapWithGson(JSONObject jsonObject) { + Gson gson = new Gson(); + return gson.fromJson(jsonObject.toString(), User.class); + } +} \ No newline at end of file diff --git a/json-modules/json-3/src/main/java/com/baeldung/pojomapping/User.java b/json-modules/json-3/src/main/java/com/baeldung/pojomapping/User.java new file mode 100644 index 000000000000..e7ca16d13133 --- /dev/null +++ b/json-modules/json-3/src/main/java/com/baeldung/pojomapping/User.java @@ -0,0 +1,52 @@ +package com.baeldung.pojomapping; + +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.List; + +public class User { + private String name; + private int age; + private String email; + private Address address; + private List phones; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getAge() { + return age; + } + + public void setAge(int age) { + this.age = age; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public Address getAddress() { + return address; + } + + public void setAddress(Address address) { + this.address = address; + } + + public List getPhones() { + return phones; + } + + public void setPhones(List phones) { + this.phones = phones; + } +} \ No newline at end of file diff --git a/json-modules/json-3/src/test/java/com/baeldung/pojomapping/JsonToPojoMapperUnitTest.java b/json-modules/json-3/src/test/java/com/baeldung/pojomapping/JsonToPojoMapperUnitTest.java new file mode 100644 index 000000000000..d335841d4b6c --- /dev/null +++ b/json-modules/json-3/src/test/java/com/baeldung/pojomapping/JsonToPojoMapperUnitTest.java @@ -0,0 +1,136 @@ +package com.baeldung.pojomapping; + +import java.util.List; + +import org.json.JSONObject; +import org.junit.jupiter.api.BeforeEach; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; + +import static org.junit.jupiter.api.Assertions.*; + +public class JsonToPojoMapperUnitTest { + + private JSONObject simpleJsonObject; + private JSONObject jsonObjectWithPhones; + private String jsonArrayString; + + @BeforeEach + public void setUp() { + String simpleJsonString = """ + { + "name": "Alice", + "age": 25, + "email": "alice@example.com", + "address": { + "city": "Singapore", + "postalCode": "123456" + } + } + """; + simpleJsonObject = new JSONObject(simpleJsonString); + + String jsonStringWithPhones = """ + { + "name": "Alice", + "age": 25, + "email": "alice@example.com", + "address": { + "city": "Singapore", + "postalCode": "123456" + }, + "phones": ["12345678", "87654321"] + } + """; + jsonObjectWithPhones = new JSONObject(jsonStringWithPhones); + + jsonArrayString = """ + [ + { "type": "dog", "name": "Buddy", "barkVolume": 5 }, + { "type": "cat", "name": "Mimi", "likesFish": true } + ] + """; + } + + @Test + public void givenSimpleJsonObject_whenMappedManually_thenUserPojoIsCreatedCorrectly() { + User user = JsonToPojoMapper.mapManually(simpleJsonObject); + + assertEquals("Alice", user.getName()); + assertEquals(25, user.getAge()); + assertEquals("alice@example.com", user.getEmail()); + assertEquals("Singapore", user.getAddress().getCity()); + assertEquals("123456", user.getAddress().getPostalCode()); + } + + @Test + public void givenNestedJsonObject_whenMappedManually_thenAddressIsPopulatedCorrectly() { + User user = JsonToPojoMapper.mapManually(simpleJsonObject); + + assertNotNull(user.getAddress()); + assertEquals("Singapore", user.getAddress().getCity()); + assertEquals("123456", user.getAddress().getPostalCode()); + } + + @Test + public void givenSimpleJsonObject_whenMappedWithJackson_thenUserPojoIsCreatedCorrectly() { + User user = JsonToPojoMapper.mapWithJackson(simpleJsonObject); + + assertEquals("Alice", user.getName()); + assertEquals("Singapore", user.getAddress().getCity()); + assertEquals("123456", user.getAddress().getPostalCode()); + } + + @Test + public void givenJsonObjectWithPhones_whenMappedWithJackson_thenPhonesListIsPopulatedCorrectly() { + User user = JsonToPojoMapper.mapWithJackson(jsonObjectWithPhones); + + assertEquals("Alice", user.getName()); + assertEquals("Singapore", user.getAddress().getCity()); + assertEquals("123456", user.getAddress().getPostalCode()); + assertEquals(2, user.getPhones().size()); + assertEquals("12345678", user.getPhones().get(0)); + assertEquals("87654321", user.getPhones().get(1)); + } + + @Test + public void givenSimpleJsonObject_whenMappedWithGson_thenUserPojoIsCreatedCorrectly() { + User user = JsonToPojoMapper.mapWithGson(simpleJsonObject); + + assertEquals("Alice", user.getName()); + assertEquals(25, user.getAge()); + assertEquals("Singapore", user.getAddress().getCity()); + } + + @Test + public void givenJsonObjectWithPhones_whenMappedWithGson_thenPhonesListIsPopulatedCorrectly() { + User user = JsonToPojoMapper.mapWithGson(jsonObjectWithPhones); + + assertEquals("Alice", user.getName()); + assertEquals(25, user.getAge()); + assertEquals("Singapore", user.getAddress().getCity()); + assertEquals(2, user.getPhones().size()); + } + + @Test + public void givenPolymorphicJsonArray_whenMappedWithJackson_thenCorrectSubclassesAreCreated() throws Exception { + ObjectMapper mapper = new ObjectMapper(); + List animals = Arrays.asList( + mapper.readValue(jsonArrayString, Animal[].class) + ); + + assertEquals(2, animals.size()); + + assertTrue(animals.get(0) instanceof Dog); + Dog dog = (Dog) animals.get(0); + assertEquals("Buddy", dog.getName()); + assertEquals(5, dog.getBarkVolume()); + + assertTrue(animals.get(1) instanceof Cat); + Cat cat = (Cat) animals.get(1); + assertEquals("Mimi", cat.getName()); + assertTrue(cat.isLikesFish()); + } +} \ No newline at end of file