一、导入HttpClient的maven坐标
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.13</version>
</dependency>
<!-- 用于文件上传,没有文件上传接口时可不添加 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.5.13</version>
</dependency>
二、封装工具类,发送请求
import com.alibaba.fastjson2.JSONObject;
import org.apache.http.*;
import org.apache.http.client.HttpClient;
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.client.methods.HttpRequestBase;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
public class HttpClintUtil {
/** 发送GET请求 */
public static JSONObject doGet(String url, Map<String, String> params, Map<String, String> headers) throws Exception {
HttpGet httpGet = null;
try {
String entity = encoderUrl(params);
url = url + entity;
HttpClient httpClient = getHttpClient(url);
httpGet = new HttpGet(url);
// 设置超时时间
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(30000).setConnectTimeout(30000).build();
httpGet.setConfig(requestConfig);
setHeader(headers, httpGet);
HttpResponse response = httpClient.execute(httpGet);
return getResultStr(response);
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
if (httpGet != null) {
httpGet.releaseConnection();
}
}
}
/** 发送POST请求 */
public static JSONObject doPost(String url, Map<String, String> params, Map<String, String> headers) throws Exception {
HttpPost httpPost = null;
try {
JSONObject jsonObject = new JSONObject();
for(Map.Entry<String, String> entry: params.entrySet()){
jsonObject.put(entry.getKey().toString(),entry.getValue().toString());
}
HttpClient httpClient = getHttpClient(url);
httpPost = new HttpPost(url);
httpPost.setHeader("Content-Type", "application/json");
// 设置超时时间
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(30000).setConnectTimeout(30000).build();
httpPost.setConfig(requestConfig);
setHeader(headers, httpPost);
setBody(httpPost, jsonObject);
HttpResponse response = httpClient.execute(httpPost);
return getResultStr(response);
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
if (httpPost != null) {
httpPost.releaseConnection();
}
}
}
// 解析响应结果
private static JSONObject getResultStr(HttpResponse response) throws Exception {
if (response == null) {
throw new Exception("响应信息为空");
}
int responseCode = response.getStatusLine().getStatusCode();
if (responseCode == HttpStatus.SC_OK) {
HttpEntity resEntity = response.getEntity();
String resStr = EntityUtils.toString(resEntity, Consts.UTF_8);
return parseObject(resStr);
} else if (HttpStatus.SC_NOT_FOUND == responseCode) {
//找不到引擎地址
throw new Exception("找不到引擎地址,状态码:" + responseCode);
} else if (HttpStatus.SC_INTERNAL_SERVER_ERROR == responseCode) {
//请求引擎500异常
throw new Exception("服务器内部异常,状态码:" + responseCode);
} else {
//httpCode状态码[{0}]
throw new Exception("请求异常,状态码:" + responseCode);
}
}
// 将响应结果转换为JSONObject对象
private static JSONObject parseObject(String jsonStr) throws Exception {
try {
return JSONObject.parseObject(jsonStr);
} catch (Exception e) {
throw new Exception("非标准的JSON字符串:\r\n" + jsonStr);
}
}
// 设置请求头
private static void setHeader(Map<String, String> headers, HttpRequestBase requestBase) {
if (headers == null) return;
for (Map.Entry<String, String> entry : headers.entrySet()) {
requestBase.addHeader(entry.getKey(), entry.getValue());
}
}
// 设置请求体
private static void setBody(HttpPost httpPost, JSONObject paramBody) {
httpPost.setEntity(new StringEntity(paramBody.toString(), Consts.UTF_8));
}
// 拼接参数方式一
private static String encoderUrl(Map<String, String> params) {
StringJoiner sb = new StringJoiner("&","?","");
params.forEach((key, value) -> {
try {
sb.add(key + "=" + URLEncoder.encode(value.toString(), "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
});
return sb.toString();
}
// 拼接参数方式二
private static String encoderUrl(String url, Map<String, String> params) {
StringBuilder paramsBuilder = new StringBuilder(url);
if (params != null) {
if (!url.contains("?")) {
paramsBuilder.append("?");
}
List<NameValuePair> list = new ArrayList<>();
params.forEach((key, value) -> list.add(new BasicNameValuePair(key.toString(), value.toString())));
try {
paramsBuilder.append(EntityUtils.toString(new UrlEncodedFormEntity(list, StandardCharsets.UTF_8)));
} catch (IOException e) {
e.printStackTrace();
}
}
return paramsBuilder.toString();
}
// 获取HttpClient实例
public static HttpClient getHttpClient(String url) throws Exception {
if (url.startsWith("https://")) {
return new HTTPSTrustClient().init();
} else {
return HttpClientBuilder.create().build();
}
}
}
注意:如果是https请求,添加以下内容跳过证书验证
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
public class HTTPSTrustClient extends HTTPSClient {
@Override
public void prepareCertificate() throws Exception {
// 跳过证书验证
SSLContext ctx = SSLContext.getInstance("TLS");
X509TrustManager tm = new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
};
// 设置成已信任的证书
ctx.init(null, new TrustManager[] { tm }, null);
this.connectionSocketFactory = new SSLConnectionSocketFactory(ctx, NoopHostnameVerifier.INSTANCE);
}
}
abstract class HTTPSClient extends HttpClientBuilder {
private CloseableHttpClient client;
protected ConnectionSocketFactory connectionSocketFactory;
/**
* 初始化HTTPSClient
*/
public CloseableHttpClient init() throws Exception {
this.prepareCertificate();
this.regist();
return this.client;
}
/**
* 准备证书验证
*/
public abstract void prepareCertificate() throws Exception;
/**
* 注册协议和端口, 此方法也可以被子类重写
*/
protected void regist() {
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.INSTANCE)
.register("https", this.connectionSocketFactory)
.build();
PoolingHttpClientConnectionManager connManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(30000).setConnectTimeout(30000).build();
this.client = HttpClients.custom().setDefaultRequestConfig(requestConfig).setConnectionManager(connManager).build();
}
}
三、调用接口下载文件,返回文件的输入流
/** 发送GET请求下载文件 */
public class HttpClintUtil {
public static InputStream doGetDownload(String url, Map<String, String> params, Map<String, String> headers) throws Exception {
HttpGet httpGet = null;
try {
String entity = encoderUrl(params);
url = url + entity;
HttpClient httpClient = getHttpClient(url);
httpGet = new HttpGet(url);
// 设置超时时间
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(30000).setConnectTimeout(30000).build();
httpGet.setConfig(requestConfig);
setHeader(headers, httpGet);
HttpResponse response = httpClient.execute(httpGet);
return getRespInputStream(response);
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
if (httpGet != null) {
httpGet.releaseConnection();
}
}
}
// 解析响应结果
private static InputStream getRespInputStream(HttpResponse response) throws Exception {
if (response == null) {
throw new Exception("响应信息为空");
}
int responseCode = response.getStatusLine().getStatusCode();
if (responseCode == HttpStatus.SC_OK) {
HttpEntity resEntity = response.getEntity();
return resEntity.getContent();
} else if (HttpStatus.SC_NOT_FOUND == responseCode) {
//找不到引擎地址
throw new Exception("找不到引擎地址,状态码:" + responseCode);
} else if (HttpStatus.SC_INTERNAL_SERVER_ERROR == responseCode) {
//请求引擎500异常
throw new Exception("服务器内部异常,状态码:" + responseCode);
} else {
//httpCode状态码[{0}]
throw new Exception("请求异常,状态码:" + responseCode);
}
}
// 设置请求头
private static void setHeader(Map<String, String> headers, HttpRequestBase requestBase) {
if (headers == null) return;
for (Map.Entry<String, String> entry : headers.entrySet()) {
requestBase.addHeader(entry.getKey(), entry.getValue());
}
}
// 拼接参数
private static String encoderUrl(Map<String, String> params) {
StringJoiner sb = new StringJoiner("&","?","");
params.forEach((key, value) -> {
try {
sb.add(key + "=" + URLEncoder.encode(value.toString(), "UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
});
return sb.toString();
}
}
四、调用接口上传文件
public class HttpClintUtil {
/** 发送POST请求 上传文件 */
public static JSONObject doPostUploadFile(String url, Map<String, String> params, Map<String, String> headers, File file) throws Exception {
HttpPost httpPost = null;
try {
MultipartEntityBuilder builder = MultipartEntityBuilder.create().setMode(HttpMultipartMode.RFC6532);
builder.setCharset(StandardCharsets.UTF_8);
builder.addBinaryBody("file", file, ContentType.MULTIPART_FORM_DATA, file.getName());
// 1.添加文件
// builder.addBinaryBody("file", file);
// 2.使用字节流
// builder.addBinaryBody("file", Files.readAllBytes(file.toPath()), ContentType.APPLICATION_OCTET_STREAM, file.getName());
// 3.使用FileBody也行
// builder.addPart("file",new FileBody(file));
// 4.使用InputStream
// builder.addBinaryBody("file", new FileInputStream(file), ContentType.APPLICATION_OCTET_STREAM, file.getName());
// 添加参数
if (params != null) {
for (String key : params.keySet()) {
builder.addTextBody(key, params.get(key));
}
}
HttpClient httpClient = getHttpClient(url);
httpPost = new HttpPost(url);
RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(30000).setConnectTimeout(30000).build();
httpPost.setConfig(requestConfig);
httpPost.setEntity(builder.build());
setHeader(headers, httpPost);
HttpResponse response = httpClient.execute(httpPost);
return getResultStr(response);
} catch (Exception e) {
e.printStackTrace();
throw e;
} finally {
if (httpPost != null) {
httpPost.releaseConnection();
}
}
}
// 解析响应结果
private static JSONObject getResultStr(HttpResponse response) throws Exception {
if (response == null) {
throw new Exception("响应信息为空");
}
int responseCode = response.getStatusLine().getStatusCode();
if (responseCode == HttpStatus.SC_OK) {
HttpEntity resEntity = response.getEntity();
String resStr = EntityUtils.toString(resEntity, Consts.UTF_8);
return parseObject(resStr);
} else if (HttpStatus.SC_NOT_FOUND == responseCode) {
//找不到引擎地址
throw new Exception("找不到引擎地址,状态码:" + responseCode);
} else if (HttpStatus.SC_INTERNAL_SERVER_ERROR == responseCode) {
//请求引擎500异常
throw new Exception("服务器内部异常,状态码:" + responseCode);
} else {
//httpCode状态码[{0}]
throw new Exception("请求异常,状态码:" + responseCode);
}
}
// 设置请求头
private static void setHeader(Map<String, String> headers, HttpRequestBase requestBase) {
if (headers == null) return;
for (Map.Entry<String, String> entry : headers.entrySet()) {
requestBase.addHeader(entry.getKey(), entry.getValue());
}
}
}