1+ package com .tgb .ccl .http .simpledemo ;
2+
3+ import java .io .File ;
4+ import java .io .FileInputStream ;
5+ import java .io .IOException ;
6+ import java .io .InputStream ;
7+ import java .io .InputStreamReader ;
8+ import java .io .Reader ;
9+ import java .security .KeyManagementException ;
10+ import java .security .KeyStore ;
11+ import java .security .KeyStoreException ;
12+ import java .security .NoSuchAlgorithmException ;
13+ import java .security .cert .CertificateException ;
14+ import java .util .ArrayList ;
15+ import java .util .HashMap ;
16+ import java .util .List ;
17+ import java .util .Map ;
18+ import java .util .Map .Entry ;
19+
20+ import javax .net .ssl .SSLContext ;
21+ import javax .net .ssl .TrustManager ;
22+ import javax .net .ssl .X509TrustManager ;
23+
24+ import org .apache .http .HttpEntity ;
25+ import org .apache .http .HttpHost ;
26+ import org .apache .http .HttpResponse ;
27+ import org .apache .http .NameValuePair ;
28+ import org .apache .http .ParseException ;
29+ import org .apache .http .client .ClientProtocolException ;
30+ import org .apache .http .client .entity .UrlEncodedFormEntity ;
31+ import org .apache .http .client .methods .HttpPost ;
32+ import org .apache .http .concurrent .FutureCallback ;
33+ import org .apache .http .config .Registry ;
34+ import org .apache .http .config .RegistryBuilder ;
35+ import org .apache .http .conn .ssl .TrustSelfSignedStrategy ;
36+ import org .apache .http .impl .conn .DefaultProxyRoutePlanner ;
37+ import org .apache .http .impl .nio .client .CloseableHttpAsyncClient ;
38+ import org .apache .http .impl .nio .client .HttpAsyncClientBuilder ;
39+ import org .apache .http .impl .nio .client .HttpAsyncClients ;
40+ import org .apache .http .impl .nio .conn .PoolingNHttpClientConnectionManager ;
41+ import org .apache .http .impl .nio .reactor .DefaultConnectingIOReactor ;
42+ import org .apache .http .impl .nio .reactor .IOReactorConfig ;
43+ import org .apache .http .message .BasicNameValuePair ;
44+ import org .apache .http .nio .conn .NoopIOSessionStrategy ;
45+ import org .apache .http .nio .conn .SchemeIOSessionStrategy ;
46+ import org .apache .http .nio .conn .ssl .SSLIOSessionStrategy ;
47+ import org .apache .http .nio .reactor .ConnectingIOReactor ;
48+ import org .apache .http .ssl .SSLContexts ;
49+ import org .apache .http .util .EntityUtils ;
50+
51+ /**
52+ * HttpAsyncClient模拟post请求简单示例
53+ *
54+ * @author arron
55+ * @date 2015年11月1日 下午2:23:18
56+ * @version 1.0
57+ */
58+ public class SimpleHttpAsyncClientDemo {
59+
60+ /**
61+ * 设置信任自定义的证书
62+ *
63+ * @param keyStorePath 密钥库路径
64+ * @param keyStorepass 密钥库密码
65+ * @return
66+ */
67+ public static SSLContext custom (String keyStorePath , String keyStorepass ) {
68+ SSLContext sc = null ;
69+ FileInputStream instream = null ;
70+ KeyStore trustStore = null ;
71+ try {
72+ trustStore = KeyStore .getInstance (KeyStore .getDefaultType ());
73+ instream = new FileInputStream (new File (keyStorePath ));
74+ trustStore .load (instream , keyStorepass .toCharArray ());
75+ // 相信自己的CA和所有自签名的证书
76+ sc = SSLContexts .custom ().loadTrustMaterial (trustStore , new TrustSelfSignedStrategy ()).build ();
77+ } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException | KeyManagementException e ) {
78+ e .printStackTrace ();
79+ } finally {
80+ try {
81+ instream .close ();
82+ } catch (IOException e ) {
83+ }
84+ }
85+ return sc ;
86+ }
87+
88+ /**
89+ * 绕过验证
90+ *
91+ * @return
92+ * @throws NoSuchAlgorithmException
93+ * @throws KeyManagementException
94+ */
95+ public static SSLContext createIgnoreVerifySSL () throws NoSuchAlgorithmException , KeyManagementException {
96+ SSLContext sc = SSLContext .getInstance ("SSLv3" );
97+
98+ // 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法
99+ X509TrustManager trustManager = new X509TrustManager () {
100+ @ Override
101+ public void checkClientTrusted (
102+ java .security .cert .X509Certificate [] paramArrayOfX509Certificate ,
103+ String paramString ) throws CertificateException {
104+ }
105+
106+ @ Override
107+ public void checkServerTrusted (
108+ java .security .cert .X509Certificate [] paramArrayOfX509Certificate ,
109+ String paramString ) throws CertificateException {
110+ }
111+
112+ @ Override
113+ public java .security .cert .X509Certificate [] getAcceptedIssuers () {
114+ return null ;
115+ }
116+ };
117+ sc .init (null , new TrustManager [] { trustManager }, null );
118+ return sc ;
119+ }
120+
121+ /**
122+ * 设置代理
123+ * @param builder
124+ * @param hostOrIP
125+ * @param port
126+ */
127+ public static HttpAsyncClientBuilder proxy (String hostOrIP , int port ){
128+ // 依次是代理地址,代理端口号,协议类型
129+ HttpHost proxy = new HttpHost (hostOrIP , port , "http" );
130+ DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner (proxy );
131+ return HttpAsyncClients .custom ().setRoutePlanner (routePlanner );
132+ }
133+
134+ /**
135+ * 模拟请求
136+ *
137+ * @param url 资源地址
138+ * @param map 参数列表
139+ * @param encoding 编码
140+ * @param handler 结果处理类
141+ * @return
142+ * @throws NoSuchAlgorithmException
143+ * @throws KeyManagementException
144+ * @throws IOException
145+ * @throws ClientProtocolException
146+ */
147+ public static void send (String url , Map <String ,String > map ,final String encoding , final AsyncHandler handler ) throws KeyManagementException , NoSuchAlgorithmException , ClientProtocolException , IOException {
148+
149+ //绕过证书验证,处理https请求
150+ SSLContext sslcontext = createIgnoreVerifySSL ();
151+
152+ // 设置协议http和https对应的处理socket链接工厂的对象
153+ Registry <SchemeIOSessionStrategy > sessionStrategyRegistry = RegistryBuilder .<SchemeIOSessionStrategy >create ()
154+ .register ("http" , NoopIOSessionStrategy .INSTANCE )
155+ .register ("https" , new SSLIOSessionStrategy (sslcontext ))
156+ .build ();
157+ //配置io线程
158+ IOReactorConfig ioReactorConfig = IOReactorConfig .custom ().setIoThreadCount (Runtime .getRuntime ().availableProcessors ()).build ();
159+ //设置连接池大小
160+ ConnectingIOReactor ioReactor ;
161+ ioReactor = new DefaultConnectingIOReactor (ioReactorConfig );
162+ PoolingNHttpClientConnectionManager connManager = new PoolingNHttpClientConnectionManager (ioReactor , null , sessionStrategyRegistry , null );
163+
164+ //创建自定义的httpclient对象
165+ final CloseableHttpAsyncClient client = proxy ("127.0.0.1" , 8087 ).setConnectionManager (connManager ).build ();
166+ // CloseableHttpAsyncClient client = HttpAsyncClients.createDefault();
167+
168+ //创建post方式请求对象
169+ HttpPost httpPost = new HttpPost (url );
170+
171+ //装填参数
172+ List <NameValuePair > nvps = new ArrayList <NameValuePair >();
173+ if (map !=null ){
174+ for (Entry <String , String > entry : map .entrySet ()) {
175+ nvps .add (new BasicNameValuePair (entry .getKey (), entry .getValue ()));
176+ }
177+ }
178+ //设置参数到请求对象中
179+ httpPost .setEntity (new UrlEncodedFormEntity (nvps , encoding ));
180+
181+ System .out .println ("请求地址:" +url );
182+ System .out .println ("请求参数:" +nvps .toString ());
183+
184+ //设置header信息
185+ //指定报文头【Content-type】、【User-Agent】
186+ httpPost .setHeader ("Content-type" , "application/x-www-form-urlencoded" );
187+ httpPost .setHeader ("User-Agent" , "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)" );
188+
189+ // Start the client
190+ client .start ();
191+ //执行请求操作,并拿到结果(异步)
192+ client .execute (httpPost , new FutureCallback <HttpResponse >() {
193+
194+ @ Override
195+ public void failed (Exception ex ) {
196+ handler .failed (ex );
197+ close (client );
198+ }
199+
200+ @ Override
201+ public void completed (HttpResponse resp ) {
202+ String body ="" ;
203+ //这里使用EntityUtils.toString()方式时会大概率报错,原因:未接受完毕,链接已关
204+ try {
205+ HttpEntity entity = resp .getEntity ();
206+ if (entity != null ) {
207+ final InputStream instream = entity .getContent ();
208+ try {
209+ final StringBuilder sb = new StringBuilder ();
210+ final char [] tmp = new char [1024 ];
211+ final Reader reader = new InputStreamReader (instream ,encoding );
212+ int l ;
213+ while ((l = reader .read (tmp )) != -1 ) {
214+ sb .append (tmp , 0 , l );
215+ }
216+ body = sb .toString ();
217+ } finally {
218+ instream .close ();
219+ EntityUtils .consume (entity );
220+ }
221+ }
222+ } catch (ParseException | IOException e ) {
223+ e .printStackTrace ();
224+ }
225+ handler .completed (body );
226+ close (client );
227+ }
228+
229+ @ Override
230+ public void cancelled () {
231+ handler .cancelled ();
232+ close (client );
233+ }
234+ });
235+ }
236+
237+ /**
238+ * 关闭client对象
239+ *
240+ * @param client
241+ */
242+ private static void close (CloseableHttpAsyncClient client ) {
243+ try {
244+ client .close ();
245+ } catch (IOException e ) {
246+ e .printStackTrace ();
247+ }
248+ }
249+
250+ static class AsyncHandler implements IHandler {
251+
252+ @ Override
253+ public Object failed (Exception e ) {
254+ System .err .println (Thread .currentThread ().getName ()+"--失败了--" +e .getClass ().getName ()+"--" +e .getMessage ());
255+ return null ;
256+ }
257+ @ Override
258+ public Object completed (String respBody ) {
259+ System .out .println (Thread .currentThread ().getName ()+"--获取内容:" +respBody );
260+ return null ;
261+ }
262+ @ Override
263+ public Object cancelled () {
264+ System .out .println (Thread .currentThread ().getName ()+"--取消了" );
265+ return null ;
266+ }
267+ }
268+
269+ /**
270+ * 回调处理接口
271+ *
272+ * @author arron
273+ * @date 2015年11月10日 上午10:05:40
274+ * @version 1.0
275+ */
276+ public interface IHandler {
277+
278+ /**
279+ * 处理异常时,执行该方法
280+ * @return
281+ */
282+ Object failed (Exception e );
283+
284+ /**
285+ * 处理正常时,执行该方法
286+ * @return
287+ */
288+ Object completed (String respBody );
289+
290+ /**
291+ * 处理取消时,执行该方法
292+ * @return
293+ */
294+ Object cancelled ();
295+ }
296+
297+
298+ public static void main (String [] args ) throws KeyManagementException , NoSuchAlgorithmException , ClientProtocolException , IOException {
299+ AsyncHandler handler = new AsyncHandler ();
300+ String url = "http://php.weather.sina.com.cn/iframe/index/w_cl.php" ;
301+ Map <String , String > map = new HashMap <String , String >();
302+ map .put ("code" , "js" );
303+ map .put ("day" , "0" );
304+ map .put ("city" , "上海" );
305+ map .put ("dfc" , "1" );
306+ map .put ("charset" , "utf-8" );
307+ send (url , map , "utf-8" , handler );
308+
309+ System .out .println ("-----------------------------------" );
310+
311+ map .put ("city" , "北京" );
312+ send (url , map , "utf-8" , handler );
313+
314+ System .out .println ("-----------------------------------" );
315+
316+ }
317+ }
0 commit comments