java 图片下载
工作中遇到图片下载,有时候成功,有时候失败;排查后发现 http 协议的下载成功,https 格式的下载不成功,考虑是因为服务器没有安全证书的原因。后面上面说直接去除掉 https 的安全校验
-
http 协议图片下载
-
去除 https 协议的安全校验
-
图片编码为 base64 字符串
-
只基于依赖 jdk 和 spring
/**
* @author
* @date 2023/11/29
*/
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.Base64Utils;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Objects;
/**
* 网络连接工具
*/
public class NetUtils {
/**
* 更具 url 下载图片,转成 base64字符串(只支持 http 和 https)
* @param url
* @return
* @throws IOException
*/
public static String downloadImgToBase64(String url) throws IOException, NoSuchAlgorithmException, KeyManagementException {
URLConnection connection = buildURLConnection(url);
return downloadImgToBase64(connection);
}
/**
* 下载图片,转成 base64字符串
* @param connection
* @return
* @throws IOException
*/
public static String downloadImgToBase64(URLConnection connection) throws IOException {
String base64Img = null;
if (Objects.isNull(connection)) {
return base64Img;
}
// 下载图片到内存。用字节数组接收
try (
InputStream inputStream = new BufferedInputStream(connection.getInputStream());
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
) {
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
byte[] byteArray = outputStream.toByteArray();
base64Img = Base64Utils.encodeToString(byteArray);
}
return base64Img;
}
/**
* 根据协议创建连接对象
* @param url
* @return
* @throws IOException
* @throws NoSuchAlgorithmException
* @throws KeyManagementException
*/
public static URLConnection buildURLConnection(String url) throws IOException, NoSuchAlgorithmException, KeyManagementException {
if (StringUtils.isBlank(url)) {
return null;
}
// 创建连接对象
URL urlObject = new URL(url);
String protocol = urlObject.getProtocol();
URLConnection connection = null;
if ("http".equals(protocol)) {
connection = buildHttpConnection(urlObject);
}else if ("https".equals(protocol)){
connection = buildUnsafeHttpsConnection(urlObject);
}
return connection;
}
/**
* 根据给定的url 建立http连接。如果是https 请求,忽略证书校验
* @param url
* @return
*/
public static HttpsURLConnection buildUnsafeHttpsConnection(URL url) throws IOException, NoSuchAlgorithmException, KeyManagementException {
if (Objects.isNull(url)) {
return null;
}
// 创建连接对象
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
// 忽略证书校验
connection.setHostnameVerifier((hostname,session) -> true);
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null,new TrustManager[]{new X509TrustManager() {
public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException {
}
public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
}
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[]{};
}
}}, new java.security.SecureRandom());
connection.setSSLSocketFactory(sslContext.getSocketFactory());
return connection;
}
/**
* 根据给定的url 建立http连接
* @param url
* @return
* @throws MalformedURLException
*/
public static HttpURLConnection buildHttpConnection(URL url) throws IOException {
if (ObjectUtils.isEmpty(url)) {
return null;
}
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
return connection;
}
}