HttpClient详细使用示例

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/justry_deng/article/details/81042379

        HTTP 协议可能是现在 Internet 上使用得最多、最重要的协议了,越来越多的 Java 应用程序需要直接通过 HTTP 协议来访问网络资源。虽然在 JDK 的 java net包中已经提供了访问 HTTP 协议的基本功能,但是对于大部分应用程序来说,JDK 库本身提供的功能还不够丰富和灵活。HttpClient 是 Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包,并且它支持 HTTP 协议最新的版本和建议。

        HTTP和浏览器有点像,但却不是浏览器。很多人觉得既然HttpClient是一个HTTP客户端编程工具,很多人把他当做浏览器来理解,但是其实HttpClient不是浏览器,它是一个HTTP通信库,因此它只提供一个通用浏览器应用程序所期望的功能子集,最根本的区别是HttpClient中没有用户界面,浏览器需要一个渲染引擎来显示页面,并解释用户输入,例如鼠标点击显示页面上的某处,有一个布局引擎,计算如何显示HTML页面,包括级联样式表和图像。javascript解释器运行嵌入HTML页面或从HTML页面引用的javascript代码。来自用户界面的事件被传递到javascript解释器进行处理。除此之外,还有用于插件的接口,可以处理Applet,嵌入式媒体对象(如pdf文件,Quicktime电影和Flash动画)或ActiveX控件(可以执行任何操作)。HttpClient只能以编程的方式通过其API用于传输和接受HTTP消息。

HttpClient的主要功能:

    实现了所有 HTTP 的方法(GET、POST、PUT、HEAD、DELETE、HEAD、OPTIONS 等)
    支持 HTTPS 协议
    支持代理服务器(Nginx等)等
    支持自动(跳转)转向
    ……
环境说明:Eclipse、JDK1.8、SpringBoot

 

 

详细使用示例

声明:此示例中,以JAVA发送HttpClient(在test里面单元测试发送的);也是以JAVA接收的(在controller里面接收的)。

声明:下面的代码,本人亲测有效。

GET无参:

HttpClient发送示例:

 1     /**
 2      * GET---无参测试
 3      *
 4      * @date 2018年7月13日 下午4:18:50
 5      */
 6     @Test
 7     public void doGetTestOne() {
 8         // 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
 9         CloseableHttpClient httpClient = HttpClientBuilder.create().build();
10         // 创建Get请求
11         HttpGet httpGet = new HttpGet("http://localhost:12345/doGetControllerOne");
12  
13         // 响应模型
14         CloseableHttpResponse response = null;
15         try {
16             // 由客户端执行(发送)Get请求
17             response = httpClient.execute(httpGet);
18             // 从响应模型中获取响应实体
19             HttpEntity responseEntity = response.getEntity();
20             System.out.println("响应状态为:" + response.getStatusLine());
21             if (responseEntity != null) {
22                 System.out.println("响应内容长度为:" + responseEntity.getContentLength());
23                 System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
24             }
25         } catch (ClientProtocolException e) {
26             e.printStackTrace();
27         } catch (ParseException e) {
28             e.printStackTrace();
29         } catch (IOException e) {
30             e.printStackTrace();
31         } finally {
32             try {
33                 // 释放资源
34                 if (httpClient != null) {
35                     httpClient.close();
36                 }
37                 if (response != null) {
38                     response.close();
39                 }
40             } catch (IOException e) {
41                 e.printStackTrace();
42             }
43         }
44     }

 

 

GET有参(方式一:直接拼接URL):

