簡體   English   中英

SOAP消息到webservice - HTTP響應代碼:403用於URL

[英]SOAP message to webservice - HTTP response code: 403 for URL

我嘗試將XML文件中的SOAP消息發送到Web服務,然后獲取二進制輸出並對其進行解碼。 端點使用HTTPS協議,因此我在代碼中使用了TrustManager來避免PKIX問題。 你可以在這里看到我的代碼:

import javax.net.ssl.*;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.security.cert.X509Certificate;

public class Main{
    public static void sendSoapRequest() throws Exception {
        String SOAPUrl = "URL HERE";
        String xmlFile2Send = ".\\src\\request.xml";
        String responseFileName = ".\\src\\response.xml";
        String inputLine;

        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
            public java.security.cert.X509Certificate[] getAcceptedIssuers() { return null; }
            public void checkClientTrusted(X509Certificate[] certs, String authType) { }
            public void checkServerTrusted(X509Certificate[] certs, String authType) { }

        } };

        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new java.security.SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());

        // Create all-trusting host name verifier
        HostnameVerifier allHostsValid = new HostnameVerifier() {
            public boolean verify(String hostname, SSLSession session) { return true; }
        };
        // Install the all-trusting host verifier
        HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);

        // Create the connection with http
        URL url = new URL(SOAPUrl);
        URLConnection connection = url.openConnection();
        HttpURLConnection httpConn = (HttpURLConnection) connection;
        FileInputStream fin = new FileInputStream(xmlFile2Send);
        ByteArrayOutputStream bout = new ByteArrayOutputStream();

        copy(fin, bout);
        fin.close();

        byte[] b = bout.toByteArray();
        StringBuffer buf=new StringBuffer();
        String s=new String(b);

        b=s.getBytes();

        // Set the appropriate HTTP parameters.
        httpConn.setRequestProperty("Content-Length", String.valueOf(b.length));
        httpConn.setRequestProperty("Content-Type", "text/xml; charset=utf-8");
        httpConn.setRequestProperty("SOAPAction", "");
        httpConn.setRequestMethod("POST");
        httpConn.setDoOutput(true);

        OutputStream out = httpConn.getOutputStream();
        out.write(b);
        out.close();

        // Read the response.
        httpConn.connect();
        System.out.println("http connection status :"+ httpConn.getResponseMessage());
        InputStreamReader isr = new InputStreamReader(httpConn.getInputStream());
        BufferedReader in = new BufferedReader(isr);

        while ((inputLine = in.readLine()) != null)
            System.out.println(inputLine);
        FileOutputStream fos=new FileOutputStream(responseFileName);
        copy(httpConn.getInputStream(),fos);
        in.close();
    }

    public static void copy(InputStream in, OutputStream out) throws IOException {

        synchronized (in) {
            synchronized (out) {
                byte[] buffer = new byte[256];
                while (true) {
                    int bytesRead = in.read(buffer);
                    if (bytesRead == -1)
                        break;
                    out.write(buffer, 0, bytesRead);
                }
            }
        }
    }

    public static void main(String args[]) throws Exception {
        sendSoapRequest();
    }
}

當我執行此操作時,我得到以下錯誤代碼。

線程“main”中的異常java.io.IOException:服務器返回HTTP響應代碼:403為URL

您的實現沒問題,問題實際上與您的Content-Type標頭有關。

text/xml; charset=utf-8 text/xml; charset=utf-8是SOAP 1.1的默認Content-Type ,可能不是您的版本。 SOAP 1.2需要一個類型為application/soap+xml; charset=utf-8的頭文件application/soap+xml; charset=utf-8 application/soap+xml; charset=utf-8 ,所以將你的代碼行更改為下面的代碼就可以了:

httpConn.setRequestProperty("Content-Type", "application/soap+xml; charset=utf-8");

在SoapUI中,可以檢查調用請求的標頭並轉到窗口底部的Headers選項卡:

在此輸入圖像描述

然后,您可以比較應用程序配置和SoapUI配置之間的差異。

403錯誤可能與發送到服務器的soap請求標頭有關。 所有主機有效將允許您的Java App信任URL的SSL證書。 檢查您的服務器是否期望帶有用戶名/密碼的soap標頭。 如果您有權訪問此服務器,則可以通過Web服務器登錄請求失敗的位置。 錯誤代碼指向缺少Soap Header,特別是使用用戶名和密碼的Soap Headers

不知道您的SOAP請求是否包含SAML等標頭中的任何類型的身份驗證信息。 一種選擇是,在上面的代碼中,您讀取文件並將數據發送到服務器,而不是將其發送到服務器,您將其轉儲到另一個文件。 轉儲byteoutputstream。 然后從該文件中復制文本並將其放入SOAP UI並嘗試運行該文件。 那樣有用嗎?

在類似的情況下,我們已經有一段時間了,只要嘗試TrustManager沒有按預期工作,我們就可以通過將證書從服務器安裝到JVM的密鑰庫(用於運行應用程序的JVM)來克服這個問題。 有關如何執行此操作的更多信息,您可以在幾個帖子中找到,例如如何將.cer證書導入Java密鑰庫?

我知道這是一種強制JVM接受SSL證書的嘗試,並且這種功能在應用程序上下文中會更好,但只要我們構建一個在特定應用程序服務器中運行的Web應用程序,實現的解決方案就是接受了一個。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM