2010-02-15 114 views
8

我试图编组一个对象作为其字段之一。JAXB使用java.lang.Object编组对象字段

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

DataObject中可以有很多不同的未知类型中的一种,所以指定每个地方不仅是不现实的,但不可能。当我尝试编组这个对象时,它说这个类对于上下文是不知道的。

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

String ti_m = JAXBMarshall.marshall(ti); 

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

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

+0

你在试图序列MockProcessData什么?即期望的表示是什么? – mtpettyp 2010-02-16 17:53:14

+0

作为第一次使用JAXB的用户,我尝试编制从头开始创建的对象树,即从编译的XSD创建的对象树时,遇到了完全相同的问题。事实上,我想要反过来,一旦我的代码工作,就从类中生成模式。我试图按照前面介绍的方式在JAXBElement中包装我的对象,并且我和之前的版本完全相同“Foobar不知道这个上下文”消息,所以我没有更进一步。 – 2011-05-20 20:40:16

+0

Hey Dasmotiu - 我最终包含了@XMLSeeAlso注解并提供了它可以尝试解组对象的所有类。例如: @XmlSeeAlso({ StringType.class, DecimalType.class, NumericType.class, BooleanType.class, StructType.class, ListType.class, DateType.class, SpatialType.class }) 公共抽象类FieldType { – jcovert 2011-05-21 19:55:34

回答

6

JAXB无法封送任何旧对象,因为它不知道如何。例如,它不知道要使用的元素名称。

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

尝试类似:

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

看起来不错,但我对此有两个问题。首先,元素名称 - 我不清楚它用于什么,但我认为“dataObject”就足够了?其次,JAXBElement是一种原始类型,编译器警告我应该参数化。我知道一个警告是一个警告,而不是一个错误,但由于我处于陌生领域,因此了解更多信息似乎是一个不错的主意。我不确定我要用它来参数化,因为我正在处理'对象'。谢谢! – jcovert 2010-02-16 15:45:37

+0

@jcovert:元素名称和命名空间可以是任何你喜欢的,所以是的,'dataObject'就可以。至于泛型,只需使用'JaxbElement ',这只是一个编译的事情,JAXB在运行时不关心。 – skaffman 2010-02-16 17:19:20

+1

花了我几分钟才得到它的工作,但确实这是一个很好的解决方案。一个小的变化(对于可能遇到相同问题的其他人):'ti.setDataObject(jaxbElement)'应该是'ti.setDataObject(jaxbElement.getValue())' 再次感谢您的帮助! – jcovert 2010-02-17 17:59:10

0

方法:

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; 
    } 
}