jaxb将命名空间添加到元素

时间:2015-12-21 14:13:26

标签: web-services soap jaxb wsdl

根据我的任务,我必须调用SOAP服务。所以,我使用xjc从wsdl生成了java类。但是我在调​​用SOAP服务时遇到了问题。我的应用程序生成此请求:

    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"/><soap:Body>
<typ:SendMessage xmlns:ns4="http://test.user.kz/UserInfo" xmlns:q1="http://test.user.kz/CustomerInfo" xmlns:typ="http://test.user.kz/MyChannel/v1/Types">
    <request>
        <requestInfo>
            <messageId>26e96b11-8f82-421e-829a</messageId>
        </requestInfo>
        <requestData>
            <data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="q1:PaymentPackageRequestType">
                <q1:methodName>testMethod</q1:methodName>
            </data>
        </requestData>
    </request>
</typ:SendMessage></soap:Body></soap:Envelope>

但我需要在我的SOAP请求中指定数据标记中的命名空间,喜欢这个:

     <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"/><soap:Body>
<typ:SendMessage xmlns:ns4="http://test.user.kz/UserInfo" xmlns:q1="http://test.user.kz/CustomerInfo" xmlns:typ="http://test.user.kz/MyChannel/v1/Types">
    <request>
        <requestInfo>
            <messageId>26e96b11-8f82-421e-829a</messageId>
        </requestInfo>
        <requestData>
                        <data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  xsi:type="q1:PaymentPackageRequestType"  **xmlns:q1="http://payments.bee.kz/PaymentPackage"**>
                <q1:methodName>testMethod</q1:methodName>
            </data>
        </requestData>
    </request>
</typ:SendMessage></soap:Body></soap:Envelope>

否则目标SOAP服务会给我错误:

XML namespace prefix 'q1' is not defined.

如何在数据标记中指定命名空间? 这是我目前的包裹信息:

@javax.xml.bind.annotation.XmlSchema(
        xmlns = {
            @javax.xml.bind.annotation.XmlNs(prefix = "typ",
                    namespaceURI = "http://test.user.kz/MyChannel/v1/Types"),
            @javax.xml.bind.annotation.XmlNs(prefix = "q1",
                    namespaceURI = "http://test.user.kz/CustomerInfo")
        },
   elementFormDefault = javax.xml.bind.annotation.XmlNsForm.UNQUALIFIED,
   attributeFormDefault = javax.xml.bind.annotation.XmlNsForm.UNSET
)
package kz.uni.gen;

所以我无法添加名称空间xmlns:q1 =&#34; http://test.user.kz/CustomerInfo"到SOAP请求中的数据标记。如何从SendMessage标记中添加此命名空间声明或移动命名空间声明?

1 个答案:

答案 0 :(得分:0)

所以使用JAXB是不可能的。因此,我在所需元素中手动添加名称空间。这是完整的代码段:

Document document = null;
        try {
            document = DocumentBuilderFactory.newInstance().newDocumentBuilder().newDocument();
            Marshaller marshaller = JAXBContext.newInstance(SendMessage.class).createMarshaller();
            marshaller.setProperty(Marshaller.JAXB_ENCODING, "UTF-8");
            marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
            marshaller.setProperty("com.sun.xml.bind.characterEscapeHandler", new CharacterEscapeHandler() {
                @Override
                public void escape(char[] buf, int start, int len, boolean b, Writer out) throws IOException {
                    out.write(buf, start, len);
                }
            });
            QName name = new QName(NAMESPACE_URI, SendMessage.class.getSimpleName());
            JAXBElement<SendMessage> root = new JAXBElement<SendMessage>(name, SendMessage.class, from);
            StringWriter writer1 = new StringWriter();
            marshaller.marshal(root, writer1);
            DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            dbf.setNamespaceAware(true);
            Element node = dbf
                    .newDocumentBuilder()
                    .parse(new ByteArrayInputStream(writer1.toString().getBytes(StandardCharsets.ISO_8859_1)))
                    .getDocumentElement();
            Attr attr1 = document.createAttribute("xmlns:q1");
            attr1.setValue("http://test.user.kz/CustomerInfo");
            node.getElementsByTagName("data").item(0).getAttributes().setNamedItem(node.getOwnerDocument().importNode(attr1, true));
            return node;
        } catch (Exception e) {
            throw new Exception("Unable to transform POJO to XML SOAP message ", e);

        }