diff --git a/core-java-modules/core-java-collections-maps-8/pom.xml b/core-java-modules/core-java-collections-maps-8/pom.xml index 8c4454cf0fe8..d29145f0a785 100644 --- a/core-java-modules/core-java-collections-maps-8/pom.xml +++ b/core-java-modules/core-java-collections-maps-8/pom.xml @@ -13,6 +13,24 @@ 0.0.1-SNAPSHOT + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + com.google.code.gson + gson + ${gson.version} + + + commons-beanutils + commons-beanutils + ${beanutils.version} + + + @@ -26,4 +44,11 @@ + + + 2.10.1 + 2.17.0 + 1.9.4 + + diff --git a/core-java-modules/core-java-collections-maps-8/src/main/java/com/baeldung/map/castingmaptoobject/Address.java b/core-java-modules/core-java-collections-maps-8/src/main/java/com/baeldung/map/castingmaptoobject/Address.java new file mode 100644 index 000000000000..ddac852b7e83 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-8/src/main/java/com/baeldung/map/castingmaptoobject/Address.java @@ -0,0 +1,43 @@ +package com.baeldung.map.castingmaptoobject; + +public class Address { + private String city; + private Country country; + + public Address() { + // default constructor needed for Jackson deserialization + } + + public Address(String city, Country country) { + this.city = city; + this.country = country; + } + + public Country getCountry() { + return country; + } + + public void setCountry(Country country) { + this.country = country; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + Address address = (Address) o; + + if (!city.equals(address.city)) return false; + return country.getName().equals(address.country.getName()); + } + +} diff --git a/core-java-modules/core-java-collections-maps-8/src/main/java/com/baeldung/map/castingmaptoobject/Country.java b/core-java-modules/core-java-collections-maps-8/src/main/java/com/baeldung/map/castingmaptoobject/Country.java new file mode 100644 index 000000000000..effa891ff0dd --- /dev/null +++ b/core-java-modules/core-java-collections-maps-8/src/main/java/com/baeldung/map/castingmaptoobject/Country.java @@ -0,0 +1,21 @@ +package com.baeldung.map.castingmaptoobject; + +public class Country { + private String name; + + public Country() { + // default constructor needed for Jackson deserialization + } + + public Country(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} diff --git a/core-java-modules/core-java-collections-maps-8/src/main/java/com/baeldung/map/castingmaptoobject/User.java b/core-java-modules/core-java-collections-maps-8/src/main/java/com/baeldung/map/castingmaptoobject/User.java new file mode 100644 index 000000000000..2ee95b24ec91 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-8/src/main/java/com/baeldung/map/castingmaptoobject/User.java @@ -0,0 +1,33 @@ +package com.baeldung.map.castingmaptoobject; + +import java.util.List; + +public class User { + private Long id; + private String name; + private List
addresses; + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public List
getAddresses() { + return addresses; + } + + public void setAddresses(List
addresses) { + this.addresses = addresses; + } +} diff --git a/core-java-modules/core-java-collections-maps-8/src/test/java/com/baeldung/map/castingmaptoobject/CastingMapToObjectUnitTest.java b/core-java-modules/core-java-collections-maps-8/src/test/java/com/baeldung/map/castingmaptoobject/CastingMapToObjectUnitTest.java new file mode 100644 index 000000000000..706bfc198bc0 --- /dev/null +++ b/core-java-modules/core-java-collections-maps-8/src/test/java/com/baeldung/map/castingmaptoobject/CastingMapToObjectUnitTest.java @@ -0,0 +1,86 @@ +package com.baeldung.map.castingmaptoobject; + +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.google.gson.Gson; +import org.apache.commons.beanutils.BeanUtils; +import org.junit.jupiter.api.Test; + +import java.lang.reflect.InvocationTargetException; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +public class CastingMapToObjectUnitTest { + + private static final Map map = Map.of( + "id", 1L, + "name", "Baeldung", + "addresses", List.of( + new Address("La Havana", new Country("Cuba")), + new Address("Paris", new Country("France")) + ) + ); + + @Test + void givenMap_whenCasting_thenThrow() { + assertThrows(ClassCastException.class, () -> { User user = (User) map; }); + } + + @Test + void givenMap_whenUsingBeanUtils_thenConvertToObject() throws InvocationTargetException, IllegalAccessException { + User user = new User(); + BeanUtils.populate(user, map); + + assertEqualsMapAndUser(map, user); + } + + @Test + void givenMap_whenUsingJackson_thenConvertToObject() { + ObjectMapper objectMapper = new ObjectMapper(); + User user = objectMapper.convertValue(map, User.class); + + assertEqualsMapAndUser(map, user); + } + + @Test + void givenMap_whenUsingJacksonWithWrongAttrs_thenThrow() { + Map modifiedMap = new HashMap<>(map); + modifiedMap.put("enabled", true); + + ObjectMapper objectMapper = new ObjectMapper(); + + assertThrows(IllegalArgumentException.class, () -> objectMapper.convertValue(modifiedMap, User.class)); + } + + @Test + void givenMap_whenUsingJacksonIgnoreUnknownProps_thenConvertToObject() { + Map modifiedMap = new HashMap<>(map); + modifiedMap.put("enabled", true); + + ObjectMapper objectMapper = new ObjectMapper(); + objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + User user = objectMapper.convertValue(modifiedMap, User.class); + + assertEqualsMapAndUser(modifiedMap, user); + } + + @Test + void givenMap_whenUsingGson_thenConvertToObject() { + Gson gson = new Gson(); + String jsonMap = gson.toJson(map); + User user = gson.fromJson(jsonMap, User.class); + + assertEqualsMapAndUser(map, user); + } + + private static void assertEqualsMapAndUser(Map map, User user) { + assertEquals(map.get("id"), user.getId()); + assertEquals(map.get("name"), user.getName()); + assertEquals(map.get("addresses"), user.getAddresses()); + } + +}