2012-08-25 186 views
2

讓我解釋我的場景 我有一個Web應用程序,它接受xml請求並作出響應。 我已經使用jaxb解析請求,將其轉換爲我的應用程序dao對象,處理請求,然後將dao結果重新轉換爲jaxb對象並返回該請求。 現在我必須支持多個版本(不同的xml版本可以作爲請求來,我必須迴應合適的xml響應)。 我爲jaxb對象 - > dao對象轉換器和反轉生成java文件。 問題是,在轉換爲我的dao對象之前,jaxb對象被創建並在將其傳遞給我的轉換器之前進行驗證。我不確定在這裏應用什麼樣的設計模式。 可能是適配器模式。請建議? 也扔光,如果我可能不得不生成jaxb編組和代碼呢?支持多種xsd版本

回答

1

希望我能很好地理解你的問題。所以你已經有:

xml 1 ---> jaxb objects 1 ---> converter 1 ---> entity objects 

現在你需要acomodate一個新的XML格式。

爲此,您可以編寫一個新的轉換器,以支持新格式:

xml 2 ---> jaxb objects 2 ---> converter 2 ---> entity objects 

或寫一些XML適配器,以適應新的JAXB對象第一格式:

xml 2 ---> jaxb objects 2 ---> adapter ---> jaxb objects 1 ---> converter 1 ---> entity objects 

我會建議第一個的方法:編寫一個新的轉換器,使新格式不依賴於第一個格式(以防可能需要退出第一格式)。

對於複雜類型,轉換器將自身與jaxb對象混合在一起作爲實體對象的包裝以及@XmlJavaTypeAdapter。一個很簡單的例子:

public class XmlPerson { 
    private Person person; 

    public XmlPerson(Person person) { 
     this.person = person; 
    } 

    public XmlPerson() { 
     this.person = new Person(); 
    } 

    public Person getPerson() { 
    } 

    public String getFirstName() { 
     return person.getFristname(); 
    } 

    public void setFirstname(String firstName) { 
     person.setFirstName(firstName); 
    } 

    .... 

    @XmlJavaTypeAdapter(XmlAddressAdapter.class) 
    public Address getAddress() { 
     return person.getAddress(); 
    } 

    public void setAddress(Address address) { 
     person.setAddress(address); 
    } 
} 

@XmlJavaTypeAdapter應該自己適應(轉換)從AddressXmlAddress

public class XmlAddressAdapter extends XmlAdapter<XmlAddress, Address> { 
    @Override 
    public Address unmarshal(XmlAddress xmlAddress) throws Exception { 
     return xmlAddress.getAddress(); 
    } 

    @Override 
    public XmlAddress marshal(Address address) throws Exception { 
     return address != null ? new XmlAddress(address) : null; 
    } 
} 

而且扔光,如果我可以有太多生成JAXB編組和未編組代碼?

你只需要通過XML對象編組,並與解組驗證xsd作爲yoou可能已經這樣做:

元帥:

JAXBContext jaxbContext = JAXBContext.newInstance(XmlPerson.class); 
    Marshaller jaxbMarshaller = jaxbContext.createMarshaller(); 
    jaxbMarshaller.marshal(xmlPerson, output); 

解組:

JAXBContext jaxbContext = JAXBContext.newInstance(targetClass); 
Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); 

SchemaFactory sf = SchemaFactory.newInstance(
        javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI); 
Schema schema = sf.newSchema(XmlInvoice.class.getResource("/yourXsd.xsd")); 
jaxbUnmarshaller.setSchema(schema); 

Object unmarshalResult = jaxbUnmarshaller.unmarshal(inputStream); 
+0

謝謝dcernahoschi,我正在做類似於你的建議。 –

+0

我將檢查出XmlJavaTypeAdapter並取回。儘管在檢出XmlJavaTypeAdapter之前太早,如果2個jaxb對象完全不兼容並且意味着一件事或另一件事,這個設計是否會起作用 –

+0

不,我不是在尋找像這樣的東西。解釋更多。我的層架構是xml 1 ---> jaxb對象1 --->一些代碼--->轉換器1 --->實體對象 我不能修改任何在「jaxb objects 1」java文件中生成的war文件使用xjc編譯時間。我寫了一個可以生成「轉換器1」的框架。請提出一個設計,我可以如何使「通常的代碼」部分成爲可能,以便將來如果「jaxb對象1」發生變化並與當前版本不兼容,我可能不需要更改「某些代碼」部分。 –