Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 到webservice的SOAP消息-HTTP响应代码:403表示URL_Java_Xml_Web Services_Soap_Trusted Timestamp - Fatal编程技术网

Java 到webservice的SOAP消息-HTTP响应代码:403表示URL

Java 到webservice的SOAP消息-HTTP响应代码:403表示URL,java,xml,web-services,soap,trusted-timestamp,Java,Xml,Web Services,Soap,Trusted Timestamp,我尝试在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.secur

我尝试在
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 URL的响应代码:403


您的实现是正常的,问题实际上与
内容类型
标题有关

text/xml;charset=utf-8
是SOAP 1.1的默认内容类型,可能不是您的版本,因此,将您的代码行更改为下面的代码行将使其正常工作:

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

在SoapUI中,可以检查调用请求的标题并转到窗口底部的标题选项卡:


然后,您可以比较应用程序配置和SoapUI配置之间的差异。

403错误可能与发送到服务器的soap请求头有关。 所有有效主机将允许您的Java应用程序信任URL的SSL证书。
检查您的服务器是否需要具有用户名/密码的soap头。如果您有权访问此服务器,则可以通过web服务器日志检查请求失败的位置。错误代码指向缺少Soap头,特别是带有用户名和密码的Soap头,不知道您的Soap请求在诸如SAML的头中是否包含任何类型的身份验证信息。一个选项是,在上面的代码中,您读取文件并将数据发送到服务器,而不是将其发送到服务器,然后将其转储到另一个文件。转储字节输出流。然后从该文件复制文本并将其放入SOAP UI中,然后尝试运行该文件。这样行吗

在类似的情况下,我们已经经历了一段时间,只要尝试
TrustManager
没有按预期工作,我们就通过将证书从服务器安装到JVM的密钥库(JVM用于运行应用程序)来克服这个问题。关于如何做到这一点的更多信息,你可以在几个帖子中找到,比如


我知道这是一种强迫JVM接受SSL证书的尝试,这种功能最好是在应用程序上下文中使用,但只要我们构建一个在特定应用程序服务器中运行的web应用程序,实现的解决方案就是一种可接受的解决方案。

您应该提供凭据以获得访问权限。用于基本身份验证的base64中带有登录名/密码的身份验证标头,是最简单的变体,但它取决于服务器端。您应该提供服务器所需的内容。@user1516873:不需要在此服务器上进行身份验证。403-forbidden表示请求已到达服务器并且有效,但服务器拒绝访问请求的资源。总而言之,SSL连接正常,因此您调用了错误的端点,或者SOAP头中缺少凭据。@pedrofb:我明白了,但是当我在SOAP请求中使用SOAP UI中的XML文件内容时,我会收到来自同一端点的响应。如果内容相同,然后检查并比较实际发送SOAPUI的标头和您的连接。服务器可能检测到一些错误并将其视为403。我在SoapUI中找不到任何标题,并且我也得到了与此内容类型完全相同的错误。标题位于响应端,而不是请求中。发出请求并在那里进行检查。在响应端是
应用程序/时间戳回复
。您是否可以共享端点?或者至少是GitHub的服务项目?很难猜测您的实现的特殊性。很抱歉,但它只能从本地网络访问。不需要用户名/密码,当前SoapUI请求中没有设置它。为什么创建另一个具有相同内容的文件更好?特别是在您的SOAP请求包含SAML或其他二进制数据的情况下。这是为了查看它是否在文件IO期间损坏。您的代码包含以下小部分:
byte[]b=bout.toByteArray();StringBuffer buf=新的StringBuffer();字符串s=新字符串(b);b=s.getBytes()将数据转换为字符串并返回字节的位置。有什么特别的需要吗?正如@pedrofb所建议的,我之前从代码中删除了这些行。哦,好的。您是否能够捕获从soapui发送的头文件与从代码发送的头文件。是的,我向Requestbin发送了请求,但正文是空的。我的Java代码有问题吗?