HttpClient发送示例:

 1     /**
 2      * GET---有参测试 (方式一:手动在url后面加上参数)
 3      *
 4      * @date 2018年7月13日 下午4:19:23
 5      */
 6     @Test
 7     public void doGetTestWayOne() {
 8         // 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
 9         CloseableHttpClient httpClient = HttpClientBuilder.create().build();
10  
11         // 参数
12         StringBuffer params = new StringBuffer();
13         try {
14             // 字符数据最好encoding以下;这样一来,某些特殊字符才能传过去(如:某人的名字就是“&”,不encoding的话,传不过去)
15             params.append("name=" + URLEncoder.encode("&", "utf-8"));
16             params.append("&");
17             params.append("age=24");
18         } catch (UnsupportedEncodingException e1) {
19             e1.printStackTrace();
20         }
21  
22         // 创建Get请求
23         HttpGet httpGet = new HttpGet("http://localhost:12345/doGetControllerTwo" + "?" + params);
24         // 响应模型
25         CloseableHttpResponse response = null;
26         try {
27             // 配置信息
28             RequestConfig requestConfig = RequestConfig.custom()
29                     // 设置连接超时时间(单位毫秒)
30                     .setConnectTimeout(5000)
31                     // 设置请求超时时间(单位毫秒)
32                     .setConnectionRequestTimeout(5000)
33                     // socket读写超时时间(单位毫秒)
34                     .setSocketTimeout(5000)
35                     // 设置是否允许重定向(默认为true)
36                     .setRedirectsEnabled(true).build();
37  
38             // 将上面的配置信息 运用到这个Get请求里
39             httpGet.setConfig(requestConfig);
40  
41             // 由客户端执行(发送)Get请求
42             response = httpClient.execute(httpGet);
43  
44             // 从响应模型中获取响应实体
45             HttpEntity responseEntity = response.getEntity();
46             System.out.println("响应状态为:" + response.getStatusLine());
47             if (responseEntity != null) {
48                 System.out.println("响应内容长度为:" + responseEntity.getContentLength());
49                 System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
50             }
51         } catch (ClientProtocolException e) {
52             e.printStackTrace();
53         } catch (ParseException e) {
54             e.printStackTrace();
55         } catch (IOException e) {
56             e.printStackTrace();
57         } finally {
58             try {
59                 // 释放资源
60                 if (httpClient != null) {
61                     httpClient.close();
62                 }
63                 if (response != null) {
64                     response.close();
65                 }
66             } catch (IOException e) {
67                 e.printStackTrace();
68             }
69         }
70     }

 

 

GET有参(方式二:使用URI获得HttpGet):

HttpClient发送示例:

 1     /**
 2      * GET---有参测试 (方式二:将参数放入键值对类中,再放入URI中,从而通过URI得到HttpGet实例)
 3      *
 4      * @date 2018年7月13日 下午4:19:23
 5      */
 6     @Test
 7     public void doGetTestWayTwo() {
 8         // 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
 9         CloseableHttpClient httpClient = HttpClientBuilder.create().build();
10  
11         // 参数
12         URI uri = null;
13         try {
14             // 将参数放入键值对类NameValuePair中,再放入集合中
15             List<NameValuePair> params = new ArrayList<>();
16             params.add(new BasicNameValuePair("name", "&"));
17             params.add(new BasicNameValuePair("age", "18"));
18             // 设置uri信息,并将参数集合放入uri;
19             // 注:这里也支持一个键值对一个键值对地往里面放setParameter(String key, String value)
20             uri = new URIBuilder().setScheme("http").setHost("localhost")
21                                   .setPort(12345).setPath("/doGetControllerTwo")
22                                   .setParameters(params).build();
23         } catch (URISyntaxException e1) {
24             e1.printStackTrace();
25         }
26         // 创建Get请求
27         HttpGet httpGet = new HttpGet(uri);
28  
29         // 响应模型
30         CloseableHttpResponse response = null;
31         try {
32             // 配置信息
33             RequestConfig requestConfig = RequestConfig.custom()
34                     // 设置连接超时时间(单位毫秒)
35                     .setConnectTimeout(5000)
36                     // 设置请求超时时间(单位毫秒)
37                     .setConnectionRequestTimeout(5000)
38                     // socket读写超时时间(单位毫秒)
39                     .setSocketTimeout(5000)
40                     // 设置是否允许重定向(默认为true)
41                     .setRedirectsEnabled(true).build();
42  
43             // 将上面的配置信息 运用到这个Get请求里
44             httpGet.setConfig(requestConfig);
45  
46             // 由客户端执行(发送)Get请求
47             response = httpClient.execute(httpGet);
48  
49             // 从响应模型中获取响应实体
50             HttpEntity responseEntity = response.getEntity();
51             System.out.println("响应状态为:" + response.getStatusLine());
52             if (responseEntity != null) {
53                 System.out.println("响应内容长度为:" + responseEntity.getContentLength());
54                 System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
55             }
56         } catch (ClientProtocolException e) {
57             e.printStackTrace();
58         } catch (ParseException e) {
59             e.printStackTrace();
60         } catch (IOException e) {
61             e.printStackTrace();
62         } finally {
63             try {
64                 // 释放资源
65                 if (httpClient != null) {
66                     httpClient.close();
67                 }
68                 if (response != null) {
69                     response.close();
70                 }
71             } catch (IOException e) {
72                 e.printStackTrace();
73             }
74         }
75     }

 

 

