BeanUtils converts java.util.Map to a nested bean

I have a Java bean that has a field, which in turn is another bean

public class BeanOne { private String fieldOne; private BeanTwo fieldTwo; public String getFieldOne() {return this.fieldOne;} public void setFieldOne(String fieldOne){this.fieldOne = fieldOne} public BeanTwo getFieldTwo() {return this.fieldTwo;} public void setFieldTwo(BeanTwo fieldTwo){this.fieldTwo = fieldTwo} } public class BeanTwo { private String fieldOne; public String getFieldOne() {return this.fieldOne;} public void setFieldOne(String fieldOne){this.fieldOne = fieldOne} } 

I am trying to transfer a BeanUtils map to try to convert the next map to BeanOne

 Map beanOneMap = new HashMap<String, Object>(); beanOneMap.put("fieldOne", "fieldOneValue"); Map beanTwoMap = new HashMap<String, Object>(); beanTwoMap.put("fieldOne", "fieldOneValue"); beanOneMap.put("fieldTwo", beanTwoMap); BeanOne beanOne = new BeanOne(); BeanUtils.populate(beanOne, beanOneMap); 

But it gives an error message - Cannot invoke BeanOne.setFieldTwo on bean class 'class Bean' - argument type mismatch - had objects of type "java.util.HashMap" but expected signature "BeanTwo"

How can I use BeanUtils to properly fill the internal bean?

+6
source share
2 answers

Here we go, you can do like this ....

Beanonene.java

 import java.util.Map; public class BeanOne { private String fieldOne; private Map<String,BeanTwo> fieldTwo; public Map<String, BeanTwo> getFieldTwo() { return fieldTwo; } public void setFieldTwo(Map<String, BeanTwo> fieldTwo) { this.fieldTwo = fieldTwo; } public String getFieldOne() { return this.fieldOne; } public void setFieldOne(String fieldOne) { this.fieldOne = fieldOne; } } 

Beantwo.java

 public class BeanTwo { private String fieldOne; public String getFieldOne() { return this.fieldOne; } public void setFieldOne(String fieldOne) { this.fieldOne = fieldOne; } } 

Tester.java

 import java.lang.reflect.InvocationTargetException; import java.util.HashMap; import java.util.Map; import org.apache.commons.beanutils.BeanUtils; public class Tester { public static void main(String[] args) throws IllegalAccessException, InvocationTargetException { Map beanTwoMap = new HashMap(); beanTwoMap.put("fieldOne", "fieldOne2222Value"); Map beanOneMap = new HashMap(); beanOneMap.put("fieldOne", "fieldOneValue"); beanOneMap.put("fieldTwo", beanTwoMap); BeanOne beanOne = new BeanOne(); BeanUtils.populate(beanOne, beanOneMap); System.out.println(beanOne.getFieldOne()); System.out.println(beanOne.getFieldTwo().get("fieldOne")); } } 

the output will be: -

 fieldOneValue fieldOne2222Value 
+4
source

You must use the Spring BeanWrapper class. It supports nested properties and possibly creates internal beans for you:

 BeanOne one = new BeanOne(); BeanWrapper wrapper = PropertyAccessorFactory.forBeanPropertyAccess(one); wrapper.setAutoGrowNestedPaths(true); Map<String, Object> map = new HashMap<>(); map.put("fieldOne", "fieldOneValue"); map.put("fieldTwo.fieldOne", "fieldOneValue"); wrapper.setPropertyValues(map); assertEquals("fieldOneValue", one.getFieldOne()); BeanTwo two = one.getFieldTwo(); assertNotNull(two); assertEquals("fieldOneValue", two.getFieldOne(); 

The killer function for automatically creating internal beans is achieved thanks to wrapper.setAutoGrowNestedPaths(true) . The default value is false, which means that you will get a NullValueInNestedPathException if the element in the property path is null.

+4
source

All Articles