我想在Java中執行POST請求。我已經成功地使用HTTP,但HTTPS對我來說很棘手。 我使用這個代碼:沒有主題替代DNS名稱匹配
// Create a trust manager that does not validate certificate chains
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};
// Install the all-trusting trust manager
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new java.security.SecureRandom());
HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
} catch (Exception e) {
}
String httpsURL = "https://requestb.in/191g0961";
String query = "email="+URLEncoder.encode("[email protected]","UTF-8");
query += "&";
query += "password="+URLEncoder.encode("abcd","UTF-8") ;
URL myurl = new URL(httpsURL);
HttpsURLConnection con = (HttpsURLConnection)myurl.openConnection();
con.setRequestMethod("POST");
con.setRequestProperty("Content-length", String.valueOf(query.length()));
con.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
con.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0;Windows98;DigExt)");
con.setDoOutput(true);
con.setDoInput(true);
DataOutputStream output = new DataOutputStream(con.getOutputStream());
output.writeBytes(query);
output.close();
DataInputStream input = new DataInputStream(con.getInputStream());
for(int c = input.read(); c != -1; c = input.read())
System.out.print((char)c);
input.close();
System.out.println("Resp Code:"+con .getResponseCode());
System.out.println("Resp Message:"+ con .getResponseMessage());
我在希望加入的TrustManager它解決了我的問題,因爲當我載入我的測試網頁https://requestb.in/191g0961在Firefox中,它說,網站使用不可信證書等。
我的代碼工作與在Firefox的加載沒有任何警告,這樣頁頁次:https://extranet.nix.cz/login(你可以試試)
但隨着https://requestb.in/191g0961它給我以下情況除外:
Exception in thread "main" javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: No subject alternative DNS name matching requestb.in found.
at sun.security.ssl.Alerts.getSSLException(Unknown Source)
at sun.security.ssl.SSLSocketImpl.fatal(Unknown Source)
at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
at sun.security.ssl.Handshaker.fatalSE(Unknown Source)
at sun.security.ssl.ClientHandshaker.serverCertificate(Unknown Source)
at sun.security.ssl.ClientHandshaker.processMessage(Unknown Source)
at sun.security.ssl.Handshaker.processLoop(Unknown Source)
at sun.security.ssl.Handshaker.process_record(Unknown Source)
at sun.security.ssl.SSLSocketImpl.readRecord(Unknown Source)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.security.ssl.SSLSocketImpl.startHandshake(Unknown Source)
at sun.net.www.protocol.https.HttpsClient.afterConnect(Unknown Source)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(Unknown Source)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(Unknown Source)
at https.Sender.main(Sender.java:80)
Caused by: java.security.cert.CertificateException: No subject alternative DNS name matching requestb.in found.
at sun.security.util.HostnameChecker.matchDNS(Unknown Source)
at sun.security.util.HostnameChecker.match(Unknown Source)
at sun.security.ssl.X509TrustManagerImpl.checkIdentity(Unknown Source)
at sun.security.ssl.AbstractTrustManagerWrapper.checkAdditionalTrust(Unknown Source)
at sun.security.ssl.AbstractTrustManagerWrapper.checkServerTrusted(Unknown Source)
... 13 more
你有什麼想法如何解決這個問題? 在此先感謝!
解決方案:
我創造了這個簡單的類:
public class Verifier implements HostnameVerifier {
public boolean verify(String arg0, SSLSession arg1) {
return true; // mark everything as verified
}
}
,然後我說:
con.setHostnameVerifier(new Verifier());
你檢查從'TrustManager'你的方法被調用?尤其需要'checkServerTrusted()'方法。 –
我剛剛嘗試過,並且方法'checkServerTrusted()'真的被調用。 – Firzen