java - 使用反射在 jaxb 对象上设置 ArrayList 值时出现问题

标签 java reflection jaxb propertydescriptor

我正在尝试从对象集合(标签)中读取值并使用反射将它们映射到 jaxb 生成的对象。我有一个字段列表,用于从主对象中过滤所需的字段。

这是示例代码。我使用内部类 Tag 作为需要从中提取值的列表。列表 fieldList 充当过滤器。目标是使用反射将这些值复制到 jaxb 生成的对象。我正在使用 javabean PropertyDescriptor 来实现这一点。

现在,我遇到了为 jaxb 对象中的集合字段设置值的问题。对于列表字段,jaxb 不提供 setter,而您必须使用 getList().add(object)。我该如何实现这一目标?

public class ReflectionTest2 {
    /**
     * @param args
     */
    public static void main(String[] args) {
        try{
            ReflectionTest2 testObj = new ReflectionTest2();
            List<Tag> tagList = new ArrayList<Tag>();
            createTag(tagList, testObj);

            List<String> fieldList = new ArrayList<String>();
            fieldList.add("ADSKContentGroup");
            fieldList.add("title");

            CaasContextObject object = new CaasContextObject();

            for(Tag each : tagList){
                innerLoop:
                    for(String field : fieldList){
                        if(each.name.equals(field)){
                            for (PropertyDescriptor pd : Introspector.getBeanInfo(
                                    CaasContextObject.class).getPropertyDescriptors()) {
                                if(pd.getWriteMethod() != null && !"class".equals(pd.getName())){
                                                                        if(pd.getName().equals(each.name)){         
                                        if(pd.getPropertyType().isAssignableFrom(java.util.List.class)){
                                            // handle list
                                        }else{
                                            pd.getWriteMethod().invoke(object, each.value);
                                        }
                                        break innerLoop;
                                    }
                                }
                            }
                        }
                    }
            }

            // Read object
            System.out.println("\n\nPrinting Title -->"+object.getTitle());
            for(String cg : object.getADSKContentGroup()){
                System.out.println(cg);
            }
        }catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void createTag(List<Tag> tagList, ReflectionTest2 obj){
        Tag tag1 = obj.new Tag();
        tag1.setName("ADSKContentGroup");
        tag1.setValue("Documentation");
        tagList.add(tag1);

        Tag tag2 = obj.new Tag();
        tag2.setName("ADSKContentGroup");
        tag2.setValue("User Guide");
        tagList.add(tag2);

        Tag tag3 = obj.new Tag();
        tag3.setName("title");
        tag3.setValue("Test Title");
        tagList.add(tag3);
    }

    public class Tag {
        protected String name;
        protected String value;

        public String getName() {
            return name;
        }

        public void setName(String value) {
            this.name = value;
        }

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }
    }
}

Jaxb 生成的对象

public class CaasContextObject{

    @XmlElement(required = true)
    protected String title;
    @XmlElement(name = "ADSKContentGroup")
    protected List<String> adskContentGroup;


    public String getTitle() {
        return title;
    }

    public void setTitle(String value) {
        this.title = value;
    }

     /**
     * Gets the value of the adskContentGroup property.
     * 
     * <p>
     * This accessor method returns a reference to the live list,
     * not a snapshot. Therefore any modification you make to the
     * returned list will be present inside the JAXB object.
     * This is why there is not a <CODE>set</CODE> method for the adskContentGroup property.
     * 
     * <p>
     * For example, to add a new item, do as follows:
     * <pre>
     *    getADSKContentGroup().add(newItem);
     * </pre>
     * 
     * 
     * <p>
     * Objects of the following type(s) are allowed in the list
     * {@link String }
     * 
     * 
     */
    public List<String> getADSKContentGroup() {
        if (adskContentGroup == null) {
            adskContentGroup = new ArrayList<String>();
        }
        return this.adskContentGroup;
    }
}

如您所见,问题在于设置 adskContentGroup 值。

任何指示将不胜感激。

谢谢

最佳答案

这是您要找的吗?

if (pd.getReadMethod() != null && pd.getReadMethod().getReturnType().isAssignableFrom(List.class)) {
    Method method = pd.getReadMethod();
    List list = (List) method.invoke(mc);
    list.add("Hello World!"); // change the passed String of course
}

关于java - 使用反射在 jaxb 对象上设置 ArrayList 值时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17287433/

相关文章:

java - 如何在 JAXB 中映射已有的 java bean

java - ANT 属性环境 ="env"无法在 JAVA 中检索它,但如果作为 ant 命令运行则工作正常

java - 获取声明的方法 - Java

java - Spring 内部事务中的 UnexpectedRollBackException

java - Kotlin 反射问题

java - 如何使用 Java 中的反射来确定字段是私有(private)字段还是 protected 字段?

xml - jaxbcontext 生成不完整的模式?

java - 我可以对带分隔符的文件使用 Eclipselink Moxy 编码吗?

java - 平面图嵌套集合

java - 添加子菜单