我们正在使用Spring-ws 2.4.2.RELEASE版本从WSDL调用外部WebService。
我们调用的方法是:
ValidateObjectResponse response = (ValidateObjectResponse) webServiceTemplate.marshalSendAndReceive(request);
生成的SOAP请求包含一个空的名称空间前缀:
<SOAP-ENV:Envelope xmlns:SOAPENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<ns2:validateObject xmlns:ns2="http://ws.validator.sch.gazelle.ihe.net/" xmlns=""><base64ObjectToValidate>Cgo8P3ht...
</SOAP-ENV:Body>
</SOAP-ENV>
在幕后,使用apache公理(版本1.2.13),在发行说明中,我读到以下内容(https://ws.apache.org/axiom/release-notes/1.2.13.html):
“在Axiom 1.2.12中,OMElement中的clarifyNamespace方法未强制执行此约束,并且在序列化过程中静默删除了违反此要求的名称空间声明。此行为是有问题的,因为它可能会导致一些细微的问题,例如未绑定名称空间前缀。在Axiom 1.2.13中,已对这些方法进行了更改,以便在尝试将空名称空间名称绑定到前缀时将引发异常。“
调用外部Web服务时,会出现以下异常:
java.lang.IllegalArgumentException: Cannot bind a prefix to the empty namespace name
at org.apache.axiom.om.impl.dom.ElementImpl.declareNamespace(ElementImpl.java:754)
at org.apache.axiom.om.impl.dom.ElementImpl.declareNamespace(ElementImpl.java:778)
at org.apache.axiom.om.impl.dom.ElementImpl.setAttributeNS(ElementImpl.java:559)
at com.sun.xml.bind.marshaller.SAX2DOMEx.startElement(SAX2DOMEx.java:163)
at com.sun.xml.bind.v2.runtime.output.SAXOutput.endStartTag(SAXOutput.java:124)
at com.sun.xml.bind.v2.runtime.XMLSerializer.endAttributes(XMLSerializer.java:302)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsSoleContent(XMLSerializer.java:588)
at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(ClassBeanInfoImpl.java:312)
at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:490)
at com.sun.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:328)
at com.sun.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:257)
at org.springframework.oxm.jaxb.Jaxb2Marshaller.marshal(Jaxb2Marshaller.java:680)
at org.springframework.ws.support.MarshallingUtils.marshal(MarshallingUtils.java:81)
at org.springframework.ws.client.core.WebServiceTemplate$2.doWithMessage(WebServiceTemplate.java:399)
at org.springframework.ws.client.core.WebServiceTemplate.doSendAndReceive(WebServiceTemplate.java:590)
at org.springframework.ws.client.core.WebServiceTemplate.sendAndReceive(WebServiceTemplate.java:555)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:390)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:383)
at org.springframework.ws.client.core.WebServiceTemplate.marshalSendAndReceive(WebServiceTemplate.java:373)
我的第一个想法是将axiom的版本降低到2.1.12,但这与其他库产生了冲突。
是否有一种方法可以避免使用spring-ws创建空的名称空间前缀?
我们有一个WSDL,在那里,一切看起来对我来说都不错,但我们无法对其进行修改:
<?xml version='1.0' encoding='UTF-8'?>
<wsdl:definitions xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:tns="http://ws.validator.sch.gazelle.ihe.net/"
xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
name="GazelleObjectValidatorService" targetNamespace="http://ws.validator.sch.gazelle.ihe.net/">
<wsdl:types>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:tns="http://ws.validator.sch.gazelle.ihe.net/"
attributeFormDefault="unqualified" elementFormDefault="unqualified"
targetNamespace="http://ws.validator.sch.gazelle.ihe.net/">
<xs:element name="about" type="tns:about"/>
<xs:element name="aboutResponse" type="tns:aboutResponse"/>
<xs:element name="getAllAvailableObjectTypes" type="tns:getAllAvailableObjectTypes"/>
<xs:element name="getAllAvailableObjectTypesResponse" type="tns:getAllAvailableObjectTypesResponse"/>
<xs:element name="getAllSchematrons" type="tns:getAllSchematrons"/>
<xs:element name="getAllSchematronsResponse" type="tns:getAllSchematronsResponse"/>
<xs:element name="getSchematronByName" type="tns:getSchematronByName"/>
<xs:element name="getSchematronByNameResponse" type="tns:getSchematronByNameResponse"/>
<xs:element name="getSchematronsForAGivenType" type="tns:getSchematronsForAGivenType"/>
<xs:element name="getSchematronsForAGivenTypeResponse" type="tns:getSchematronsForAGivenTypeResponse"/>
<xs:element name="validateObject" type="tns:validateObject"/>
<xs:element name="validateObjectResponse" type="tns:validateObjectResponse"/>
这是我们创建WebServiceTemplate的代码:
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setPackagesToScan("com.test");
WebServiceTemplate webServiceTemplate = new WebServiceTemplate(marshaller);
webServiceTemplate.setDefaultUri(defaultUri);
webServiceTemplate.setMessageSender(new HttpComponentsMessageSender(httpClientBuilder.build()));
ValidateObject request = new ValidateObject();
request.setBase64ObjectToValidate(base64Object);
request.setXmlReferencedStandard(xmlReferencedStandard);
request.setXmlMetadata(xmlMetadata);
ValidateObjectResponse response = (ValidateObjectResponse)
webServiceTemplate.marshalSendAndReceive(request);
return response.getValidationResult();
问题是我如何避免生成空的名称空间名称:
<ns2:validateObject xmlns:ns2="http://ws.validator.sch.gazelle.ihe.net/" xmlns="">
让公理不再抱怨?
答案 0 :(得分:0)
问题最终导致spring-ws使用的公理jar与Axis使用的公理jar之间发生了jar冲突。
通过强制为WebServiceTemplate使用特定的SaajSoapMessageFactory:
SaajSoapMessageFactory saajSoapMessageFactory = new SaajSoapMessageFactory(new SOAPMessageFactory1_1Impl());
saajSoapMessageFactory.setSoapVersion(SoapVersion.SOAP_11);
saajSoapMessageFactory.afterPropertiesSet();
webServiceTemplate.setMessageFactory(saajSoapMessageFactory);
我们设法解决了问题。
答案 1 :(得分:0)
为生成空名称空间,请尝试为子元素和父元素设置相同的名称空间;子元素应该在没有名称空间的情况下生成。