我这里主要是服务端的问题,客户端直接拿的对方的wsdl生成的实体类,直接用实体类的方法请求的上位.
问题简要描述:在编写服务端的时候,因为对方的请求方法和返回方法不是对应的,而且在返回的消息的方法名有一个ns3的前缀,我都没有声明这个ns3,不造为什么会出现.然后需求是要改成ns1,然后在<SOAP-ENV:Envelope中添加ns1的命名空间
我这里说一下解决的思路:主要是通过拦截器,把返回的方法的消息拦截下来,在代码中手动修改方法名前缀和新增命名空间
package com.ittx.edi.erp.webservice.endpoint
import org.springframework.ws.context.MessageContext
import org.springframework.ws.server.endpoint.interceptor.EndpointInterceptorAdapter
import org.springframework.ws.soap.saaj.SaajSoapMessage
import javax.xml.soap.SOAPBody
import javax.xml.soap.SOAPBodyElement
import javax.xml.soap.SOAPEnvelope
import javax.xml.soap.SOAPException
import javax.xml.soap.SOAPMessage
import javax.xml.soap.SOAPPart
class CustomEndpointInterceptor extends EndpointInterceptorAdapter{
private static final String SOAP_ENV_NAMESPACE = "http://ws.webservices.services.adapter.datahub/";
private static final String PREFERRED_PREFIX = "ns1";
@Override
public boolean handleResponse(MessageContext messageContext, Object endpoint) throws Exception {
SaajSoapMessage soapResponse = (SaajSoapMessage) messageContext.getResponse();
alterSoapEnvelope(soapResponse);
return super.handleResponse(messageContext, endpoint);
}
private void alterSoapEnvelope(SaajSoapMessage soapResponse) {
try {
SOAPMessage soapMessage = soapResponse.getSaajMessage();
SOAPPart soapPart = soapMessage.getSOAPPart();
SOAPEnvelope envelope = soapPart.getEnvelope();
SOAPBody body = soapMessage.getSOAPBody();
envelope.addNamespaceDeclaration(PREFERRED_PREFIX, SOAP_ENV_NAMESPACE);
Iterator<SOAPBodyElement> it = body.getChildElements();
while (it.hasNext()) {
SOAPBodyElement node = it.next();
node.removeNamespaceDeclaration("")
node.removeNamespaceDeclaration(node.getPrefix())
node.setPrefix(PREFERRED_PREFIX);
Iterator<SOAPBodyElement> it2 = node.getChildElements();
while (it2.hasNext()) {
SOAPBodyElement node2 = it2.next();
node2.setPrefix("");
}
}
soapMessage.saveChanges();
} catch (SOAPException e) {
e.printStackTrace();
}
}
}
主要是参考了2位大佬的文章:
文章1:让我大概了解了spring-ws还有apache的cxf
https://blog.lqdev.cn/2018/11/09/springboot/chapter-thirty-three/
文章2:让我知道了可以通过这种拦截器来实现修改方法名前缀和增删命名空间
https://blog.csdn.net/baidu_29258933/article/details/82528410