2009-11-03 43 views
3

我試圖編組一個具有JAXB(2.1.12)的DataHandler字段的對象。對於流式支持,DataHandler使用@XmlAttachmentRef進行註釋。通過Web服務進行序列化和流式傳輸(Metro on JBoss)可以正常工作,但使用JAXB進行簡單編組卻不行。如何編組一個DataHandler用JAXB註解爲@XmlAttachmentRef?

這裏是一個精簡的例子:

public class DataHandlerAttachmentSerialization { 

    @XmlRootElement 
    static class RootObject { 
     @XmlElement 
     @XmlAttachmentRef // Works without this, but required for streaming 
     DataHandler dataHandler = new DataHandler(
       new com.sun.xml.ws.util.ByteArrayDataSource(
       " ".getBytes(), "application/octet-stream")); 
    } 

    @Test 
    public void test() throws JAXBException { 
     JAXBContext context = JAXBContext.newInstance(RootObject.class); 
     Marshaller marshaller = context.createMarshaller(); 
     StringWriter writer = new StringWriter(); 
     marshaller.marshal(new RootObject(), writer); 
     Assert.assertNotNull(writer.toString()); 
    } 
} 

運行這個測試得出以下堆棧跟蹤:

javax.xml.bind.MarshalException 
- with linked exception: 
[com.sun.xml.bind.api.AccessorException: java.lang.NullPointerException] 
    at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:318) 
    at com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:244) 
    at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:96) 
    ... 
Caused by: com.sun.xml.bind.api.AccessorException: java.lang.NullPointerException 
    at com.sun.xml.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:246) 
    at com.sun.xml.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:261) 
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:335) 
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsSoleContent(XMLSerializer.java:593) 
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(ClassBeanInfoImpl.java:320) 
    at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:494) 
    at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:315) 
    ... 25 more 
Caused by: com.sun.xml.bind.api.AccessorException: java.lang.NullPointerException 
    at com.sun.xml.bind.v2.runtime.reflect.AdaptedAccessor.get(AdaptedAccessor.java:74) 
    at com.sun.xml.bind.v2.runtime.reflect.TransducedAccessor$CompositeTransducedAccessorImpl.writeLeafElement(TransducedAccessor.java:250) 
    at com.sun.xml.bind.v2.runtime.property.SingleElementLeafProperty.serializeBody(SingleElementLeafProperty.java:98) 
    at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:332) 
    ... 29 more 
Caused by: java.lang.NullPointerException 
    at com.sun.xml.bind.v2.runtime.SwaRefAdapter.marshal(SwaRefAdapter.java:80) 
    at com.sun.xml.bind.v2.runtime.SwaRefAdapter.marshal(SwaRefAdapter.java:65) 
    at com.sun.xml.bind.v2.runtime.reflect.AdaptedAccessor.get(AdaptedAccessor.java:72) 
    ... 32 more 

線80 SwaRefAdapterreturn am.addSwaRefAttachment(data);amAttachmentMarshaller am = XMLSerializer.getInstance().attachmentMarshaller;分配如此看來attachmentMarshaller如果@XmlAttachmentRef存在,則此時爲空。

我需要設置不同的東西,還是以不同的方式使用JAXB API來處理附件?

回答

5

在JAX-WS環境外部使用JAXB時,JAXB實現應默認將XML文檔中的二進制內容內聯爲base64Binary。

這似乎是JAXB(包含在JDK/JRE中的RI)在Metro中的缺陷。如果您使用其他JAXB實現(例如EclipseLink JAXB (MOXy)),則此操作將正常工作。要使用的EclipseLink莫西的eclipselink.jar(available here)添加到您的類路徑,並添加jaxb.properties文件與模型類時,以下內容:

javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory 

JAX-WS註冊AttachmentMarshallers & AttachmentUnmarshallers處理二進制JAXB模型中的內容。如果您願意,可以在使用JAXB獨立版時指定自己的版本。

http://download.oracle.com/docs/cd/E17409_01/javase/6/docs/api/javax/xml/bind/attachment/AttachmentMarshaller.html