2012-08-25 139 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”发生变化并与当前版本不兼容,我可能不需要更改“某些代码”部分。 –