更新时间 | 内容 |
---|---|
2021/03/03 | 自定义请求工具类实现 |
2021/05/11 | 使用 Hutool 工具包实现 |
在日常开发中,有时会在程序中进行一些接口的调用,对于 Http 请求,可以使用 Apache 的 HttpClient
或者 Java 原生的 HttpURLConnection
来实现,但对于 Https 请求,由于需要对证书进行验证,无法直接进行请求。本文记录了一下在 Java 中调用 Https 请求的方法,便于后续使用。
该方法为笔者一开始查找资料自己封装的方法,不是特别完善;后来发现了 Hutool 工具包中封装了对 Https 请求的调用(关于 Hutool 工具包会在下文介绍),而且灵活度也比较高,因此推荐使用 Hutool 工具包。
该方法通过 Java 原生的 HttpsURLConnection
来实现,优点为不需要依赖任何第三方包,缺点为需要自己实现编写较多代码。下面展示一下 GET
请求的实现,其他请求方法通过setRequestMethod
方法设置请求方法来实现,例如: httpsURLConnection.setRequestMethod("POST")
。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.net.ssl.*;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
/**
* HTTPS请求工具类
*
* @author xiaoqqya
* @version 2021/03/03
*/
public class HttpsClientUtil {
private static final Logger logger = LoggerFactory.getLogger(HttpsClientUtil.class);
/**
* 封装HTTPS GET请求
*
* @param urlStr 请求地址
* @return 请求结果
* @author xiaoqqya
*/
public static byte[] httpsGet(String urlStr) {
InputStream input;
try {
URL url = new URL(urlStr);
boolean useHttps = urlStr.startsWith("https");
if (useHttps) {
HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url.openConnection();
HostnameVerifier ignoreHostnameVerifier = new MyHostnameVerifier();
SSLContext sslContext = SSLContext.getInstance("SSL", "SunJSSE");
sslContext.init(null, new TrustManager[]{new MyX509TrustManager()}, new SecureRandom());
httpsURLConnection.setConnectTimeout(10000);
httpsURLConnection.setReadTimeout(20000);
httpsURLConnection.setHostnameVerifier(ignoreHostnameVerifier);
httpsURLConnection.setSSLSocketFactory(sslContext.getSocketFactory());
httpsURLConnection.connect();
input = httpsURLConnection.getInputStream();
} else {
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setConnectTimeout(10000);
httpURLConnection.setReadTimeout(20000);
httpURLConnection.connect();
input = httpURLConnection.getInputStream();
}
return toByteArray(input);
} catch (Exception e) {
logger.error(e.getMessage(), e);
return null;
}
}
/**
* 将输入流转换成字节数组
*
* @param input 输入流对象
* @return 字节数组
* @throws IOException IO异常
* @author xiaoqqya
*/
private static byte[] toByteArray(InputStream input) throws IOException {
ByteArrayOutputStream output = new ByteArrayOutputStream();
byte[] buffer = new byte[4096];
int n;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
}
return output.toByteArray();
}
}
/**
* 实现X509TrustManager接口,信任所有
*
* @author xiaoqqya
* @version 2021/03/03
*/
class MyX509TrustManager implements X509TrustManager {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
}
/**
* 实现HostnameVerifier接口,忽略HTTPS主机验证
*
* @author xiaoqqya
* @version 2021/03/03
*/
class MyHostnameVerifier implements HostnameVerifier {
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
}
Hutool 是一个小而全的 Java 工具类库,通过静态方法封装,降低相关 API 的学习成本,提高工作效率,使 Java 拥有函数式语言般的优雅,让 Java 语言也可以“甜甜的”。
1. 导入 Maven 依赖
如果你的项目不是一个 Maven 项目,那么请自行下载 Jar 包导入依赖。
Hutool 提供了一个包含所有模块的 Jar 包 hutool-all
,也为每个子模块提供了单独的 Jar 包,例如此处用到的 Http 模块 hutool-http
,在使用时二者导入一个即可,因为 Hutool 中还提供了很多其他的优秀工具类,所以笔者此处选择导入所有模块。
<dependency>
<groupId>cn.hutoolgroupId>
<artifactId>hutool-allartifactId>
<version>5.6.5version>
dependency>
<dependency>
<groupId>cn.hutoolgroupId>
<artifactId>hutool-httpartifactId>
<version>5.6.5version>
dependency>
2. 调用 Get、Post 请求
针对常用的 Get、Post 请求,Hutool 在 HttpUtil 类中封装了两个方法。
Get 请求例子:
// 最简单的HTTP请求,可以自动通过header等信息判断编码,不区分HTTP和HTTPS
String result1= HttpUtil.get("https://www.baidu.com");
// 当无法识别页面编码的时候,可以自定义请求页面的编码
String result2= HttpUtil.get("https://www.baidu.com", CharsetUtil.CHARSET_UTF_8);
//可以单独传入http参数,这样参数会自动做URL编码,拼接在URL中
HashMap<String, Object> paramMap = new HashMap<>();
paramMap.put("city", "北京");
String result3= HttpUtil.get("https://www.baidu.com", paramMap);
Post 请求例子:
HashMap<String, Object> paramMap = new HashMap<>();
paramMap.put("city", "北京");
String result= HttpUtil.post("https://www.baidu.com", paramMap);
文件上传:
HashMap<String, Object> paramMap = new HashMap<>();
//文件上传只需将参数中的键指定(默认file),值设为文件对象即可,对于使用者来说,文件上传与普通表单提交并无区别
paramMap.put("file", FileUtil.file("D:\\face.jpg"));
String result= HttpUtil.post("https://www.baidu.com", paramMap);
文件下载:
String fileUrl = "http://mirrors.sohu.com/centos/7.3.1611/isos/x86_64/CentOS-7-x86_64-DVD-1611.iso";
//将文件下载后保存在E盘,返回结果为下载文件大小
long size = HttpUtil.downloadFile(fileUrl, FileUtil.file("e:/"));
System.out.println("Download size: " + size);
3. HttpRequest
为了能够更加灵活的操作 Http 请求,Hutool 还提供了 HttpRequest
类,使用该类可以通过链式很方便的指定请求头、表单等信息。
Post 请求例子:
//链式构建请求
String result2 = HttpRequest.post(url)
.header(Header.USER_AGENT, "Hutool http")//头信息,多个头信息多次调用此方法即可
.form(paramMap)//表单内容
.timeout(20000)//超时,毫秒
.execute().body();
通过 HttpRequest
类还可以设置一些验证信息等,具体可查阅 Hutool 官方文档。
通过 Java 原生的 HttpsURLConnection
来实现不需要依赖任何的第三方包,也比较灵活,但需要自己编写较多代码来实现,也容易出现异常;而通过 Hutool 工具包来实现,虽然需要导入第三方 Jar 包依赖,但方便灵活,稳定性也较好。因此,从笔者自己体验来看,推荐使用后者。
相关链接: