|
|
@@ -0,0 +1,292 @@
|
|
|
+package com.kingdee.eas.custom.esign.util;
|
|
|
+
|
|
|
+import okhttp3.*;
|
|
|
+import org.apache.commons.io.IOUtils;
|
|
|
+
|
|
|
+import java.io.*;
|
|
|
+import java.util.Map;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 下载文件工具类
|
|
|
+ * description: Downloader <br>
|
|
|
+ * date: 18/11/2025 下午 4:25 <br>
|
|
|
+ * author: lhbj <br>
|
|
|
+ * version: 1.0 <br>
|
|
|
+ */
|
|
|
+public class DownloaderUtil {
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 异步接口
|
|
|
+ */
|
|
|
+ public interface Listener {
|
|
|
+ void onSuccess(String data);
|
|
|
+ void onError(String error);
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 异步接口
|
|
|
+ */
|
|
|
+ public interface CallbackBytes {
|
|
|
+ void onSuccess(byte[] bytes);
|
|
|
+ void onError(String error);
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 异步
|
|
|
+ * 进度条监听类接口
|
|
|
+ */
|
|
|
+ public interface ProgressListener extends Listener{
|
|
|
+ void onProgress(int percentage, long downloaded, long total);
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 异步下载
|
|
|
+ * 由于返回byte数组,使用时需要注意下载文件大小,不能过大,不能多线程调用,以规避内存风险。
|
|
|
+ * @param url
|
|
|
+ * @param callback 回调实现类
|
|
|
+ */
|
|
|
+ public static void downloadFileToByteArrayAsync(String url,
|
|
|
+ final CallbackBytes callback) {
|
|
|
+ downloadFileToByteArrayAsync(url,null,callback);
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 异步下载
|
|
|
+ * 由于返回byte数组,使用时需要注意下载文件大小,不能过大,不能多线程调用,以规避内存风险。
|
|
|
+ * @param url
|
|
|
+ * @param headers 请求头
|
|
|
+ * @param callback 回调实现类
|
|
|
+ */
|
|
|
+ public static void downloadFileToByteArrayAsync(String url,Map<String, String> headers,
|
|
|
+ final CallbackBytes callback) {
|
|
|
+ OkHttpClient client = new OkHttpClient();
|
|
|
+ Request request = new Request.Builder()
|
|
|
+ .url(url)
|
|
|
+ .build();
|
|
|
+
|
|
|
+ client.newCall(request).enqueue(new Callback() {
|
|
|
+ @Override
|
|
|
+ public void onFailure(Call call, IOException e) {
|
|
|
+ callback.onError(e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onResponse(Call call, Response response) throws IOException {
|
|
|
+ if (!response.isSuccessful()) {
|
|
|
+ callback.onError("HTTP " + response.code());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ InputStream inputStream = null;
|
|
|
+ try {
|
|
|
+
|
|
|
+ ResponseBody body=response.body();
|
|
|
+ long contentLength =body.contentLength();
|
|
|
+
|
|
|
+ inputStream = body.byteStream();
|
|
|
+ callback.onSuccess(IOUtils.toByteArray(inputStream));
|
|
|
+ } catch (Exception e) {
|
|
|
+ callback.onError("文件保存失败: " + e.getMessage());
|
|
|
+ } finally {
|
|
|
+ closeQuietly(inputStream);
|
|
|
+
|
|
|
+ if (response != null) {
|
|
|
+ response.close();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 进度条下载
|
|
|
+ * @param url
|
|
|
+ * @param outputPath 保存下载文件地址
|
|
|
+ * @param listener 进度条监听类接口
|
|
|
+ */
|
|
|
+ public static void downloadWithProgress(String url, String outputPath,
|
|
|
+ final ProgressListener listener) {
|
|
|
+ downloadWithProgress(url,outputPath,null,listener);
|
|
|
+ }
|
|
|
+ public static void downloadWithProgress(String url, String outputPath,Map<String, String> headers,
|
|
|
+ final ProgressListener listener) {
|
|
|
+ OkHttpClient client = new OkHttpClient();
|
|
|
+ Request request = new Request.Builder()
|
|
|
+ .url(url)
|
|
|
+ .build();
|
|
|
+
|
|
|
+ client.newCall(request).enqueue(new Callback() {
|
|
|
+ @Override
|
|
|
+ public void onFailure(Call call, IOException e) {
|
|
|
+ listener.onError(e.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public void onResponse(Call call, Response response) throws IOException {
|
|
|
+ if (!response.isSuccessful()) {
|
|
|
+ listener.onError("HTTP " + response.code());
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ long contentLength = response.body().contentLength();
|
|
|
+ InputStream inputStream = null;
|
|
|
+ FileOutputStream outputStream = null;
|
|
|
+
|
|
|
+ try {
|
|
|
+ inputStream = response.body().byteStream();
|
|
|
+ File file = new File(outputPath);
|
|
|
+ outputStream = new FileOutputStream(file);
|
|
|
+
|
|
|
+ byte[] buffer = new byte[8192];
|
|
|
+ int bytesRead;
|
|
|
+ long totalBytesRead = 0;
|
|
|
+
|
|
|
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
|
|
|
+ outputStream.write(buffer, 0, bytesRead);
|
|
|
+ totalBytesRead += bytesRead;
|
|
|
+
|
|
|
+ // 更新进度
|
|
|
+ if (contentLength > 0) {
|
|
|
+ int progress = (int) (totalBytesRead * 100 / contentLength);
|
|
|
+ listener.onProgress(progress, totalBytesRead, contentLength);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ listener.onSuccess(file.getAbsolutePath());
|
|
|
+
|
|
|
+ } catch (Exception e) {
|
|
|
+ listener.onError("文件保存失败: " + e.getMessage());
|
|
|
+ } finally {
|
|
|
+ closeQuietly(inputStream);
|
|
|
+ closeQuietly(outputStream);
|
|
|
+ if (response != null) {
|
|
|
+ response.close();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 下载文件到byte数组
|
|
|
+ * 由于返回byte数组,使用时需要注意下载文件大小,不能过大,不能多线程调用,以规避内存风险。
|
|
|
+ * @param url
|
|
|
+ * @return
|
|
|
+ * @throws IOException
|
|
|
+ */
|
|
|
+ public static byte[] downloadFileToByteArray(String url) throws IOException {
|
|
|
+ return downloadFileToByteArray(url,null);
|
|
|
+ }
|
|
|
+ /**
|
|
|
+ * 携带header下载文件到byte数组
|
|
|
+ * 由于返回byte数组,使用时需要注意下载文件大小,不能过大,不能多线程调用,以规避内存风险。
|
|
|
+ * @param url
|
|
|
+ * @param headers 请求头
|
|
|
+ * @return
|
|
|
+ * @throws IOException
|
|
|
+ */
|
|
|
+ public static byte[] downloadFileToByteArray(String url, Map<String, String> headers) throws IOException {
|
|
|
+ OkHttpClient client = new OkHttpClient.Builder()
|
|
|
+ .connectTimeout(240, TimeUnit.SECONDS)
|
|
|
+ .readTimeout(240, TimeUnit.SECONDS)
|
|
|
+ .writeTimeout(240, TimeUnit.SECONDS)
|
|
|
+ .retryOnConnectionFailure(true)
|
|
|
+ .build();
|
|
|
+ Request.Builder requestBuilder = new Request.Builder().url(url);
|
|
|
+ // 添加自定义请求头
|
|
|
+ if (headers != null) {
|
|
|
+ for (Map.Entry<String, String> entry : headers.entrySet()) {
|
|
|
+ requestBuilder.addHeader(entry.getKey(), entry.getValue());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Request request = requestBuilder.build();
|
|
|
+ Response response = null;
|
|
|
+ InputStream inputStream = null;
|
|
|
+ try {
|
|
|
+ response = client.newCall(request).execute();
|
|
|
+ if (!response.isSuccessful()) {
|
|
|
+ throw new IOException("下载失败: " + response.code());
|
|
|
+ }
|
|
|
+ inputStream = response.body().byteStream();
|
|
|
+ return IOUtils.toByteArray(inputStream);
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ throw e;
|
|
|
+ } finally {
|
|
|
+ // 手动关闭资源
|
|
|
+ closeQuietly(inputStream);
|
|
|
+ if (response != null) {
|
|
|
+ response.close();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 文件下载方法
|
|
|
+ * @param url
|
|
|
+ * @param savePath 保存下载文件地址
|
|
|
+ * @param headers 请求头
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static boolean download(String url, String savePath,Map<String, String> headers) {
|
|
|
+ OkHttpClient client = new OkHttpClient.Builder()
|
|
|
+ .connectTimeout(240, TimeUnit.SECONDS)
|
|
|
+ .readTimeout(240, TimeUnit.SECONDS)
|
|
|
+ .writeTimeout(240, TimeUnit.SECONDS)
|
|
|
+ .retryOnConnectionFailure(true)
|
|
|
+ .build();
|
|
|
+ Request.Builder requestBuilder = new Request.Builder().url(url);
|
|
|
+ // 添加自定义请求头
|
|
|
+ if (headers != null) {
|
|
|
+ for (Map.Entry<String, String> entry : headers.entrySet()) {
|
|
|
+ requestBuilder.addHeader(entry.getKey(), entry.getValue());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ Request request = requestBuilder.build();
|
|
|
+
|
|
|
+ Response response = null;
|
|
|
+ InputStream inputStream = null;
|
|
|
+ FileOutputStream outputStream = null;
|
|
|
+
|
|
|
+ try {
|
|
|
+ response = client.newCall(request).execute();
|
|
|
+ if (response.isSuccessful()) {
|
|
|
+ inputStream = response.body().byteStream();
|
|
|
+ outputStream = new FileOutputStream(new File(savePath));
|
|
|
+
|
|
|
+ byte[] buffer = new byte[4096];
|
|
|
+ int bytesRead;
|
|
|
+ while ((bytesRead = inputStream.read(buffer)) != -1) {
|
|
|
+ outputStream.write(buffer, 0, bytesRead);
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ } finally {
|
|
|
+ // 关闭资源
|
|
|
+ closeQuietly(inputStream);
|
|
|
+ closeQuietly(outputStream);
|
|
|
+ if (response != null) {
|
|
|
+ response.close();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void closeQuietly(InputStream is) {
|
|
|
+ if (is != null) {
|
|
|
+ try {
|
|
|
+ is.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ // 静默关闭
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void closeQuietly(OutputStream fos) {
|
|
|
+ if (fos != null) {
|
|
|
+ try {
|
|
|
+ fos.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ // 静默关闭
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|