原创地址:http://www.cnblogs.com/shipengzhi/archive/2012/08/22/2650953.html
在开发java时调用别人接口(这个接口还是https开头的)过程中,需要认证你的证书,然而测试服务器常常没有一个(有效的)SSL证书。在你的客户端连接测试服务器时,如下的异常会被抛出:”javax.net.ssl.SSLPeerUnverifiedException: peer not authenticated”。
1.解决思路
我们将需要告诉client使用一个不同的TrustManager。TrustManager(http://download.oracle.com/docs/cd/E17476_01/javase/1.5.0/docs/api/javax/net/ssl/TrustManager.html)是一个检查给定的证书是否有效的类。
SSL使用的模式是X.509(http://en.wikipedia.org/wiki/X.509),对于该模式Java有一个特定的TrustManager,称为X509TrustManager。首先我们需要创建这样的TrustManager。
下面我们需要找到一个将TrustManager设置到我们的HttpClient的方法。TrustManager只是被SSL的Socket所使用。Socket通过SocketFactory创建。对于SSL Socket,有一个SSLSocketFactory(http://download.oracle.com/docs/cd/E17476_01/javase/1.5.0/docs/api/javax/net/ssl/SSLSocketFactory.html)。当创建新的SSLSocketFactory时,你需要传入SSLContext到它的构造方法中。在SSLContext中,我们将包含我们新创建的TrustManager。
首先我们需要得到一个SSLContext:
TLS是SSL的继承者,但是它们使用相同的SSLContext。
然后我们需要使用我们上面新创建的TrustManager来初始化该上下文:
最后我们创建SSLSocketFactory:
现在我们仍然需要将SSLSocketFactory注册到我们的HttpClient上。这是在SchemeRegistry中完成的:
我们注册了一个新的Scheme,使用协议https,我们新创建的SSLSocketFactory包含了我们的TrustManager,然后我们告诉HttpClienthttps的默认端口是443.
下面上代码:
1.使用的jar包:
<!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpclient --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.1.2</version> </dependency>
2.在已有的util类中写:
/** * 避免HttpClient的”SSLPeerUnverifiedException: peer not authenticated”异常 * 不用导入SSL证书 */ public static class WebClientPassWrapper { public static org.apache.http.client.HttpClient wrapClientPass(org.apache.http.client.HttpClient base) { try { SSLContext ctx = SSLContext.getInstance("TLS"); X509TrustManager tm = new X509TrustManager() { public X509Certificate[] getAcceptedIssuers() { return null; } public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {} public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {} }; ctx.init(null, new TrustManager[] { tm }, null); SSLSocketFactory ssf = new SSLSocketFactory(ctx, SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER); SchemeRegistry registry = new SchemeRegistry(); //https registry.register(new Scheme("https", 443, ssf)); //http registry.register(new Scheme("http",80,PlainSocketFactory.getSocketFactory())); ThreadSafeClientConnManager mgr = new ThreadSafeClientConnManager(registry); return new DefaultHttpClient(mgr, base.getParams()); } catch (Exception ex) { System.out.println("WebClientPassWrapper"+"创建忽略用户证书的HttpClient对象失败,尝试创建普通HttpClient对象"); ex.printStackTrace(); return new DefaultHttpClient(); } } }
3:使用方式:
/** * http请求工具类,get请求 * @param url * @param params * @param resonseCharSet * @return * @throws Exception */ public static String httpGet(String url, Map<String, Object> params,String ...resonseCharSet) throws Exception { DefaultHttpClient defaultHttpClient = null; BufferedReader bufferedReader = null; try { defaultHttpClient = new DefaultHttpClient(); if(params!=null){ StringBuilder stringBuilder=new StringBuilder(); Iterator<String> iterator=params.keySet().iterator(); String key; while (iterator.hasNext()){ key=iterator.next(); Object val=params.get(key); if(val instanceof List){ List v= (List) val; for (Object o:v){ stringBuilder.append(key).append("=").append(o.toString()).append("&"); } }else{ stringBuilder.append(key).append("=").append(val.toString()).append("&"); } } stringBuilder.deleteCharAt(stringBuilder.length()-1); url=url+"?"+stringBuilder.toString(); log.info("url:{}",url); } //调用忽略认证证书 defaultHttpClient= (DefaultHttpClient) WebClientPassWrapper.wrapClientPass(defaultHttpClient); HttpGet httpGet = new HttpGet(url); httpGet.setHeader("Content-Type", "application/json;charset=ut-8"); HttpResponse httpResponse = defaultHttpClient.execute(httpGet); if (httpResponse.getStatusLine().getStatusCode() != 200) { String errorLog="请求失败,errorCode:"+httpResponse.getStatusLine().getStatusCode(); log.info(errorLog); throw new Exception(url+errorLog); } //读取返回信息 String charSet="utf-8"; if(resonseCharSet!=null && resonseCharSet.length>0) charSet=resonseCharSet[0]; String output; bufferedReader=new BufferedReader(new InputStreamReader(httpResponse.getEntity().getContent(),charSet)); StringBuilder dataBuilder=new StringBuilder(); while ((output=bufferedReader.readLine())!=null){ dataBuilder.append(output); } return dataBuilder.toString(); } catch (ClientProtocolException e) { e.printStackTrace(); throw e; }catch (IOException e){ e.printStackTrace(); throw e; }finally { if(defaultHttpClient!=null) defaultHttpClient.getConnectionManager().shutdown(); if(bufferedReader!=null) bufferedReader.close(); } }
到这里就结束了,也是借鉴别人的思路,可以动手试试