POST无参:

HttpClient发送示例:

 1     /**
 2      * POST---无参测试
 3      *
 4      * @date 2018年7月13日 下午4:18:50
 5      */
 6     @Test
 7     public void doPostTestOne() {
 8  
 9         // 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
10         CloseableHttpClient httpClient = HttpClientBuilder.create().build();
11  
12         // 创建Post请求
13         HttpPost httpPost = new HttpPost("http://localhost:12345/doPostControllerOne");
14         // 响应模型
15         CloseableHttpResponse response = null;
16         try {
17             // 由客户端执行(发送)Post请求
18             response = httpClient.execute(httpPost);
19             // 从响应模型中获取响应实体
20             HttpEntity responseEntity = response.getEntity();
21  
22             System.out.println("响应状态为:" + response.getStatusLine());
23             if (responseEntity != null) {
24                 System.out.println("响应内容长度为:" + responseEntity.getContentLength());
25                 System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
26             }
27         } catch (ClientProtocolException e) {
28             e.printStackTrace();
29         } catch (ParseException e) {
30             e.printStackTrace();
31         } catch (IOException e) {
32             e.printStackTrace();
33         } finally {
34             try {
35                 // 释放资源
36                 if (httpClient != null) {
37                     httpClient.close();
38                 }
39                 if (response != null) {
40                     response.close();
41                 }
42             } catch (IOException e) {
43                 e.printStackTrace();
44             }
45         }
46     }

 

 

POST有参(普通参数):

注:POST传递普通参数时,方式与GET一样即可,这里以直接在url后缀上参数的方式示例。

HttpClient发送示例:

 1     /**
 2      * POST---有参测试(普通参数)
 3      *
 4      * @date 2018年7月13日 下午4:18:50
 5      */
 6     @Test
 7     public void doPostTestFour() {
 8  
 9         // 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
10         CloseableHttpClient httpClient = HttpClientBuilder.create().build();
11  
12         // 参数
13         StringBuffer params = new StringBuffer();
14         try {
15             // 字符数据最好encoding以下;这样一来,某些特殊字符才能传过去(如:某人的名字就是“&”,不encoding的话,传不过去)
16             params.append("name=" + URLEncoder.encode("&", "utf-8"));
17             params.append("&");
18             params.append("age=24");
19         } catch (UnsupportedEncodingException e1) {
20             e1.printStackTrace();
21         }
22  
23         // 创建Post请求
24         HttpPost httpPost = new HttpPost("http://localhost:12345/doPostControllerFour" + "?" + params);
25  
26         // 设置ContentType(注:如果只是传普通参数的话,ContentType不一定非要用application/json)
27         httpPost.setHeader("Content-Type", "application/json;charset=utf8");
28  
29         // 响应模型
30         CloseableHttpResponse response = null;
31         try {
32             // 由客户端执行(发送)Post请求
33             response = httpClient.execute(httpPost);
34             // 从响应模型中获取响应实体
35             HttpEntity responseEntity = response.getEntity();
36  
37             System.out.println("响应状态为:" + response.getStatusLine());
38             if (responseEntity != null) {
39                 System.out.println("响应内容长度为:" + responseEntity.getContentLength());
40                 System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
41             }
42         } catch (ClientProtocolException e) {
43             e.printStackTrace();
44         } catch (ParseException e) {
45             e.printStackTrace();
46         } catch (IOException e) {
47             e.printStackTrace();
48         } finally {
49             try {
50                 // 释放资源
51                 if (httpClient != null) {
52                     httpClient.close();
53                 }
54                 if (response != null) {
55                     response.close();
56                 }
57             } catch (IOException e) {
58                 e.printStackTrace();
59             }
60         }
61     }

 

 

POST有参(对象参数):

先给出User类

