2011-08-12 132 views
4

我有一些@ javax.xml.bind.annotation.Xml ...這裏的註釋類用於RESt Web服務。 Jersey被安裝在一個彈簧託管的Web容器中,Web服務正在返回格式良好的xml。我們使用maven-enunciate-plugin來記錄Web服務併爲返回的xml文檔創建xsd。我現在想在返回的xml文件中使用文檔xsd文件作爲schemaLocation,以便xml驗證不會抱怨缺少定義。我如何獲得爲此配置的XML序列化?如何自定義Jersey JAXB序列化的XML輸出

回答

7

如果我沒有記錯的話,我不得不做一些事情來將命名空間標識符正確寫入我生成的XML中。

1)創建一個JaxbFactory,它配置並返回一個自定義編組器(並且解組器也是BTW)。我正在省略下面的getters /和unmarshalling設置...

//constructor 
public JaxbFactory() throws Exception { 
    context = JAXBContext.newInstance(ResourceDto.class); 

    // Setup the marshaller 
    marshaller = context.createMarshaller(); 
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); 
    marshaller.setProperty(Marshaller.JAXB_SCHEMA_LOCATION, XmlMetadataConstants.XML_SCHEMA_LOCATION); // this schema location is used in generating the schema-location property in the xml 
} 

2)該工廠類對Jersey沒有「可見」。爲了使其可見,我創建了一個MarshallerProvider。這看起來是這樣的:

@Provider 
public class ResourceJaxbMarshallerProvider implements ContextResolver<Marshaller> { 
// injected by Spring 
private ResourceJaxbFactory ResourceJaxbFactory; 
private ResourceStatusJaxbFactory ResourceStatusJaxbFactory; 


/* 
* ---------------------------------------- 
* Setters (for Spring injected properties) 
* ---------------------------------------- 
*/ 
public void setResourceJaxbFactory(ResourceJaxbFactory ResourceJaxbFactory) { 
    this.ResourceJaxbFactory = ResourceJaxbFactory; 
} 

public void setResourceStatusJaxbFactory(ResourceStatusJaxbFactory ResourceStatusJaxbFactory) { 
    this.ResourceStatusJaxbFactory = ResourceStatusJaxbFactory; 
} 

/* 
* ------------------------ 
* Interface Implementation 
* ------------------------ 
*/ 
public Marshaller getContext(Class<?> type) { 
    if (type == ResourceDto.class) 
     return ResourceJaxbFactory.getMarshaller(); 
    else if (type == ResourceStatusDto.class) 
     return ResourceStatusJaxbFactory.getMarshaller(); 
    else 
     return null; 
}  
} 

我有澤西使用Jersey有線到Spring /春天的Servlet,因此任何@Provider類,得到由春創建自動由新澤西州的認可。在我的Spring applicationContext.xml中,我只需要實例化資源提供者。反過來,它將從工廠抓住編組人員。

3)我發現的另一個關鍵是我必須在包含我的資源的根包中創建一個package-info.java文件。看起來是這樣的:

/* 
* Note that this file is critical for ensuring that our ResourceDto object is 
* marshalled/unmarshalled with the correct namespace. Without this, marshalled 
* classes produce XML files without a namespace identifier 
*/ 
@XmlSchema(namespace = XmlMetadataConstants.XML_SCHEMA_NAMESPACE, elementFormDefault = XmlNsForm.QUALIFIED) 
package com.yourcompany.resource; 

import javax.xml.bind.annotation.XmlNsForm; 

至少我認爲這就是我需要做的一切,我不能記住每一個單件。我記得package-info.java作品是最後一個讓所有人都聚集在一起的關鍵齒輪。

希望有所幫助。我花了很多時間挖掘這些信息。在我希望它進行適當的XML模式驗證之前,澤西島是誘人簡單的(對於模式無效輸入,還有體面的錯誤報告)。一旦我開始走下這條道路,澤西從腦死亡變得容易體面硬。大部分難度都是從網上各種帖子的所有細節中提煉出來的。希望這會幫助你更快,更快。 :-)