http请求是我们常用的一种web应用的应用层协议,但是由于它的不安全性,现在正在逐渐向https协议过渡。https协议是在http的基础上进行了隧道加密,加密方式有SSL和TLS两种。当server用https协议进行数据交换后,client请求server时会对server的证书进行校验,如果server端证书为四大证书机构颁发的证书或者其授权机构颁发的证书,则允许进一步请求,否则会警告证书不受信任。更多信息可参考
当用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 @Override19 public void checkClientTrusted(X509Certificate[] chain,20 String authType) throws CertificateException {21 }22 @Override23 public void checkServerTrusted(X509Certificate[] chain,24 String authType) throws CertificateException {25 }26 @Override27 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 }