HttpClient https发布请求失败

时间:2015-08-03 12:00:52

标签: java ssl httpclient

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

  • 我使用的是Apache的HttpClient 3.1
  • 我使用编码“application / x-www-form-urlencoded”
  • 我使用的网址以https
  • 开头

这是我尝试运行的代码:

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,但没有帮助。

2 个答案:

答案 0 :(得分:4)

如果您想一起忽略证书,请在此处查看答案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);`

答案 1 :(得分:0)

我重构了旧代码来处理 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;
}