2011-06-06 78 views
2

我正在嘗試將add a comment轉換爲JAXB生成的XML @GET結果,這似乎不是一個簡單的任務。我正在使用Spring,並且I don't have direct access to the marshalling and DOM哪個JAXB實現實現Marshaller.getNode()?

通過將public void beforeMarshal(Marshaller m)添加到我的@XmlElement中,我應該可以通過Marshaller#getNode(Object)訪問DOM,從而能夠添加註釋。

的問題是AbstractMarshallerImpl#getNode(Object)

默認情況下,getNode方法是 不受支持並拋出一個 java.lang.UnsupportedOperationException。 選擇支持 此方法的實現必須重寫此方法。

getNode(Object)是否由任何JAXB實現在那裏實現?

回答

2

注:我領導EclipseLink JAXB (MOXy),是JAXB 2(JSR-222)專家組的成員。


莫西目前不支持可選的getNode方法見(增強請求https://bugs.eclipse.org/332762)。然而,JAXB的Binder可能與這種使用情況有所幫助:

演示

import javax.xml.bind.Binder; 
import javax.xml.bind.JAXBContext; 
import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.transform.Transformer; 
import javax.xml.transform.TransformerFactory; 
import javax.xml.transform.dom.DOMSource; 
import javax.xml.transform.stream.StreamResult; 

import org.w3c.dom.Comment; 
import org.w3c.dom.Document; 
import org.w3c.dom.Node; 

public class Demo { 

    public static void main(String[] args) throws Exception { 
     Customer customer = new Customer(); 
     customer.setName("Jane Doe"); 

     PhoneNumber homePhoneNumber = new PhoneNumber(); 
     customer.getPhoneNumbers().add(homePhoneNumber); 

     PhoneNumber workPhoneNumber = new PhoneNumber(); 
     customer.getPhoneNumbers().add(workPhoneNumber); 

     JAXBContext jc = JAXBContext.newInstance(Customer.class); 

     Binder<Node> binder = jc.createBinder(); 
     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
     DocumentBuilder db = dbf.newDocumentBuilder(); 
     Document document = db.newDocument(); 

     binder.marshal(customer, document); 
     Node homePhoneNumberElement = binder.getXMLNode(homePhoneNumber); 
     Comment comment = document.createComment("My Comment"); 
     homePhoneNumberElement.appendChild(comment); 

     TransformerFactory tf = TransformerFactory.newInstance(); 
     Transformer t = tf.newTransformer(); 
     DOMSource source = new DOMSource(document); 
     StreamResult result = new StreamResult(System.out); 
     t.transform(source, result); 
    } 

} 

客戶

import java.util.ArrayList; 
import java.util.List; 

import javax.xml.bind.annotation.XmlElement; 
import javax.xml.bind.annotation.XmlRootElement; 

@XmlRootElement 
public class Customer { 

    private String name; 

    private List<PhoneNumber> phoneNumbers = new ArrayList<PhoneNumber>(); 

    public String getName() { 
     return name; 
    } 

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

    @XmlElement(name="phone-number") 
    public List<PhoneNumber> getPhoneNumbers() { 
     return phoneNumbers; 
    } 

    public void setPhoneNumbers(List<PhoneNumber> phoneNumbers) { 
     this.phoneNumbers = phoneNumbers; 
    } 

} 

******中國

public class PhoneNumber { 

} 
+0

謝謝,Blaise!問題是,我不直接使用JAXBContext。我只是用@GET註釋我的方法並返回一個Response.ok(實體).build()。 – neu242 2011-06-07 06:10:57

+0

@ neu242 - 您可以利用MessageBodyReader/MessageBodyWriter的JAX-RS概念作爲此用例。有關如何使用JAXB的示例,請參閱:http://stackoverflow.com/questions/3428273/validate-jaxbelement-in-jpa-jax-rs-web-service/3440388#3440388 – 2011-06-07 14:42:59

+0

好吧,我有一個@Path(「/ myApi」)@Component @Scope(「request」)@Produces({「application/json」,「application/xml」}) public class MyResource,方法@GET public Response myMethod(){ MyEntity entity = getEntity();返回Response.ok(實體).build();}。現在,我創建了另一個@Provider @Consumes({「application/xml」,「application/json」})public class ValidatingReader實現MessageBodyReader {...}就像你的例子。 MessageBodyReader似乎沒有被觸發,我錯過了什麼? – neu242 2011-06-08 06:52:50