带有 java.lang.Object 字段的 JAXB 编组对象

Posted

技术标签:

【中文标题】带有 java.lang.Object 字段的 JAXB 编组对象【英文标题】:JAXB Marshalling Objects with java.lang.Object field 【发布时间】:2011-01-17 04:33:47 【问题描述】:

我正在尝试编组一个将 Object 作为其字段之一的对象。

@XmlRootElement
public class TaskInstance implements Serializable 
   ...
   private Object dataObject;
   ...

dataObject 可以是许多不同的unknown 类型之一,因此在某处指定每个类型不仅不切实际而且不可能。当我尝试编组对象时,它说上下文不知道该类。

MockProcessData mpd = new MockProcessData();
TaskInstance ti = new TaskInstance();
ti.setDataObject(mpd);

String ti_m = JAXBMarshall.marshall(ti);

“MockProcessData 及其任何超类在此上下文中都是已知的。”是我得到的。

有没有办法解决这个错误?

【问题讨论】:

你试图将 MockProcessData 序列化为什么?即,期望的表示是什么? 作为第一次使用 JAXB 的用户,我在尝试编组从头开始创建的对象树时遇到了完全相同的问题,即不是从已编译的 XSD 创建的。事实上,我想反过来做,一旦我的代码工作,就从类中生成模式。我尝试按照描述将我的对象包装在一个 JAXBElement 中,我得到了与以前完全相同的“Foobar is not known to this context”消息,所以我没有更进一步。 Hey Dasmotiu - 我最终包含了 @XMLSeeAlso 注释并提供了它可以尝试解组对象的所有类。例如:@XmlSeeAlso( StringType.class, DecimalType.class, NumericType.class, BooleanType.class, StructType.class, ListType.class, DateType.class, SpatialType.class ) public abstract class FieldType 【参考方案1】:

JAXB 无法编组任何旧对象,因为它不知道如何编组。例如,它不知道要使用什么元素名称。

如果您需要处理这种通配符,唯一的解决方案是将对象包装在 JAXBElement 对象中,该对象包含足够的信息供 JAXB 编组为 XML。

尝试类似:

QName elementName = new QName(...); // supply element name here
JAXBElement jaxbElement = new JAXBElement(elementName, mpd.getClass(), mpd);
ti.setDataObject(jaxbElement);

【讨论】:

看起来不错,但我对此有两个问题。首先,元素名称 - 我不清楚它的用途,但我认为“dataObject”就足够了?其次,JAXBElement 是原始类型,编译器警告我应该对其进行参数化。我知道警告是警告而不是错误,但是由于我处于不熟悉的领域,因此了解更多信息似乎是个好主意。我不确定我会用什么参数化它,因为我正在处理“对象”。谢谢! @jcovert:元素名称和命名空间可以是任何你喜欢的,所以是的,dataObject 就可以了。至于泛型,就用JaxbElement<Object>吧,只是编译的东西,JAXB在运行时不关心。 我花了几分钟才让它工作,但这确实是一个很好的解决方案。一个小改动(对于可能遇到同样问题的其他人):ti.setDataObject(jaxbElement) 应该是 ti.setDataObject(jaxbElement.getValue()) 再次感谢您的帮助! 您好,我尝试过这样做。但我仍然遇到同样的错误。我的问题张贴在这里。 ***.com/questions/14057932/… 。你能帮帮我吗? 我喜欢这个想法,我会自己尝试并发布结果。我想做的是将 ResultSet 对象写入 XML【参考方案2】:

方法:

public String marshallXML(Object object) 
        JAXBContext context;
        try 
            context = JAXBContext.newInstance(object.getClass());
            StringWriter writer = new StringWriter();
            Marshaller marshaller = context.createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
            marshaller.marshal(object, writer);
            String stringXML = writer.toString();
            return stringXML;
         catch (JAXBException e) 

        

型号:

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Customer 
    String name;
    int id;
    public String getName() 
        return name;
    
    @XmlElement
    public void setName(String name) 
        this.name = name;
    
    public int getId() 
        return id;
    
    @XmlAttribute
    public void setId(int id) 
        this.id = id;
    

【讨论】:

以上是关于带有 java.lang.Object 字段的 JAXB 编组对象的主要内容,如果未能解决你的问题,请参考以下文章

杂-The type java.lang.Object cannot be resolved It is indirectly referenced ...

为啥 java.lang.Cloneable 不覆盖 java.lang.Object 中的 clone() 方法?

java.lang.Class java.lang.Object.getClass()' 在空对象引用上

maven找不到java.lang.object的类文件

Spring mvc的jdbc查询:queryForInt(java.lang.String sql, java.lang.Object... args)

ClassCastException:java.lang.Object[] 无法转换为 java.lang.String[] android