支持多个xsd版本

zpgglvta  于 2021-07-09  发布在  Java
关注(0)|答案(1)|浏览(358)

让我解释一下我的场景:我有一个web应用程序,它接受xml请求并响应。我使用jaxb解析请求,将其转换为我的应用程序dao对象,处理请求,然后将dao结果重新转换为jaxb对象并返回该对象。现在我必须支持多个版本(不同的xml版本可以根据请求提供,我必须用合适的xml响应来响应)。我为jaxb object->dao object convertor和reverse生成java文件。问题是,在转换到我的dao对象之前,jaxb对象被创建,然后在传递给我的转换器之前被验证。我不确定在这里应用什么样的设计模式。可能是适配器模式。请建议?如果我可能还需要生成jaxb编组和取消编组代码,也可以这么说吗?

xxb16uws

xxb16uws1#

希望我能很好地理解你的问题。所以你已经有了:

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

现在需要修改一种新的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对象传递给marshaller并验证 xsd 你可能已经在用解编器了:
元帅:

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);

相关问题