【问题标题】:XStream exception on generic list通用列表上的 XStream 异常
【发布时间】:2013-06-27 16:48:09
【问题描述】:

使用 XStream 1.4.4。

我有以下 XML:

<app name="MyApp">
    <properties>
        <property name="fizz" value="buzz" />
        <property name="foo" value="bar" />
    </properties>

    <fruit type="apple" />

    <!-- ...etc. -->
</app>

以及属性列表的相应 POJO,以及属性本身:

@XStreamAlias("properties")
public class Properties {
    private List<Property> properties = new ArrayList<Property>();

    public List<Property> getProperties() {
        return properties;
    }

    public void setProperties(List<Property> properties) {
        this.properties = properties;
    }
}

@XStreamAlias("property")
public class Property {
    private String name = null;

    private String value = null;

    public String getName() {
        return name;
    }

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

    public String getValue() {
        return value;
    }

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

当我尝试运行以下代码时:

XStream xs = new XStream();
Strnig xml = getXML(); // Fetches the string of XML from above
App app = (App)xs.fromXML(xml);

我明白了:

Exception in thread "main" com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$UnknownFieldException: No such field com.me.myapp.Properties.property
---- Debugging information ----
field               : property
class               : com.me.myapp.Properties
required-type       : com.me.myapp.Properties
converter-type      : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
path                : /app/properties/property
line number         : 4
class[1]            : com.me.myapp.App
version             : null
-------------------------------
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.determineType(AbstractReflectionConverter.java:453)
    at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doUnmarshal(AbstractReflectionConverter.java:294)
    ...rest of stack trace omitted for brevity

我哪里错了?

【问题讨论】:

  • 你过得怎么样?有任何成功或反馈,以便我们提供更多答案吗?

标签: java xml generics xstream oxm


【解决方案1】:

您根本不需要注释。只需使用别名 Property.class 作为“属性”,XStream 就会为您处理其他所有事情。

【讨论】:

    【解决方案2】:

    完全删除Properties 类。从 Property 类中删除 XStream 别名。将Property 类直接添加到App 类。使用以下别名以您希望的方式获得 XStream 序列化/反序列化:

    xstream.alias("property", Property.class);
    xstream.aliasField("property", Property.class, "properties");
    

    应该这样做:-)

    【讨论】:

      【解决方案3】:

      问题

      • 你有一个类com.me.myapp.Properties,别名为properties
      • 在其中,您有一个名为properties 的实例变量
      • 这是properties的两个级别
      • 您的 XML 有一级 properties

      我的建议

      • 在声明上方添加注释:

        @XStreamImplicit(itemFieldName="property")
        private List<Property> properties = new ArrayList<Property>()
        
      • 这表示省略包装列表的元素&lt;properties&gt;(隐式列表),并且还为列表中的每个项目使用元素&lt;property&gt;

      测试:

      • 一旦你认为你有正确的设置,首先通过生成 XML 进行测试:

        XStream xs = new XStream();
        App app = ...;              // Construct & populate a new App object
        String xml = xs.toXML(app); // Convert to XML
        System.out.println(xml);
        // This shows the XML format that must be used to parse XML to App.
        

      【讨论】:

        【解决方案4】:

        此代码将 XML(由您提供)转换为 App 对象。由于您给定的代码不足,所以我将整个代码粘贴在这里。我想你忘了提xstream.processAnnotations(App.class);

        <app name="MyApp">
            <properties>
                <property name="fizz" value="buzz" />
                <property name="foo" value="bar" />
            </properties>
        </app>
        

        package com.xstream;
        
        import com.thoughtworks.xstream.annotations.XStreamAlias;
        
        @XStreamAlias("app")
        public class App {
        
          @XStreamAlias("properties")
          private Properties properties;
        
          /**
           * @param properties
           */
          public App(Properties properties) {
            super();
            this.properties = properties;
          }
        
          /**
           * 
           */
          public App() {
            super();
            // TODO Auto-generated constructor stub
          }
        
          /**
           * @return the properties
           */
          public Properties getProperties() {
            return properties;
          }
        
          /**
           * @param properties the properties to set
           */
          public void setProperties(Properties properties) {
            this.properties = properties;
          }
        
          /* (non-Javadoc)
           * @see java.lang.Object#toString()
           */
          @Override
          public String toString() {
            return "App [properties=" + properties + "]";
          }
        
        }
        
        
        ----------
        
        package com.xstream;                                                                                                   
        
        import java.util.ArrayList;                                                                                            
        import java.util.List;                                                                                                 
        
        import com.thoughtworks.xstream.annotations.XStreamAlias;                                                              
        import com.thoughtworks.xstream.annotations.XStreamImplicit;                                                           
        
        @XStreamAlias("properties")                                                                                            
        public class Properties {                                                                                              
        
            @XStreamImplicit(itemFieldName = "property")                                                                       
            private List<Property> property = new ArrayList<Property>();                                                       
        
            public List<Property> getProperties() {                                                                            
                return property;                                                                                               
            }                                                                                                                  
        
            public void setProperties(List<Property> properties) {                                                             
                this.property = properties;                                                                                    
            }                                                                                                                  
        
            /**                                                                                                                
             * @return the property                                                                                            
             */                                                                                                                
            public List<Property> getProperty() {                                                                              
              return property;                                                                                                 
            }                                                                                                                  
        
            /**                                                                                                                
             * @param property the property to set                                                                             
             */                                                                                                                
            public void setProperty(List<Property> property) {                                                                 
              this.property = property;                                                                                        
            }                                                                                                                  
        
            /* (non-Javadoc)                                                                                                   
             * @see java.lang.Object#toString()                                                                                
             */                                                                                                                
            @Override                                                                                                          
            public String toString() {                                                                                         
              return "Properties [property=" + property + "]";                                                                 
            }                                                                                                                  
        
        
        }                                                                                                                      
        ----------------
        
        package com.xstream;
        
        import com.thoughtworks.xstream.annotations.XStreamAlias;
        import com.thoughtworks.xstream.annotations.XStreamAsAttribute;
        
        @XStreamAlias("property")
        public class Property {
        
          @XStreamAsAttribute
            private String name = null;
        
          @XStreamAsAttribute
            private String value = null;
        
            public String getName() {
                return name;
            }
        
            public void setName(String name) {
                this.name = name;
            }
        
            public String getValue() {
                return value;
            }
        
            public void setValue(String value) {
                this.value = value;
            }
        
            /* (non-Javadoc)
             * @see java.lang.Object#toString()
             */
            @Override
            public String toString() {
              return "Property [name=" + name + ", value=" + value + "]";
            }
        
        
        }
        

        Main 类的代码是。

        XStream xstream = new XStream();
        xstream.processAnnotations(App.class);
        
        App app = null;
        try {
          app = (App) xstream.fromXML(new FileInputStream(new File("D:/property.xml")));
        }
        catch (FileNotFoundException e) {
          e.printStackTrace();
        }
        
        System.out.println(app.toString());  
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2023-03-05
          • 1970-01-01
          • 1970-01-01
          • 2013-08-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多