HttpClient发送示例:

 1     /**
 2      * POST---有参测试(对象参数)
 3      *
 4      * @date 2018年7月13日 下午4:18:50
 5      */
 6     @Test
 7     public void doPostTestTwo() {
 8  
 9         // 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
10         CloseableHttpClient httpClient = HttpClientBuilder.create().build();
11  
12         // 创建Post请求
13         HttpPost httpPost = new HttpPost("http://localhost:12345/doPostControllerTwo");
14         User user = new User();
15         user.setName("潘晓婷");
16         user.setAge(18);
17         user.setGender("女");
18         user.setMotto("姿势要优雅~");
19         // 我这里利用阿里的fastjson,将Object转换为json字符串;
20         // (需要导入com.alibaba.fastjson.JSON包)
21         String jsonString = JSON.toJSONString(user);
22  
23         StringEntity entity = new StringEntity(jsonString, "UTF-8");
24  
25         // post请求是将参数放在请求体里面传过去的;这里将entity放入post请求体中
26         httpPost.setEntity(entity);
27  
28         httpPost.setHeader("Content-Type", "application/json;charset=utf8");
29  
30         // 响应模型
31         CloseableHttpResponse response = null;
32         try {
33             // 由客户端执行(发送)Post请求
34             response = httpClient.execute(httpPost);
35             // 从响应模型中获取响应实体
36             HttpEntity responseEntity = response.getEntity();
37  
38             System.out.println("响应状态为:" + response.getStatusLine());
39             if (responseEntity != null) {
40                 System.out.println("响应内容长度为:" + responseEntity.getContentLength());
41                 System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
42             }
43         } catch (ClientProtocolException e) {
44             e.printStackTrace();
45         } catch (ParseException e) {
46             e.printStackTrace();
47         } catch (IOException e) {
48             e.printStackTrace();
49         } finally {
50             try {
51                 // 释放资源
52                 if (httpClient != null) {
53                     httpClient.close();
54                 }
55                 if (response != null) {
56                     response.close();
57                 }
58             } catch (IOException e) {
59                 e.printStackTrace();
60             }
61         }
62     }

 

 

POST有参(普通参数 + 对象参数):

注:POST传递普通参数时,方式与GET一样即可,这里以通过URI获得HttpPost的方式为例。

先给出User类:

HttpClient发送示例:

 1     /**
 2      * POST---有参测试(普通参数 + 对象参数)
 3      *
 4      * @date 2018年7月13日 下午4:18:50
 5      */
 6     @Test
 7     public void doPostTestThree() {
 8  
 9         // 获得Http客户端(可以理解为:你得先有一个浏览器;注意:实际上HttpClient与浏览器是不一样的)
10         CloseableHttpClient httpClient = HttpClientBuilder.create().build();
11  
12         // 创建Post请求
13         // 参数
14         URI uri = null;
15         try {
16             // 将参数放入键值对类NameValuePair中,再放入集合中
17             List<NameValuePair> params = new ArrayList<>();
18             params.add(new BasicNameValuePair("flag", "4"));
19             params.add(new BasicNameValuePair("meaning", "这是什么鬼?"));
20             // 设置uri信息,并将参数集合放入uri;
21             // 注:这里也支持一个键值对一个键值对地往里面放setParameter(String key, String value)
22             uri = new URIBuilder().setScheme("http").setHost("localhost").setPort(12345)
23                     .setPath("/doPostControllerThree").setParameters(params).build();
24         } catch (URISyntaxException e1) {
25             e1.printStackTrace();
26         }
27  
28         HttpPost httpPost = new HttpPost(uri);
29         // HttpPost httpPost = new
30         // HttpPost("http://localhost:12345/doPostControllerThree1");
31  
32         // 创建user参数
33         User user = new User();
34         user.setName("潘晓婷");
35         user.setAge(18);
36         user.setGender("女");
37         user.setMotto("姿势要优雅~");
38  
39         // 将user对象转换为json字符串,并放入entity中
40         StringEntity entity = new StringEntity(JSON.toJSONString(user), "UTF-8");
41  
42         // post请求是将参数放在请求体里面传过去的;这里将entity放入post请求体中
43         httpPost.setEntity(entity);
44  
45         httpPost.setHeader("Content-Type", "application/json;charset=utf8");
46  
47         // 响应模型
48         CloseableHttpResponse response = null;
49         try {
50             // 由客户端执行(发送)Post请求
51             response = httpClient.execute(httpPost);
52             // 从响应模型中获取响应实体
53             HttpEntity responseEntity = response.getEntity();
54  
55             System.out.println("响应状态为:" + response.getStatusLine());
56             if (responseEntity != null) {
57                 System.out.println("响应内容长度为:" + responseEntity.getContentLength());
58                 System.out.println("响应内容为:" + EntityUtils.toString(responseEntity));
59             }
60         } catch (ClientProtocolException e) {
61             e.printStackTrace();
62         } catch (ParseException e) {
63             e.printStackTrace();
64         } catch (IOException e) {
65             e.printStackTrace();
66         } finally {
67             try {
68                 // 释放资源
69                 if (httpClient != null) {
70                     httpClient.close();
71                 }
72                 if (response != null) {
73                     response.close();
74                 }
75             } catch (IOException e) {
76                 e.printStackTrace();
77             }
78         }
79     }

 

 

