【问题标题】:BeanUtils converting java.util.Map to nested beanBeanUtils 将 java.util.Map 转换为嵌套 bean
【发布时间】:2015-11-26 18:42:34
【问题描述】:

我有一个 Java bean,它有一个字段,而该字段又是另一个 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}
}

我正在尝试将地图传递给 BeanUtils 以尝试将以下地图转换为 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);

但它会抛出一个错误说 - Cannot invoke BeanOne.setFieldTwo on bean class 'class Bean' - argument type mismatch - had objects of type "java.util.HashMap" but expected signature "BeanTwo"

如何使用 BeanUtils 正确填充内部 bean?

【问题讨论】:

  • 检查 BeanOne.java 的 fieldTwo 类型为 BeanTwo.. 但 setter 和 getter 类型为 String..
  • 谢谢。我不小心写了那个。现在修好了。
  • 我不相信这是可能的。填充BeanTwo,然后用它填充BeanOne

标签: java javabeans pojo apache-commons-beanutils


【解决方案1】:

你应该使用 Spring 的 BeanWrapper 类。它支持嵌套属性,并且可以选择为您创建内部 bean:

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();

感谢wrapper.setAutoGrowNestedPaths(true),实现了自动创建内部 bean 的杀手级功能。默认值为 false,这意味着如果属性路径中的元素为空,您将获得 NullValueInNestedPathException

【讨论】:

  • 我在我的项目中使用了spring mvc,这个解决方案对我来说是最好的。想想 spring mvc 自动绑定 JSON 到你的 bean,spring 工作得很好。所以,这个convert map to bean 解决方案真的很棒。
【解决方案2】:

你可以这样做......

BeanOne.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"));
    }

}

输出将是:-

fieldOneValue
fieldOne2222Value

【讨论】:

    猜你喜欢
    • 2017-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-03
    • 2013-12-07
    相关资源
    最近更新 更多