<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>HttpClient</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <slf4j.version>1.7.36</slf4j.version> <log4j.version>1.2.17</log4j.version> <httpclient.version>4.5.14</httpclient.version> <maven.compiler.plugin.version>3.6.1</maven.compiler.plugin.version> </properties> <dependencies> <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> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-reload4j</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>${log4j.version}</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>${maven.compiler.plugin.version}</version> </plugin> </plugins> </build> </project>
package com.chenwc.httpclient; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.ssl.NoopHostnameVerifier; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.TrustStrategy; 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.entity.mime.content.FileBody; import org.apache.http.entity.mime.content.StringBody; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.message.BasicNameValuePair; import org.apache.http.ssl.SSLContextBuilder; import org.apache.http.util.EntityUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLContext; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.nio.charset.StandardCharsets; import java.security.KeyManagementException; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.util.*; /** * HttpClient 网络请求工具类 * @author chenwc * @date 2023/5/17 22:25 */ public class RestMock<K, V> { private final static Logger log = LoggerFactory.getLogger(RestMock.class); /** * Socket 超时时间 */ private final static Integer SocketTimeout = 20000; /** * 连接超时时间 */ private final static Integer ConnectTimeout = 20000; /** * 发起 post 请求,提交文件和表单 * 文件表单格式:form-data; name="file"; filename="xxxxxxxxxx" * 表单格式:form-data; name="key1" * 单格式:form-data; name="key2" * * @param urlStr http请求的地址 * @param headerMap 头信息 * @param formBodyMap 表单参数 * @param file 文件 * @return 响应信息 */ public static String sendPostByFileAndFormBody(String urlStr, Map<String, String> headerMap, Map<String, String> formBodyMap, File file) { log.info("url----------------> " + urlStr); String sResponse = null; long t1 = System.currentTimeMillis(); CloseableHttpClient httpClient = null; try { // 创建HttpClient httpClient = getHttpClient(urlStr.startsWith("https"));; HttpPost httpPost = getHttpPost(urlStr, headerMap); MultipartEntityBuilder builder = MultipartEntityBuilder.create(); //请求的编码格式 builder.setCharset(StandardCharsets.UTF_8); //浏览器兼容模式 builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE); FileBody fileBody = new FileBody(file); builder.addPart("file", fileBody); //添加表单参数 if (null != formBodyMap && !formBodyMap.isEmpty()){ for (String key : formBodyMap.keySet()) { StringBody strBody = new StringBody(formBodyMap.get(key), ContentType.MULTIPART_FORM_DATA.withCharset(StandardCharsets.UTF_8)); builder.addPart(key, strBody); } } HttpEntity entity = builder.build(); httpPost.setEntity(entity); // 执行提交 HttpResponse response = httpClient.execute(httpPost); sResponse = getResponseMessage(response); long t2 = System.currentTimeMillis(); log.info("----------请求总用时:{} 秒", ((t2 - t1) / 1000.0)); } catch (Exception ex) { ex.printStackTrace(); } finally { try { if (null != httpClient) { httpClient.close(); } } catch (IOException e) { e.printStackTrace(); } } return sResponse; } /** * 发起 post 请求,提交表单 * 表单格式:form-data; name="key1" * 单格式:form-data; name="key2" * * @param urlStr http请求的地址 * @param headerMap 头信息 * @param formBodyMap 表单参数 * @return 响应信息 */ public static String sendPostByFormBody(String urlStr, Map<String, String> headerMap, Map<String, String> formBodyMap) { log.info("url----------------> " + urlStr); String sResponse = null; long t1 = System.currentTimeMillis(); CloseableHttpClient httpClient = null; try { // 创建HttpClient httpClient = getHttpClient(urlStr.startsWith("https"));; HttpPost httpPost = getHttpPost(urlStr, headerMap); StringEntity entity = getFormBodyEntity(formBodyMap); if (null != entity){ httpPost.setEntity(entity); } // 执行提交 HttpResponse response = httpClient.execute(httpPost); sResponse = getResponseMessage(response); long t2 = System.currentTimeMillis(); log.info("----------请求总用时:{} 秒", ((t2 - t1) / 1000.0)); } catch (Exception ex) { ex.printStackTrace(); } finally { try { if (null != httpClient) { httpClient.close(); } } catch (IOException e) { e.printStackTrace(); } } return sResponse; } /** * 发起 post 请求,带有请求体 * * @param urlStr http请求的地址 * @param headerMap 头信息 * @param body 请求体 * @return 响应信息 */ public static String sendPostByBody(String urlStr, Map<String, String> headerMap, String body) { log.info("url----------------> " + urlStr); String sResponse = null; long t1 = System.currentTimeMillis(); CloseableHttpClient httpClient = null; try { // 创建HttpClient httpClient = getHttpClient(urlStr.startsWith("https"));; HttpPost httpPost = getHttpPost(urlStr, headerMap); if (null != body && !body.isEmpty()){ StringEntity entity = new StringEntity(body, StandardCharsets.UTF_8); httpPost.setEntity(entity); } // 执行提交 HttpResponse response = httpClient.execute(httpPost); sResponse = getResponseMessage(response); long t2 = System.currentTimeMillis(); log.info("----------请求总用时:{} 秒", ((t2 - t1) / 1000.0)); } catch (Exception ex) { ex.printStackTrace(); } finally { try { if (null != httpClient) { httpClient.close(); } } catch (IOException e) { e.printStackTrace(); } } return sResponse; } /** * 发起 post 请求 * * @param urlStr http请求的地址 * @param headerMap 头信息 * @return 响应信息 */ public static String sendPost(String urlStr, Map<String, String> headerMap) { return sendPostByBody(urlStr, headerMap, null); } /** * 获取HttpPost * @param url url * @param header 头信息 * @return HttpPost */ private static HttpPost getHttpPost(String url, Map<String, String> header) throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException { HttpPost httpPost = new HttpPost(url); httpPost.setConfig(getRequestConfig()); //装入头信息 if (null != header && !header.isEmpty()) { for (String key : header.keySet()) { httpPost.addHeader(key, header.get(key)); } } return httpPost; } /** * 发起 get 请求,带有请求参数 * * @param urlStr http请求的地址 * @param headerMap 头信息 * @param parameterMap 请求参数 * @return 响应信息 */ public static String sendGetByParameter(String urlStr, Map<String, String> headerMap, Map<String, String> parameterMap) { log.info("url----------------> " + urlStr); String sResponse = null; long t1 = System.currentTimeMillis(); CloseableHttpClient httpClient = null; try { // 创建HttpClient httpClient = getHttpClient(urlStr.startsWith("https")); HttpGet httpGet = getHttpGet(urlStr, headerMap, parameterMap); // 执行提交 HttpResponse response = httpClient.execute(httpGet); sResponse = getResponseMessage(response); long t2 = System.currentTimeMillis(); log.info("----------请求总用时:{} 秒", ((t2 - t1) / 1000.0)); } catch (Exception ex) { ex.printStackTrace(); } finally { try { if (null != httpClient) { httpClient.close(); } } catch (IOException e) { e.printStackTrace(); } } return sResponse; } /** * 发起 get 请求 * * @param urlStr http请求的地址 * @param headerMap 头信息 * @return 响应信息 */ public static String sendGet(String urlStr, Map<String, String> headerMap) { return sendGetByParameter(urlStr, headerMap, new HashMap<>()); } /** * 使用get请求下载文件 * * @param urlStr url * @param filePath 文件保存路径 */ public static void downloadFileByGet(String urlStr, String filePath) { log.info("url----------------> " + urlStr); long t1 = System.currentTimeMillis(); CloseableHttpClient httpClient = null; InputStream inputStream = null; FileOutputStream fos = null; ByteArrayOutputStream bos = null; File fileExists = new File(filePath); try { if (!fileExists.exists()) { if (!mkdirParents(fileExists)) { log.info("创建父级目录失败!"); return; } if (!fileExists.createNewFile()) { log.info("创建文件: {} 失败!", filePath); return; } } // 创建HttpClient httpClient = getHttpClient(urlStr.contains("https")); HttpGet httpGet = getHttpGet(urlStr, new HashMap<>(), new HashMap<>()); // 执行提交 HttpResponse response = httpClient.execute(httpGet); int statusCode = response.getStatusLine().getStatusCode(); log.info("-----------------状态码--------------"); log.info("---------------------->statusCode: " + statusCode); if (statusCode == 200) { // 得到实体 HttpEntity entity = response.getEntity(); log.info("开始下载文件...."); inputStream = entity.getContent(); byte[] buffer = new byte[1024]; int len = 0; bos = new ByteArrayOutputStream(); while ((len = inputStream.read(buffer)) != -1) { bos.write(buffer, 0, len); } byte[] getData = bos.toByteArray(); File file = new File(filePath); fos = new FileOutputStream(file); fos.write(getData); log.info("下载文件成功!"); log.info("文件保存到:{}", filePath); } long t2 = System.currentTimeMillis(); log.info("----------请求总用时:{} 秒", ((t2 - t1) / 1000.0)); } catch (Exception e) { e.printStackTrace(); } finally { try { if (null != httpClient) { httpClient.close(); } if (null != inputStream) { inputStream.close(); } if (null != fos) { fos.close(); } if (null != bos) { bos.close(); } } catch (IOException e) { e.printStackTrace(); } } } /** * 获取HttpGet * @param url url * @param header 头信息 * @param parameterMap 请求参数 * @return HttpGet */ private static HttpGet getHttpGet(String url, Map<String, String> header, Map<String, String> parameterMap) throws UnsupportedEncodingException, NoSuchAlgorithmException, KeyStoreException, KeyManagementException { String paramerterString = generateGetParameter(parameterMap); if (null != parameterMap && !parameterMap.isEmpty()) { if (url.endsWith("?")) { url = url + paramerterString; } else { url = url + "?" + paramerterString; } } log.info("getUrl---------------->{}", url); HttpGet httpGet= new HttpGet(url); httpGet.setConfig(getRequestConfig()); //装入头信息 if (null != header && !header.isEmpty()) { for (String key : header.keySet()) { httpGet.addHeader(key, header.get(key)); } } return httpGet; } /** * 根据表单 map 转换成 StringEntity * @param formBodyMap 表单 map * @return StringEntity */ private static StringEntity getFormBodyEntity(Map<String, String> formBodyMap){ StringEntity entity = null; List<NameValuePair> kvList = new ArrayList<>(); if (null != formBodyMap && !formBodyMap.isEmpty()){ for (String key : formBodyMap.keySet()) { kvList.add(new BasicNameValuePair(key, formBodyMap.get(key))); } } if (!kvList.isEmpty()){ // 包装成一个Entity对象 entity = new UrlEncodedFormEntity(kvList, StandardCharsets.UTF_8); } return entity; } /** * 获取 http 响应信息 * @param response HttpResponse * @return 响应信息 * @throws IOException IOException */ private static String getResponseMessage(HttpResponse response) throws IOException { String sResponse = null; int statusCode = response.getStatusLine().getStatusCode(); log.info("-----------------状态码--------------"); log.info("---------------------->statusCode: " + statusCode); HttpEntity responseEntity = response.getEntity(); //响应状态码200 if (null != responseEntity) { // 将响应的内容转换成字符串 sResponse = EntityUtils.toString(responseEntity, StandardCharsets.UTF_8); log.info("sResponse:--------------->" + sResponse); } else { log.info("响应信息为空!"); } return sResponse; } /** * 获取 CloseableHttpClient * @param isDeceive 是否绕过SSL * @return CloseableHttpClient */ private static CloseableHttpClient getHttpClient(boolean isDeceive) throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException { CloseableHttpClient httpClient; if (isDeceive){ // 信任所有 SSLContext sslContext = new SSLContextBuilder().loadTrustMaterial(null, (TrustStrategy) (chain, authType) -> true).build(); HostnameVerifier hostnameVerifier = NoopHostnameVerifier.INSTANCE; SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext, hostnameVerifier); httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build(); } else { httpClient = HttpClients.createDefault(); } return httpClient; } /** * 获取 http 请求配置 * @return http 请求配置 */ private static RequestConfig getRequestConfig() { RequestConfig.Builder requestConfigBuilder = RequestConfig.custom(); //设置超时时间,这个是httpclient 4.3版本之后的设置方法 requestConfigBuilder.setConnectTimeout(ConnectTimeout); requestConfigBuilder.setSocketTimeout(SocketTimeout); return requestConfigBuilder.build(); } /** * 根据map生成get请求参数,格式 A=a&B=b * @param parameterMap 请求参数map * @return get请求参数url */ private static String generateGetParameter(Map<String, String> parameterMap) throws UnsupportedEncodingException { StringBuilder sb = new StringBuilder(); if (null != parameterMap) { Set<String> keySet = parameterMap.keySet(); int index = 1; for (String key : keySet) { String value = URLEncoder.encode(parameterMap.get(key), String.valueOf(StandardCharsets.UTF_8)); if(index == keySet.size()) { sb.append(key).append("=").append(value); } else { sb.append(key).append("=").append(value).append("&"); } index++; } } return sb.toString(); } /** * 判断文件的父级目录是否存在,不存在则创建 * * @param file 文件 * @return true 父级目录存在或创建父级目录成功, false创建父级目录失败 */ public static boolean mkdirParents(File file) { if (!file.getParentFile().exists()) { return file.getParentFile().mkdirs(); } else { return true; } } }
log4j.rootLogger=info,stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.out log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d %-5p %-5L --- [%-5t] %-10c : %m %n
log4j-1.2.17.jar
slf4j-api-1.7.36.jar
slf4j-log4j12-1.7.7.jar
httpmime-4.5.14.jar
httpcore-4.4.14.jar
httpclient-4.5.14.jar
commons-logging-1.2.jar
commons-codec-1.11.jar