对评论区关注度较高的问题进行相关补充:

提示:如果想要知道完整的具体的代码及测试细节,可去下面给的项目代码托管链接,将项目clone下来
           进行观察。如果需要运行测试,可以先启动该SpringBoot项目,然后再运行相关test方法,进行
           测试。
解决响应乱码问题(示例):

 

 

进行HTTPS请求并进行(或不进行)证书校验(示例):

使用示例:

 

 

相关方法详情(非完美封装):

  1 /**
  2  * 根据是否是https请求,获取HttpClient客户端
  3  *
  4  * TODO 本人这里没有进行完美封装。对于 校不校验校验证书的选择,本人这里是写死
  5  *      在代码里面的,你们再使用时,可以灵活二次封装。
  6  *
  7  * 提示: 此工具类的封装、相关客户端、服务端证书的生成,可参考我的这篇博客:
  8  *      <linked>https://blog.csdn.net/justry_deng/article/details/91569132</linked>
  9  *
 10  *
 11  * @param isHttps 是否是HTTPS请求
 12  *
 13  * @return  HttpClient实例
 14  * @date 2019/9/18 17:57
 15  */
 16 private CloseableHttpClient getHttpClient(boolean isHttps) {
 17    CloseableHttpClient httpClient;
 18    if (isHttps) {
 19       SSLConnectionSocketFactory sslSocketFactory;
 20       try {
 21          /// 如果不作证书校验的话
 22          sslSocketFactory = getSocketFactory(false, null, null);
 23  
 24          /// 如果需要证书检验的话
 25          // 证书
 26          //InputStream ca = this.getClass().getClassLoader().getResourceAsStream("client/ds.crt");
 27          // 证书的别名,即:key。 注:cAalias只需要保证唯一即可,不过推荐使用生成keystore时使用的别名。
 28          // String cAalias = System.currentTimeMillis() + "" + new SecureRandom().nextInt(1000);
 29          //sslSocketFactory = getSocketFactory(true, ca, cAalias);
 30       } catch (Exception e) {
 31          throw new RuntimeException(e);
 32       }
 33       httpClient = HttpClientBuilder.create().setSSLSocketFactory(sslSocketFactory).build();
 34       return httpClient;
 35    }
 36    httpClient = HttpClientBuilder.create().build();
 37    return httpClient;
 38 }
 39  
 40 /**
 41  * HTTPS辅助方法, 为HTTPS请求 创建SSLSocketFactory实例、TrustManager实例
 42  *
 43  * @param needVerifyCa
 44  *         是否需要检验CA证书(即:是否需要检验服务器的身份)
 45  * @param caInputStream
 46  *         CA证书。(若不需要检验证书,那么此处传null即可)
 47  * @param cAalias
 48  *         别名。(若不需要检验证书,那么此处传null即可)
 49  *         注意:别名应该是唯一的, 别名不要和其他的别名一样,否者会覆盖之前的相同别名的证书信息。别名即key-value中的key。
 50  *
 51  * @return SSLConnectionSocketFactory实例
 52  * @throws NoSuchAlgorithmException
 53  *         异常信息
 54  * @throws CertificateException
 55  *         异常信息
 56  * @throws KeyStoreException
 57  *         异常信息
 58  * @throws IOException
 59  *         异常信息
 60  * @throws KeyManagementException
 61  *         异常信息
 62  * @date 2019/6/11 19:52
 63  */
 64 private static SSLConnectionSocketFactory getSocketFactory(boolean needVerifyCa, InputStream caInputStream, String cAalias)
 65       throws CertificateException, NoSuchAlgorithmException, KeyStoreException,
 66       IOException, KeyManagementException {
 67    X509TrustManager x509TrustManager;
 68    // https请求,需要校验证书
 69    if (needVerifyCa) {
 70       KeyStore keyStore = getKeyStore(caInputStream, cAalias);
 71       TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
 72       trustManagerFactory.init(keyStore);
 73       TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
 74       if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
 75          throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
 76       }
 77       x509TrustManager = (X509TrustManager) trustManagers[0];
 78       // 这里传TLS或SSL其实都可以的
 79       SSLContext sslContext = SSLContext.getInstance("TLS");
 80       sslContext.init(null, new TrustManager[]{x509TrustManager}, new SecureRandom());
 81       return new SSLConnectionSocketFactory(sslContext);
 82    }
 83    // https请求,不作证书校验
 84    x509TrustManager = new X509TrustManager() {
 85       @Override
 86       public void checkClientTrusted(X509Certificate[] arg0, String arg1) {
 87       }
 88  
 89       @Override
 90       public void checkServerTrusted(X509Certificate[] arg0, String arg1) {
 91          // 不验证
 92       }
 93  
 94       @Override
 95       public X509Certificate[] getAcceptedIssuers() {
 96          return new X509Certificate[0];
 97       }
 98    };
 99    SSLContext sslContext = SSLContext.getInstance("TLS");
