Java 调用 Https 请求(2021/05/11)

Java 调用 Https 请求(2021/05/11)

更新时间 内容
2021/03/03 自定义请求工具类实现
2021/05/11 使用 Hutool 工具包实现

文章目录

      • Java 调用 Https 请求(2021/05/11)
        • 1. 概述
        • 2. 实现
          • 2.1 HttpsURLConnection 实现
          • 2.2 Hutool 工具包实现
        • 3. 总结

1. 概述

在日常开发中,有时会在程序中进行一些接口的调用,对于 Http 请求,可以使用 Apache 的 HttpClient 或者 Java 原生的 HttpURLConnection 来实现,但对于 Https 请求,由于需要对证书进行验证,无法直接进行请求。本文记录了一下在 Java 中调用 Https 请求的方法,便于后续使用。

2. 实现

2.1 HttpsURLConnection 实现

该方法为笔者一开始查找资料自己封装的方法,不是特别完善;后来发现了 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;
    }
}
2.2 Hutool 工具包实现

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 官方文档。

3. 总结

通过 Java 原生的 HttpsURLConnection 来实现不需要依赖任何的第三方包,也比较灵活,但需要自己编写较多代码来实现,也容易出现异常;而通过 Hutool 工具包来实现,虽然需要导入第三方 Jar 包依赖,但方便灵活,稳定性也较好。因此,从笔者自己体验来看,推荐使用后者。

相关链接:

  • Hutool 官网:https://www.hutool.cn/
  • Hutool 参考文档:https://www.hutool.cn/docs/#/
  • Hutool API 文档:https://apidoc.gitee.com/dromara/hutool/

你可能感兴趣的:(Java,java,https)