文件来源:
https://blog.csdn.net/Mrqiang9001/article/details/90271675
文章目录
1 摘要
2 Maven 依赖
3 HttpClient 网络请求工具类
4 应用与测试
4.1 测试类
4.2 GET 请求测试
4.3 POST 请求-URL拼接参数
4.4 POST请求-JSON参数
4.5 POST请求-文件上传
5 参考资料推荐
6 Github 源码
1 摘要
java 项目中网络请求是一个常用的功能。jdk 自带的网络工具类(java.net)效率低下,因此推荐使用第三方的网络库。Apache HttpClient 库深受广大开发者的欢迎。本文将介绍在 Spring Boot 2.X 项目中简单使用基于 Apache Httpclient 4.5.X 发送请求与上传文件。
Apache HttpClient 官方文档: https://hc.apache.org/httpcomponents-client-ga/quickstart.html
2 Maven 依赖
../pom.xml
../demo-common/pom.xml
<!-- Apache httpClient --> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>${httpclient.version}</version> </dependency> <dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpmime</artifactId> <version>${httpclient.version}</version> </dependency>
其中的版本为:
<httpclient.version>4.5.6</httpclient.version>
3 HttpClient 网络请求工具类
../demo-common/src/main/java/com/ljq/demo/springboot/common/util/SimpleHttpClientUtil.java
package com.ljq.demo.springboot.common.util; import org.apache.http.Consts; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.entity.mime.HttpMultipartMode; import org.apache.http.entity.mime.MultipartEntityBuilder; import org.apache.http.impl.client.HttpClients; import org.apache.http.protocol.HTTP; import java.io.IOException; import java.io.InputStream; import java.io.Serializable; import java.util.Map; /** * @Description: 网络请求工具类--Powered by Apache HttpClient * @Author: junqiang.lu * @Date: 2019/5/16 */ public class SimpleHttpClientUtil implements Serializable { private static final long serialVersionUID = 4634161754990919271L; private static volatile HttpClient httpClient; private SimpleHttpClientUtil(){} /** * GET 方式请求 * 参数通过 url 拼接 * * @param host 请求地址 * @param path 接口路径 * @param paramsMap 请求参数 * @return * @throws IOException */ public static HttpResponse doGet(String host, String path, Map<String, String> paramsMap) throws IOException { initHttpClient(); RequestConfig requestConfig = RequestConfig.custom() .setConnectionRequestTimeout(10000) .setConnectTimeout(5000) .build(); HttpGet httpGet = new HttpGet(getRequestUrl(host, path, paramsMap)); httpGet.setConfig(requestConfig); httpGet.setHeader(HTTP.CONTENT_TYPE,ContentType.create(ContentType.APPLICATION_FORM_URLENCODED .getMimeType(),Consts.UTF_8).toString()); return httpClient.execute(httpGet); } /** * POST 方式请求 * 参数通过 url 拼接 * * @param host 请求地址 * @param path 接口路径 * @param paramsMap 请求参数 * @return * @throws IOException */ public static HttpResponse doPost(String host, String path, Map<String, String> paramsMap) throws IOException { initHttpClient(); RequestConfig requestConfig = RequestConfig.custom() .setConnectionRequestTimeout(10000) .setConnectTimeout(5000) .build(); HttpPost httpPost = new HttpPost(getRequestUrl(host, path, paramsMap)); httpPost.setConfig(requestConfig); httpPost.setHeader(HTTP.CONTENT_TYPE,ContentType.create(ContentType.APPLICATION_FORM_URLENCODED .getMimeType(),Consts.UTF_8).toString()); return httpClient.execute(httpPost); } /** * POST 方式请求 * 参数通过 Body 传送,JSON 格式 * * @param host 请求地址 * @param path 接口路径 * @param jsonParams 请求参数(json 字符串) * @return */ public static HttpResponse doPost(String host, String path, String jsonParams) throws IOException { initHttpClient(); RequestConfig requestConfig = RequestConfig.custom() .setConnectionRequestTimeout(10000) .setConnectTimeout(5000) .build(); HttpPost httpPost = new HttpPost(host + path); StringEntity stringentity = new StringEntity(jsonParams, ContentType.APPLICATION_JSON); httpPost.setEntity(stringentity); httpPost.setConfig(requestConfig); httpPost.addHeader(HTTP.CONTENT_TYPE, ContentType.APPLICATION_JSON.toString()); return httpClient.execute(httpPost); } /** * POST 方式请求 * 文件上传 * * @param host 请求地址 * @param path 接口路径 * @param paramsMap 请求参数 * @param fileInputStream 待上传文件流 * @param name 文件对应字段名 * @param fileOriginalName 原始文件名 * @return */ public static HttpResponse doPost(String host, String path, Map<String, String> paramsMap, InputStream fileInputStream, String name, String fileOriginalName) throws IOException { initHttpClient(); RequestConfig requestConfig = RequestConfig.custom() .setConnectionRequestTimeout(10000) .setConnectTimeout(5000) .build(); HttpPost httpPost = new HttpPost(host + path); MultipartEntityBuilder entityBuilder = MultipartEntityBuilder.create(); // 解决中文文件名乱码问题 entityBuilder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); entityBuilder.setCharset(Consts.UTF_8); ContentType contentType = ContentType.create(ContentType.TEXT_PLAIN.getMimeType(), Consts.UTF_8); for (Map.Entry<String, String> entry : paramsMap.entrySet()) { entityBuilder.addTextBody(entry.getKey(), entry.getValue(), contentType); } if (fileInputStream != null && name != null && fileOriginalName != null) { entityBuilder.addBinaryBody(name, fileInputStream, ContentType.DEFAULT_BINARY, fileOriginalName); } httpPost.setEntity(entityBuilder.build()); httpPost.setConfig(requestConfig); return httpClient.execute(httpPost); } /** * 初始化 httpClient * @return */ private static HttpClient initHttpClient() { if (httpClient == null) { synchronized (SimpleHttpClientUtil.class) { if (httpClient == null) { httpClient = HttpClients.createDefault(); } } } return httpClient; } /** * 获取完整请求地址(包含参数) * 参数拼接在 url 中 * * @param host 请求地址 * @param path 接口路径 * @param paramsMap 请求参数 * @return */ private static String getRequestUrl(String host, String path, Map<String, String> paramsMap) { StringBuilder reqUrl = new StringBuilder(host).append(path); if (paramsMap != null && !paramsMap.isEmpty()) { StringBuilder params = new StringBuilder(); for (Map.Entry<String, String> entry : paramsMap.entrySet()) { params.append("&" + entry.getKey() + "=" + entry.getValue()); } String paramConnector = "?"; if (!host.contains(paramConnector) && !path.contains(paramConnector)) { reqUrl.append(paramConnector); reqUrl.append(params.toString().substring(1)); } else { reqUrl.append(params.toString()); } } return reqUrl.toString(); } }
4 应用与测试
4.1 测试类
../demo-web/src/test/java/com/ljq/demo/springboot/common/util/SimpleHttpClientUtilTest.java
package com.ljq.demo.springboot.common.util; import com.fasterxml.jackson.databind.ObjectMapper; import org.apache.http.HttpResponse; import org.apache.http.util.EntityUtils; import org.junit.Test; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.HashMap; import java.util.Map; public class SimpleHttpClientUtilTest { private static String API_HOST = "http://192.168.100.100:8848"; private static String API_PATH_USER_LIST = "/api/user/list"; private static String API_PATH_USER_LISTS = "/api/user/lists"; private static String API_PATH_COMMON_UPLOAD = "/api/demo/common/upload"; @Test public void doGet() throws IOException { String paramsStr = "?demoKey=demoValue"; Map<String, String> paramsMap = new HashMap<>(16); paramsMap.put("demoMapKey", "demoMapValue"); paramsMap.put("zhTest", "德玛西亚"); HttpResponse httpResponse = SimpleHttpClientUtil.doGet(API_HOST, API_PATH_USER_LIST + paramsStr, paramsMap); printHttpResponse(httpResponse); } @Test public void doPostJson() throws IOException { Map<String, String> paramsMap = new HashMap<>(16); paramsMap.put("demoMapKey", "demoMapValue"); paramsMap.put("zhTest", "德玛西亚"); HttpResponse httpResponse = SimpleHttpClientUtil.doPost(API_HOST, API_PATH_USER_LIST, new ObjectMapper().writeValueAsString(paramsMap)); printHttpResponse(httpResponse); } @Test public void doPostUrl() throws IOException { Map<String, String> paramsMap = new HashMap<>(16); paramsMap.put("demoMapKey", "demoMapValue"); paramsMap.put("zhTest", "德玛西亚"); HttpResponse httpResponse = SimpleHttpClientUtil.doPost(API_HOST, API_PATH_USER_LISTS, paramsMap); printHttpResponse(httpResponse); } @Test public void doPostMultipart() throws IOException { Map<String, String> paramsMap = new HashMap<>(16); paramsMap.put("demoMapKey", "demoMapValue"); paramsMap.put("zhTest", "德玛西亚"); Path path = Paths.get("F:\\download\\阿里巴巴Java开发手册(详尽版).pdf"); String name = "file"; String fileOriginalName = "阿里巴巴Java开发手册(详尽版).pdf"; HttpResponse httpResponse = SimpleHttpClientUtil.doPost(API_HOST, API_PATH_COMMON_UPLOAD, paramsMap, Files.newInputStream(path),name, fileOriginalName); printHttpResponse(httpResponse); } /** * 打印 http 请求结果 * * @param httpResponse * @throws IOException */ public static void printHttpResponse(HttpResponse httpResponse) throws IOException { System.out.println("response Code: " + httpResponse.getStatusLine().getStatusCode()); System.out.println(EntityUtils.toString(httpResponse.getEntity())); } }
4.2 GET 请求测试
请求日志:
2019-05-16 19:49:02:919 [http-nio-8848-exec-2] INFO com.ljq.demo.springboot.web.acpect.LogAspect(LogAspect.java 67) -[AOP-LOG-START] requestMark: ee0a1d50-d943-42aa-ab63-5505f04de027 requestIP: 192.168.100.1 contentType:application/x-www-form-urlencoded; charset=UTF-8 requestUrl: http://192.168.100.100:8848/api/user/list requestMethod: GET requestParams: demoKey = demoValue;zhTest = 德玛西亚;demoMapKey = demoMapValue; targetClassAndMethod: com.ljq.demo.springboot.web.controller.UserController#queryList
返回结果:
response Code: 200
{"code":1000,"msg":"成功","data":[{"id":5,"userName":"liming","userPasscode":"ed0de7252acf2980e677bacab01bde25","userEmail":"liming@example.com","userInsertTime":"2019-04-25 17:07:30","userUpdateTime":"2019-04-25 17:07:30","userStatus":1},{"id":4,"userName":"lily","userPasscode":"ed0de7252acf2980e677bacab01bde25","userEmail":"lily@example.com","userInsertTime":"2019-04-25 17:07:30","userUpdateTime":"2019-04-25 17:07:30","userStatus":1},{"id":3,"userName":"jack","userPasscode":"ed0de7252acf2980e677bacab01bde25","userEmail":"jack@example.com","userInsertTime":"2019-04-25 17:07:30","userUpdateTime":"2019-04-25 17:07:30","userStatus":1},{"id":2,"userName":"bob","userPasscode":"ed0de7252acf2980e677bacab01bde25","userEmail":"bob@example.com","userInsertTime":"2019-04-25 17:07:30","userUpdateTime":"2019-04-25 17:07:30","userStatus":1},{"id":1,"userName":"tom","userPasscode":"ed0de7252acf2980e677bacab01bde25","userEmail":"tom@example.com","userInsertTime":"2019-04-25 17:07:30","userUpdateTime":"2019-04-25 17:07:30","userStatus":1}]}
4.3 POST 请求-URL拼接参数
请求日志:
2019-05-16 20:13:28:509 [http-nio-8848-exec-4] INFO com.ljq.demo.springboot.web.acpect.LogAspect(LogAspect.java 67) -[AOP-LOG-START] requestMark: c7e7d6d0-873b-440e-bb24-270abde33e7f requestIP: 192.168.100.1 contentType:application/x-www-form-urlencoded; charset=UTF-8 requestUrl: http://192.168.100.100:8848/api/user/lists requestMethod: POST requestParams: zhTest = 德玛西亚;demoMapKey = demoMapValue; targetClassAndMethod: com.ljq.demo.springboot.web.controller.UserController#queryLists
返回结果:
response Code: 200
{"code":1000,"msg":"成功","data":[{"id":5,"userName":"liming","userPasscode":"ed0de7252acf2980e677bacab01bde25","userEmail":"liming@example.com","userInsertTime":"2019-04-25 17:07:30","userUpdateTime":"2019-04-25 17:07:30","userStatus":1},{"id":4,"userName":"lily","userPasscode":"ed0de7252acf2980e677bacab01bde25","userEmail":"lily@example.com","userInsertTime":"2019-04-25 17:07:30","userUpdateTime":"2019-04-25 17:07:30","userStatus":1},{"id":3,"userName":"jack","userPasscode":"ed0de7252acf2980e677bacab01bde25","userEmail":"jack@example.com","userInsertTime":"2019-04-25 17:07:30","userUpdateTime":"2019-04-25 17:07:30","userStatus":1},{"id":2,"userName":"bob","userPasscode":"ed0de7252acf2980e677bacab01bde25","userEmail":"bob@example.com","userInsertTime":"2019-04-25 17:07:30","userUpdateTime":"2019-04-25 17:07:30","userStatus":1},{"id":1,"userName":"tom","userPasscode":"ed0de7252acf2980e677bacab01bde25","userEmail":"tom@example.com","userInsertTime":"2019-04-25 17:07:30","userUpdateTime":"2019-04-25 17:07:30","userStatus":1}]}
4.4 POST请求-JSON参数
请求日志:
2019-05-16 20:15:26:249 [http-nio-8848-exec-5] INFO com.ljq.demo.springboot.web.acpect.LogAspect(LogAspect.java 67) -[AOP-LOG-START] requestMark: f94612bd-dcc9-4b7b-9c77-2b296cd00948 requestIP: 192.168.100.1 contentType:application/json; charset=UTF-8 requestUrl: http://192.168.100.100:8848/api/user/list requestMethod: POST requestParams: {"zhTest":"德玛西亚","demoMapKey":"demoMapValue"} targetClassAndMethod: com.ljq.demo.springboot.web.controller.UserController#queryList
返回结果:
response Code: 200
{"code":1000,"msg":"成功","data":[{"id":5,"userName":"liming","userPasscode":"ed0de7252acf2980e677bacab01bde25","userEmail":"liming@example.com","userInsertTime":"2019-04-25 17:07:30","userUpdateTime":"2019-04-25 17:07:30","userStatus":1},{"id":4,"userName":"lily","userPasscode":"ed0de7252acf2980e677bacab01bde25","userEmail":"lily@example.com","userInsertTime":"2019-04-25 17:07:30","userUpdateTime":"2019-04-25 17:07:30","userStatus":1},{"id":3,"userName":"jack","userPasscode":"ed0de7252acf2980e677bacab01bde25","userEmail":"jack@example.com","userInsertTime":"2019-04-25 17:07:30","userUpdateTime":"2019-04-25 17:07:30","userStatus":1},{"id":2,"userName":"bob","userPasscode":"ed0de7252acf2980e677bacab01bde25","userEmail":"bob@example.com","userInsertTime":"2019-04-25 17:07:30","userUpdateTime":"2019-04-25 17:07:30","userStatus":1},{"id":1,"userName":"tom","userPasscode":"ed0de7252acf2980e677bacab01bde25","userEmail":"tom@example.com","userInsertTime":"2019-04-25 17:07:30","userUpdateTime":"2019-04-25 17:07:30","userStatus":1}]}
4.5 POST请求-文件上传
请求日志:
2019-05-16 20:16:56:569 [http-nio-8848-exec-7] INFO com.ljq.demo.springboot.web.acpect.LogAspect(LogAspect.java 67) -[AOP-LOG-START] requestMark: 3a4eb27e-c35b-4804-bda1-100c0a1b89d9 requestIP: 192.168.100.1 contentType:multipart/form-data; boundary=-e08loTIIPoPhChkhGqIWqy4J9HX7REn; charset=UTF-8 requestUrl: http://192.168.100.100:8848/api/demo/common/upload requestMethod: POST requestParams: zhTest = 德玛西亚;demoMapKey = demoMapValue;fileSize = 1163395;fileContentType = application/octet-stream;fieldName = file;fileOriginalName = 阿里巴巴Java开发手册(详尽版).pdf; targetClassAndMethod: com.ljq.demo.springboot.web.controller.CommonController#upload
返回参数:
response Code: 200 {"code":1000,"msg":"成功","data":null}
5 参考资料推荐
官方文档 HttpClient Quick Start
官方文档 HttpClient Examples
解决httpclient上传文件的时候中文文件名乱码的问题
6 Github 源码
Gtihub 源码地址 : https://github.com/Flying9001/springBootDemo