100    sslContext.init(null, new TrustManager[]{x509TrustManager}, new SecureRandom());
101    return new SSLConnectionSocketFactory(sslContext);
102 }
103  
104 /**
105  * 获取(密钥及证书)仓库
106  * 注:该仓库用于存放 密钥以及证书
107  *
108  * @param caInputStream
109  *         CA证书(此证书应由要访问的服务端提供)
110  * @param cAalias
111  *         别名
112  *         注意:别名应该是唯一的, 别名不要和其他的别名一样,否者会覆盖之前的相同别名的证书信息。别名即key-value中的key。
113  * @return 密钥、证书 仓库
114  * @throws KeyStoreException 异常信息
115  * @throws CertificateException 异常信息
116  * @throws IOException 异常信息
117  * @throws NoSuchAlgorithmException 异常信息
118  * @date 2019/6/11 18:48
119  */
120 private static KeyStore getKeyStore(InputStream caInputStream, String cAalias)
121       throws KeyStoreException, CertificateException, IOException, NoSuchAlgorithmException {
122    // 证书工厂
123    CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
124    // 秘钥仓库
125    KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
126    keyStore.load(null);
127    keyStore.setCertificateEntry(cAalias, certificateFactory.generateCertificate(caInputStream));
128    return keyStore;
129 }
View Code

 

application/x-www-form-urlencoded表单请求(示例):

 

 

发送文件(示例):

准备工作:

       如果想要灵活方便的传输文件的话,除了引入org.apache.httpcomponents基本的httpclient依赖外再额外引入org.apache.httpcomponents的httpmime依赖。
P.S.:即便不引入httpmime依赖,也是能传输文件的,不过功能不够强大。

在pom.xml中额外引入:

1 <!--
2      如果需要灵活的传输文件,引入次依赖后会更加方便
3 -->
4 <dependency>
5     <groupId>org.apache.httpcomponents</groupId>
6     <artifactId>httpmime</artifactId>
7     <version>4.5.5</version>
8 </dependency>

