如何修复没有 SOAPAction header!错误

How to fix no SOAPAction header! error

请在下面找到 html 我用来调用我的 soap 端点的 soap 客户端代码 我的 soap 网络服务作为轴项目部署在 tomcat 中。

请在下面找到客户端代码

<html>
<head>
    <title>SOAP JavaScript Client Test</title>
    <script type="text/javascript">
        function soap() {
            var xmlhttp = new XMLHttpRequest();
            xmlhttp.open('POST', 'http://localhost:9090/SMSSoapInterface/services/smsxmlpushservicewsSoap11', true);

            // build SOAP request
            var sr =
                '<?xml version="1.0" encoding="utf-8"?>' +
                '<soapenv:Envelope ' + 
                    'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ' +
                    'xmlns:urn="urn:mm7pushinterface' +
                    'xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">' +
                    '<soapenv:Body>' +
                            '<urn:SubmitReq>' +
                            '<urn:MM7Version>5.3.0</urn:MM7Version>' +
                            '<urn:SenderIdentification>' +
                            '<urn:VASPID>1234</urn:VASPID>'+
                            '<urn:VASID>12345</urn:VASID>'+
                            '<urn:CampaignName>SOAP Campaign</urn:CampaignName>'+
                            '<urn:CampaignDesc>test</urn:CampaignDesc>'+
                            '<urn:MsgCategory>1</urn:MsgCategory>'+
                            '<urn:SenderAddress>'+
                            '<urn:RFC2822Address >1244</urn:RFC2822Address>'+
                            '<urn:Number>919901251515</urn:Number>'+
                            '<urn:ShortCode >1234</urn:ShortCode>'+
                            '</urn:SenderAddress>'+
                            '</urn:SenderIdentification>'+
                            '<urn:Recipients>'+
                            '<urn:To>'+
                            '<urn:RFC2822Address >6789</urn:RFC2822Address>'+
                            '<urn:Number >919901251516</urn:Number>'+
                            '<urn:ShortCode >7896</urn:ShortCode>'+
                            '</urn:To>'+
                            '</urn:Recipients>'+
                            '</urn:Recipients>'+
                    '</soapenv:Body>' +
                '</soapenv:Envelope>';

            xmlhttp.onreadystatechange = function () {
                if (xmlhttp.readyState == 4) {
                    if (xmlhttp.status == 200) {
                        alert('done. use firebug/console to see network response');
                    }
                }
            }
            // Send the POST request
            xmlhttp.setRequestHeader('Content-Type', 'text/xml');
            xmlhttp.setRequestHeader('SOAPAction', "");
            xmlhttp.setRequestHeader('Access-Control-Allow-Headers', 'Authorization');
            xmlhttp.setRequestHeader('Access-Control-Allow-Methods', 'POST');
            xmlhttp.setRequestHeader('Access-Control-Allow-Origin', '*');
            xmlhttp.setRequestHeader('username', 'ecpDemoUser');
            xmlhttp.setRequestHeader('password', 'ecpDemo');
            xmlhttp.setRequestHeader('SOAPAction', "");
            xmlhttp.send(sr);
            // send request
            // ...
        }
    </script>
</head>
<body>
    <form name="Demo" action="" method="post">
        <div>
            <input type="button" value="Soap" onclick="soap();" />
        </div>
    </form>
</body>
</html> <!-- typo -->

下面是 error/stack 我在尝试访问 soap webservice 时得到的跟踪

no SOAPAction header!
       at org.apache.axis.transport.http.AxisServlet.getSoapAction(AxisServlet.java:1013)
       at org.apache.axis.transport.http.AxisServlet.doPost(AxisServlet.java:678)
       at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
       at org.apache.axis.transport.http.AxisServletBase.service(AxisServletBase.java:327)
       at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
       at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
       at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
       at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
       at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
       at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
       at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
       at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
       at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
       at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:956)
       at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
       at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:436)
       at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1078)
       at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:625)
       at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2517)
       at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2506)
       at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
       at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
       at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
       at java.lang.Thread.run(Thread.java:745)

下面是 wsdl 中的 soap 操作

<soap:operation soapAction=""/>

请告诉我如何解决这个问题?

参见SOAP 1.1 specification

The SOAPAction HTTP request header field can be used to indicate the intent of the SOAP HTTP request. The value is a URI identifying the intent. SOAP places no restrictions on the format or specificity of the URI or that it is resolvable. An HTTP client MUST use this header field when issuing a SOAP HTTP Request. The presence and content of the SOAPAction header field can be used by servers such as firewalls to appropriately filter SOAP request messages in HTTP. The header field value of empty string ("") means that the intent of the SOAP message is provided by the HTTP Request-URI. No value means that there is no indication of the intent of the message.

您正在使用 AxisServlet,这需要肥皂操作

Technically, if we don't find this header, we should probably fault. It's required in the SOAP HTTP binding.

代码:

private String More ...getSoapAction(HttpServletRequest req) throws AxisFault {

String soapAction = req.getHeader(HTTPConstants.HEADER_SOAP_ACTION);
if (soapAction == null) {
    String contentType = req.getHeader(HTTPConstants.HEADER_CONTENT_TYPE);
    if(contentType != null) {
        int index = contentType.indexOf("action");
        if(index != -1){
            soapAction = contentType.substring(index + 7);
        }
    }
}

..

   if (soapAction == null) {
        AxisFault af = new AxisFault("Client.NoSOAPAction",
                                     Messages.getMessage("noHeader00",
                "SOAPAction"),
                                     null, null);