即使使用了正确的命名空间,也会收到版本不匹配的 SOAP 错误

问题描述 投票:0回答:2

我正在使用 apache commons httpclient 4.2 版来执行基于 SOAP 1.2 的简单 Web 服务。我能够通过 SOAP UI 正确启动 Web 服务,但我无法使用 Java 执行相同的操作。

以下是我用来调用服务的方法(超时代码基于 kuester2000this answer)。

private static byte[] callSOAPServer(String body, String SOAP_ACTION,
        String SERVER_URL) {

    byte[] result = null;

    HttpParams httpParameters = new BasicHttpParams();
    // Set the timeout in milliseconds until a connection is established.
    int timeoutConnection = 15000;
    HttpConnectionParams.setConnectionTimeout(httpParameters,
            timeoutConnection);
    // Set the default socket timeout (SO_TIMEOUT)
    // in milliseconds which is the timeout for waiting for data.
    int timeoutSocket = 35000;
    HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);

    DefaultHttpClient httpclient = new DefaultHttpClient(httpParameters);

    /*
     * httpclient.getCredentialsProvider().setCredentials( new
     * AuthScope("os.icloud.com", 80, null, "Digest"), new
     * UsernamePasswordCredentials(username, password));
     */
    HttpPost httppost = new HttpPost(SERVER_URL);
    httppost.setHeader("soapaction", SOAP_ACTION);
    httppost.setHeader("Content-Type", "text/xml; charset=utf-8");

    System.out.println("executing request" + httppost.getRequestLine());
    // now create a soap request message as follows:
    final StringBuffer soap = new StringBuffer();
    soap.append("\n");
    soap.append("");
    // this is a sample data..you have create your own required data BEGIN
    soap.append(" \n");
    soap.append(" \n");
    soap.append("" + body);
    soap.append(" \n");
    soap.append(" \n");

    /* soap.append(body); */
    // END of MEssage Body
    soap.append("");
    System.out.println("SOAP Request : " + soap.toString());
    // END of full SOAP request message
    try {
        HttpEntity entity = new StringEntity(soap.toString(), HTTP.UTF_8);
        httppost.setEntity(entity);
        HttpResponse response = httpclient.execute(httppost);// calling
                                                                // server
        HttpEntity r_entity = response.getEntity(); // get response
        System.out.println("Reponse Header:Begin..."); // response headers
        System.out.println("Reponse Header StatusLine:"
                + response.getStatusLine());
        Header[] headers = response.getAllHeaders();
        for (Header h : headers) {
            System.out.println("Reponse Header " + h.getName() + ": "
                    + h.getValue());
        }
        System.out.println("Reponse Header END...");
        if (r_entity != null) {
            result = new byte[(int) r_entity.getContentLength()];
            if (r_entity.isStreaming()) {
                DataInputStream is = new DataInputStream(
                        r_entity.getContent());
                is.readFully(result);
            }
        }
    } catch (Exception E) {
        System.out.println("Exception While Connecting " + E.getMessage());
        E.printStackTrace();
    }

    httpclient.getConnectionManager().shutdown(); // shut down the
                                                    // connection
    return result;
}

以下是我的 SOAP Request 以及终点。

String soapRequest = "<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\" xmlns:typ=\"http://skash.service.sahaj.com/types/\">"
            + "<soap:Header/>"
            + "<soap:Body>"
            + "<typ:remoteSKASHDeductionElement>"
            + "<typ:vleId>?</typ:vleId>"
            + "<typ:paidAmt>?</typ:paidAmt>"
            + "<typ:refTxnId>?</typ:refTxnId>"
            + "</typ:remoteSKASHDeductionElement>"
            + "</soap:Body>"
            + "</soap:Envelope>";
    String soapEndPoint = "http://xxx.xxx.xxx.xxx:xxxx/skashws/remoteSKASHDeductionSoap12HttpPort";
    String soapAction = "http://xxx.xxx.xxx.xxx:xxxx//remoteSKASHDeduction";
    // executeSOAPRequest(soapRequest, soapEndPoint, soapAction);
    byte[] resp = callSOAPServer(soapRequest, soapAction, soapEndPoint);
    System.out.println(IOUtils.toString(resp));

我可以看到设置为 Envelope 标记的名称空间适用于 SOAP 1.2 并且设置得很好。我不确定我哪里出错了。我收到以下版本不匹配错误。

<env:Envelope xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
<env:Header>
    <env:Upgrade>
        <env:SupportedEnvelope xmlns:soap12="http://www.w3.org/2003/05/soap-envelope" qname="soap12:Envelope"/>
    </env:Upgrade>
</env:Header>
<env:Body>
    <env:Fault xmlns:env="http://schemas.xmlsoap.org/soap/envelope/">
        <faultcode>env:VersionMismatch</faultcode>
        <faultstring>Version Mismatch</faultstring>
        <faultactor>http://schemas.xmlsoap.org/soap/actor/next</faultactor>
    </env:Fault>
</env:Body>

web-services soap apache-commons-httpclient
2个回答
1
投票

你可以使用这个代码块

public class GenericSoapMessageFactory extends SaajSoapMessageFactory implements InitializingBean {
    @Override
    public SaajSoapMessage createWebServiceMessage(InputStream inputStream) throws IOException {
        setMessageFactoryForRequestContext(soap11);
        if (inputStream instanceof TransportInputStream) {
            TransportInputStream transportInputStream = (TransportInputStream) inputStream;
            if (soapProtocolChooser.useSoap12(transportInputStream)) {
                setMessageFactoryForRequestContext(soap12);
            }
        }
        SaajSoapMessageFactory mf = getMessageFactoryForRequestContext();
        return mf.createWebServiceMessage(inputStream);
    }
}

和 web.xml 参数

<servlet>
    <servlet-name>spring-ws2</servlet-name>
    <servlet-class>org.springframework.ws.transport.http.MessageDispatcherServlet</servlet-class>
    <init-param>
        <param-name>messageFactoryBeanName</param-name>
        <param-value>genericSoapMessageFactory</param-value>
    </init-param>
</servlet>

0
投票

我看到这个错误一次,我更改了以下行:

httppost.setHeader("Content-Type", "text/xml; charset=utf-8");

httppost.setHeader("Content-Type", "application/soap+xml;charset=UTF-8;");

它解决了这个问题。

© www.soinside.com 2019 - 2024. All rights reserved.