http請求是我們常用的一種web應用的應用層協議,但是由於它的不安全性,現在正在逐漸向https協議過渡。https協議是在http的基礎上進行了隧道加密,加密方式有SSL和TLS兩種。當server用https協議進行數據交換后,client請求server時會對server的證書進行校驗,如果server端證書為四大證書機構頒發的證書或者其授權機構頒發的證書,則允許進一步請求,否則會警告證書不受信任。更多信息可參考https://www.cnblogs.com/handsomeBoys/p/6556336.html
當用httpclient進行請求https,會提示找不到有效的證書(unable to find valid certification path to requested target)
出現這種情況就是server端的證書不被信任,可以通過重寫一個類繼承DefaultHttpClient類,代碼如下:
1 import org.apache.http.conn.ClientConnectionManager; 2 import org.apache.http.conn.scheme.Scheme; 3 import org.apache.http.conn.scheme.SchemeRegistry; 4 import org.apache.http.conn.ssl.SSLSocketFactory; 5 import org.apache.http.impl.client.DefaultHttpClient; 6 7 import javax.net.ssl.SSLContext; 8 import javax.net.ssl.TrustManager; 9 import javax.net.ssl.X509TrustManager; 10 import java.security.cert.CertificateException; 11 import java.security.cert.X509Certificate; 12 13 public class SSLClient extends DefaultHttpClient { 14 public SSLClient() throws Exception{ 15 super(); 16 SSLContext ctx = SSLContext.getInstance("TLS"); 17 X509TrustManager tm = new X509TrustManager() { 18 @Override 19 public void checkClientTrusted(X509Certificate[] chain, 20 String authType) throws CertificateException { 21 } 22 @Override 23 public void checkServerTrusted(X509Certificate[] chain, 24 String authType) throws CertificateException { 25 } 26 @Override 27 public X509Certificate[] getAcceptedIssuers() { 28 return null; 29 } 30 }; 31 ctx.init(null, new TrustManager[]{tm}, null); 32 SSLSocketFactory ssf = new SSLSocketFactory(ctx,SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); 33 ClientConnectionManager ccm = this.getConnectionManager(); 34 SchemeRegistry sr = ccm.getSchemeRegistry(); 35 sr.register(new Scheme("https", 443, ssf)); 36 } 37 }
然后在進行https請求創建HttpClient對象時用這個類的構造器創建對象就可以實現https請求,例如:
1 import org.apache.http.Header; 2 import org.apache.http.HttpResponse; 3 import org.apache.http.client.methods.HttpGet; 4 import org.apache.http.impl.client.CloseableHttpClient; 5 6 public class RestApi { 7 8 public static String getCsrf(){ 9 String csrfToken = ""; 10 try { 11 CloseableHttpClient client = new SSLClient(); 12 String url = "https://10.67.19.186"; 13 HttpGet get = new HttpGet(url); 14 HttpResponse response = client.execute(get); 15 Header setCookidHeader = response.getFirstHeader("Set-Cookie"); 16 csrfToken = setCookidHeader.getValue().split(";")[0].split("=")[1]; 17 } catch (Exception e) { 18 e.printStackTrace(); 19 } 20 return csrfToken; 21 }