发送端是这样的:

 1 /**
 2  *
 3  * 发送文件
 4  *
 5  * multipart/form-data传递文件(及相关信息)
 6  *
 7  * 注:如果想要灵活方便的传输文件的话,
 8  *    除了引入org.apache.httpcomponents基本的httpclient依赖外
 9  *    再额外引入org.apache.httpcomponents的httpmime依赖。
10  *    追注:即便不引入httpmime依赖,也是能传输文件的,不过功能不够强大。
11  *
12  */
13 @Test
14 public void test4() {
15    CloseableHttpClient httpClient = HttpClientBuilder.create().build();
16    HttpPost httpPost = new HttpPost("http://localhost:12345/file");
17    CloseableHttpResponse response = null;
18    try {
19       MultipartEntityBuilder multipartEntityBuilder = MultipartEntityBuilder.create();
20       // 第一个文件
21       String filesKey = "files";
22       File file1 = new File("C:\\Users\\JustryDeng\\Desktop\\back.jpg");
23       multipartEntityBuilder.addBinaryBody(filesKey, file1);
24       // 第二个文件(多个文件的话,使用可一个key就行,后端用数组或集合进行接收即可)
25       File file2 = new File("C:\\Users\\JustryDeng\\Desktop\\头像.jpg");
26       // 防止服务端收到的文件名乱码。 我们这里可以先将文件名URLEncode,然后服务端拿到文件名时在URLDecode。就能避免乱码问题。
27       // 文件名其实是放在请求头的Content-Disposition里面进行传输的,如其值为form-data; name="files"; filename="头像.jpg"
28       multipartEntityBuilder.addBinaryBody(filesKey, file2, ContentType.DEFAULT_BINARY, URLEncoder.encode(file2.getName(), "utf-8"));
29       // 其它参数(注:自定义contentType,设置UTF-8是为了防止服务端拿到的参数出现乱码)
30       ContentType contentType = ContentType.create("text/plain", Charset.forName("UTF-8"));
31       multipartEntityBuilder.addTextBody("name", "邓沙利文", contentType);
32       multipartEntityBuilder.addTextBody("age", "25", contentType);
33  
34       HttpEntity httpEntity = multipartEntityBuilder.build();
35       httpPost.setEntity(httpEntity);
36  
37       response = httpClient.execute(httpPost);
38       HttpEntity responseEntity = response.getEntity();
39       System.out.println("HTTPS响应状态为:" + response.getStatusLine());
40       if (responseEntity != null) {
41          System.out.println("HTTPS响应内容长度为:" + responseEntity.getContentLength());
42          // 主动设置编码,来防止响应乱码
43          String responseStr = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);
44          System.out.println("HTTPS响应内容为:" + responseStr);
45       }
46    } catch (ParseException | IOException e) {
47       e.printStackTrace();
48    } finally {
49       try {
50          // 释放资源
51          if (httpClient != null) {
52             httpClient.close();
53          }
54          if (response != null) {
55             response.close();
56          }
57       } catch (IOException e) {
58          e.printStackTrace();
59       }
60    }
61 }

接收端是这样的:

 

 

发送流(示例):

发送端是这样的:

 1 /**
 2  *
 3  * 发送流
 4  *
 5  */
 6 @Test
 7 public void test5() {
 8    CloseableHttpClient httpClient = HttpClientBuilder.create().build();
 9    HttpPost httpPost = new HttpPost("http://localhost:12345/is?name=邓沙利文");
10    CloseableHttpResponse response = null;
11    try {
12       InputStream is = new ByteArrayInputStream("流啊流~".getBytes());
13       InputStreamEntity ise = new InputStreamEntity(is);
14       httpPost.setEntity(ise);
15  
16       response = httpClient.execute(httpPost);
17       HttpEntity responseEntity = response.getEntity();
18       System.out.println("HTTPS响应状态为:" + response.getStatusLine());
19       if (responseEntity != null) {
20          System.out.println("HTTPS响应内容长度为:" + responseEntity.getContentLength());
21          // 主动设置编码,来防止响应乱码
22          String responseStr = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8);
23          System.out.println("HTTPS响应内容为:" + responseStr);
24       }
25    } catch (ParseException | IOException e) {
26       e.printStackTrace();
27    } finally {
28       try {
29          // 释放资源
30          if (httpClient != null) {
31             httpClient.close();
32          }
33          if (response != null) {
34             response.close();
35          }
36       } catch (IOException e) {
37          e.printStackTrace();
38       }
39    }
40 }

接收端是这样的:

 

 工具类提示:使用HttpClient时,可以视情况将其写为工具类。如:Github上Star非常多的一个HttpClient
                      的工具类是httpclientutil。本人在这里也推荐使用该工具类,因为该工具类的编写者封装了
                      很多功能在里面,如果不是有什么特殊的需求的话,完全可以不用造轮子,可以直接使用
                      该工具类。使用方式很简单,可详见https://github.com/Arronlong/httpclientutil。


 

 

 

posted @ 2019-11-01 16:15  家有小壮壮、  阅读(1607)  评论(0编辑  收藏  举报