java - 使用 EndpointInterceptor 从 SOAP 请求中删除空 ns 属性

标签 java spring-boot soap

有一个遗留系统发送带有空命名空间属性的 SOAP 请求,导致字段值为空,当从 SOAP UI 测试时删除命名空间属性时,它可以正常工作。

这就是有问题的 SOAP 请求的样子

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
        <ADD xmlns="http://www.cc.com/ws">
            <ID xmlns="">dummy</ID>
            <PWD xmlns="">password</PWD>
        </ADD>
    </soapenv:Body>
</soapenv:Envelope>

我尝试使用WsConfigurerAdapteraddInterceptors方法添加拦截器,其代码粘贴在下面,但它不起作用

@Override
public boolean handleRequest(MessageContext messageContext, Object endpoint) throws Exception {
    
    SOAPMessage soapMessage = ((SaajSoapMessage) messageContext.getRequest()).getSaajMessage();
    SOAPBody body = soapMessage.getSOAPBody();
    
    Iterator<SOAPBodyElement> it = body.getChildElements();
    while (it.hasNext()) {
        Object node = it.next();
        if (!isTextNode(node)) {
            com.sun.xml.internal.messaging.saaj.soap.ver1_1.BodyElement1_1Impl e = 
                    (com.sun.xml.internal.messaging.saaj.soap.ver1_1.BodyElement1_1Impl) node;
            
            Iterator<SOAPBodyElement> subItr = e.getChildElements();
            while(subItr.hasNext()) {
                Object subNode = subItr.next();
                if(subNode instanceof com.sun.xml.internal.messaging.saaj.soap.impl.ElementImpl) {
                    SOAPElement el = (SOAPElement) subNode;
                
                    el.removeAttribute("xmlns");
                }
            }
            
        }
    }
    
    soapMessage.writeTo(System.out);
    return true;
}

最佳答案

请注意,XML 中的 namespace 声明不是属性。不要对相似的语法感到困惑!

所以我不希望 e.removeAttribute 执行任何操作,因为没有名为 xmlns 的属性。

您实际上需要做的是更改元素的名称,例如使用其 setElementQName()方法。

@Override
public boolean handleRequest(MessageContext messageContext, Object endpoint) throws Exception {
    
    SOAPMessage soapMessage = ((SaajSoapMessage) messageContext.getRequest()).getSaajMessage();
    SOAPBody body = soapMessage.getSOAPBody();
    
    Iterator<SOAPBodyElement> it = body.getChildElements();
    while (it.hasNext()) {
        Object node = it.next();
        if (!isTextNode(node)) {
            com.sun.xml.internal.messaging.saaj.soap.ver1_1.BodyElement1_1Impl e = 
                    (com.sun.xml.internal.messaging.saaj.soap.ver1_1.BodyElement1_1Impl) node;
            
            Iterator<SOAPBodyElement> subItr = e.getChildElements();
            while(subItr.hasNext()) {
                Object subNode = subItr.next();
                if(subNode instanceof com.sun.xml.internal.messaging.saaj.soap.impl.ElementImpl) {
                    SOAPElement el = (SOAPElement) subNode;                
                    el.setElementQName(
                        new QName(
                            e.getElementName().getURI(), 
                            el.getElementName().getLocalName()
                        )
                    );
                }
            }
            
        }
    }
    
    soapMessage.writeTo(System.out);
    return true;
}

关于java - 使用 EndpointInterceptor 从 SOAP 请求中删除空 ns 属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73713460/

相关文章:

java - 使用 DataOutputStream 写入偏移量

java - 如何在一次测试中启动2个Spring Boot应用程序?

php - 如何构造复杂的嵌套 SOAP 参数

Apache Axis 2 中没有时区的 Java 日历

wcf - 使用WebFaultException的WCF错误管理-错误的HttpStatusCode

java - 如果一个或多个属性具有特定值,则删除 Weka 实例

java - Spring /hibernate : New entity-classes in dependend project

java - 具有 java.lang.illegalstateexception state== header 的 WebSphere 服务器和 Jetty 客户端

tomcat - Spring Boot(使用tomcat)url重定向没有模板引擎

spring-boot - 登录后,我被重定向到/robots.txt