HttpClient https Post 请求失败

HttpClient https Post request fails

我正在尝试以下一种方式发出 post 请求:

这是我尝试使用的代码 运行:

public static String httpsPost(String url, String body, String mediaType, String encoding) {
   disableCertificateValidation();
   HttpClient client = new HttpClient();
   StringRequestEntity requestEntity = new StringRequestEntity(body, mediaType, encoding);
   PostMethod method = new PostMethod(url);
   method.setRequestEntity(requestEntity);
   client.executeMethod(method);
}

public static void disableCertificateValidation() {
    // Create a trust manager that does not validate certificate chains
    TrustManager[] trustAllCerts = new TrustManager[] {
            new X509TrustManager() {
                public X509Certificate[] getAcceptedIssuers() {
                    return new X509Certificate[0];
                }
                public void checkClientTrusted(X509Certificate[] certs, String authType) {}
                public void checkServerTrusted(X509Certificate[] certs, String authType) {}
            }};

    // Ignore differences between given hostname and certificate hostname
    HostnameVerifier hv = new HostnameVerifier() {
        public boolean verify(String hostname, SSLSession session) { return true; }
    };

    // Install the all-trusting trust manager
    try {
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, new SecureRandom());
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
        HttpsURLConnection.setDefaultHostnameVerifier(hv);
    } catch (Exception e) {}
}

在执行 executeMethod 时我发现:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

我试过 disable certificate validation 但没用。

如果您想完全忽略证书,请查看此处的答案Ignore self-signed ssl cert using Jersey Client

尽管这会使您的应用容易受到中间人攻击。

您可以尝试将证书作为可信证书添加到您的 java 存储中,而不是这样做。这个网站可能会有帮助。 http://blog.icodejava.com/tag/get-public-key-of-ssl-certificate-in-java/

这是显示如何向您的商店添加证书的另一个答案。 Java SSL connect, add server cert to keystore programatically

关键是

KeyStore.Entry newEntry = new KeyStore.TrustedCertificateEntry(someCert);
ks.setEntry("someAlias", newEntry, null);`

我重构了旧代码以处理 https。现在它可以工作了,看起来像这样:

public static String httpsPost(String url, String body, String mediaType, String encoding) {
    SSLContext ctx;
    ctx = SSLContext.getInstance("TLS");
    ctx.init(new KeyManager[0], new TrustManager[]{new DefaultTrustManager()}, new SecureRandom());
    SSLContext.setDefault(ctx);
    HttpsURLConnection.setDefaultSSLSocketFactory(ctx.getSocketFactory());

    URL serverUrl = new URL(url);

    HttpsURLConnection con =  (HttpsURLConnection) serverUrl.openConnection();

    con.setRequestMethod("POST");
    con.setDoOutput(true);
    con.connect();

    OutputStreamWriter post = new OutputStreamWriter(con.getOutputStream());
    post.write(body);
    post.flush();

    BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
    String inputLine;
    String content = "";
    while ((inputLine = in.readLine()) != null) {
        content += inputLine;
    }
    post.close();
    in.close();

    return content;
}