Quellcode durchsuchen

fix 修改 wx-java-cp,添加文件上传下载

Young vor 2 Jahren
Ursprung
Commit
cc9dfd35c5

+ 33 - 1
support-http/src/main/java/cn/nosum/http/SimpleDownloadRequestExecutor.java

@@ -1,5 +1,13 @@
 package cn.nosum.http;
 
+import cn.nosum.http.apache.ApacheDownloadRequestExecutor;
+import cn.nosum.http.apache.ApacheSimpleGetRequestExecutor;
+import cn.nosum.http.exception.HttpErrorException;
+import cn.nosum.http.jodd.JoddDownloadRequestExecutor;
+import cn.nosum.http.jodd.JoddHttpSimpleGetRequestExecutor;
+import cn.nosum.http.okhttp.OkHttpDownloadRequestExecutor;
+import cn.nosum.http.okhttp.OkHttpSimpleGetRequestExecutor;
+
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -13,7 +21,7 @@ import java.io.OutputStream;
  * @param <P> 代理对象
  * @author Young
  */
-public abstract class SimpleDownloadRequestExecutor<H, P> extends SimpleGetRequestExecutor<H, P, OutputStream> {
+public abstract class SimpleDownloadRequestExecutor<H, P>  extends SimpleRequestExecutor<H, P, String, OutputStream> {
 
     public SimpleDownloadRequestExecutor(RequestHttp<H, P> requestHttp) {
         super(requestHttp);
@@ -23,6 +31,30 @@ public abstract class SimpleDownloadRequestExecutor<H, P> extends SimpleGetReque
         super(requestHttp, responseHandler);
     }
 
+    @Override
+    public <V> V execute(String uri, String queryParam, ResponseHandler<OutputStream,V> handler) throws HttpErrorException, IOException {
+        if (queryParam != null) {
+            if (uri.indexOf('?') == -1) {
+                uri += '?';
+            }
+            uri += uri.endsWith("?") ? queryParam : '&' + queryParam;
+        }
+        return handler.handle(doExecute(uri, queryParam));
+    }
+
+    public static RequestExecutor<String, OutputStream> create(RequestHttp requestHttp) {
+        switch (requestHttp.getRequestType()) {
+            case APACHE_HTTP:
+                return new ApacheDownloadRequestExecutor(requestHttp);
+            case JODD_HTTP:
+                return new JoddDownloadRequestExecutor(requestHttp);
+            case OK_HTTP:
+                return new OkHttpDownloadRequestExecutor(requestHttp);
+            default:
+                throw new IllegalArgumentException("非法请求参数");
+        }
+    }
+
     protected OutputStream transfer(InputStream inputStream) throws IOException {
         OutputStream output = new ByteArrayOutputStream();
         byte[] buffer = new byte[4096];

+ 14 - 1
support-http/src/main/java/cn/nosum/http/SimpleUploadRequestExecutor.java

@@ -7,7 +7,10 @@ import cn.nosum.http.jodd.JoddHttpSimpleUploadRequestExecutor;
 import cn.nosum.http.okhttp.OkHttpSimpleUploadRequestExecutor;
 import org.apache.commons.lang3.StringUtils;
 
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
 import java.util.Objects;
 
 /**
@@ -30,7 +33,7 @@ public abstract class SimpleUploadRequestExecutor<H, P, R> extends SimpleRequest
 
     @Override
     public <V> V execute(String uri, UploadRequest uploadRequest, ResponseHandler<R,V> handler) throws HttpErrorException, IOException {
-        if (Objects.isNull(uploadRequest) || Objects.isNull(uploadRequest.getFile())) {
+        if (Objects.isNull(uploadRequest) || Objects.isNull(uploadRequest.getInputStream())) {
             throw new HttpErrorException("request file cannot be empty");
         }
         if (StringUtils.isBlank(uploadRequest.getName())) {
@@ -39,6 +42,16 @@ public abstract class SimpleUploadRequestExecutor<H, P, R> extends SimpleRequest
         return handler.handle(doExecute(uri, uploadRequest));
     }
 
+    protected byte[] transfer(InputStream inputStream) throws IOException {
+        ByteArrayOutputStream output = new ByteArrayOutputStream();
+        byte[] buffer = new byte[4096];
+        int n;
+        while (-1 != (n = inputStream.read(buffer))) {
+            output.write(buffer, 0, n);
+        }
+        return output.toByteArray();
+    }
+
     public static RequestExecutor<UploadRequest, String> create(RequestHttp requestHttp) {
         switch (requestHttp.getRequestType()) {
             case APACHE_HTTP:

+ 1 - 1
support-http/src/main/java/cn/nosum/http/apache/ApacheSimpleUploadRequestExecutor.java

@@ -41,7 +41,7 @@ public class ApacheSimpleUploadRequestExecutor extends SimpleUploadRequestExecut
         }
         HttpEntity entity = MultipartEntityBuilder
                 .create()
-                .addBinaryBody(uploadRequest.getName(), uploadRequest.getFile())
+                .addBinaryBody(uploadRequest.getName(), uploadRequest.getInputStream())
                 .setMode(HttpMultipartMode.RFC6532)
                 .build();
         httpPost.setEntity(entity);

+ 2 - 1
support-http/src/main/java/cn/nosum/http/entity/UploadRequest.java

@@ -4,6 +4,7 @@ import lombok.Builder;
 import lombok.Data;
 
 import java.io.File;
+import java.io.InputStream;
 import java.io.Serializable;
 
 /**
@@ -18,7 +19,7 @@ public class UploadRequest implements Serializable {
     /**
      * 文件内容
      */
-    private File file;
+    private InputStream inputStream;
 
     /**
      * 参数名称

+ 1 - 1
support-http/src/main/java/cn/nosum/http/jodd/JoddHttpSimpleUploadRequestExecutor.java

@@ -37,7 +37,7 @@ public class JoddHttpSimpleUploadRequestExecutor extends SimpleUploadRequestExec
             requestHttp.getRequestHttpClient().useProxy(requestHttp.getRequestHttpProxy());
         }
         request.withConnectionProvider(requestHttp.getRequestHttpClient());
-        request.form(uploadRequest.getName(), uploadRequest.getFile());
+        request.form(uploadRequest.getName(), uploadRequest.getInputStream());
         HttpResponse response = request.send();
         response.charset(StandardCharsets.UTF_8.name());
         return response.bodyText();

+ 3 - 2
support-http/src/main/java/cn/nosum/http/okhttp/OkHttpSimpleUploadRequestExecutor.java

@@ -32,9 +32,10 @@ public class OkHttpSimpleUploadRequestExecutor extends SimpleUploadRequestExecut
         RequestBody body = new MultipartBody.Builder()
                 .setType(Objects.requireNonNull(MediaType.parse("multipart/form-data")))
                 .addFormDataPart(uploadRequest.getName(),
-                        uploadRequest.getFile().getName(),
-                        RequestBody.create(MediaType.parse("application/octet-stream"), uploadRequest.getFile()))
+                        uploadRequest.getName(),
+                        RequestBody.create(MediaType.parse("application/octet-stream"), transfer(uploadRequest.getInputStream())))
                 .build();
+
         Request request = new Request.Builder().url(uri).post(body).build();
 
         Response response = requestHttp.getRequestHttpClient().newCall(request).execute();

+ 77 - 0
wx-java-tools/wx-java-common/src/main/java/cn/nosum/wx/common/utils/FileUtils.java

@@ -0,0 +1,77 @@
+package cn.nosum.wx.common.utils;
+
+import org.apache.commons.io.IOUtils;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.util.Base64;
+
+import static org.apache.commons.io.FileUtils.openOutputStream;
+
+public class FileUtils {
+
+  /**
+   * 创建临时文件.
+   *
+   * @param inputStream 输入文件流
+   * @param name        文件名
+   * @param ext         扩展名
+   * @param tmpDirFile  临时文件夹目录
+   */
+  public static File createTmpFile(InputStream inputStream, String name, String ext, File tmpDirFile) throws IOException {
+    File resultFile = File.createTempFile(name, '.' + ext, tmpDirFile);
+
+    resultFile.deleteOnExit();
+    copyToFile(inputStream, resultFile);
+    return resultFile;
+  }
+
+  private static void copyToFile(final InputStream source, final File destination) throws IOException {
+    try (InputStream in = source; OutputStream out = openOutputStream(destination)) {
+      IOUtils.copy(in, out);
+    }
+  }
+
+  /**
+   * 创建临时文件.
+   *
+   * @param inputStream 输入文件流
+   * @param name        文件名
+   * @param ext         扩展名
+   */
+  public static File createTmpFile(InputStream inputStream, String name, String ext) throws IOException {
+    return createTmpFile(inputStream, name, ext, Files.createTempDirectory("weixin-java-tools-temp").toFile());
+  }
+
+  /**
+   * 文件流生成base64
+   *
+   * @param in 文件流
+   * @return base64编码
+   */
+  public static String imageToBase64ByStream(InputStream in) {
+    byte[] data = null;
+    // 读取图片字节数组
+    try {
+      data = new byte[in.available()];
+      in.read(data);
+      // 返回Base64编码过的字节数组字符串
+      return Base64.getEncoder().encodeToString(data);
+    } catch (IOException e) {
+      e.printStackTrace();
+    } finally {
+      if (in != null) {
+        try {
+          in.close();
+        } catch (IOException e) {
+          e.printStackTrace();
+        }
+      }
+    }
+    return null;
+  }
+
+}

+ 26 - 29
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/api/WxCpMediaService.java

@@ -1,11 +1,15 @@
 package cn.nosum.wx.cp.api;
 
+import cn.nosum.http.entity.UploadRequest;
 import cn.nosum.wx.common.entity.result.WxMediaUploadResult;
 import cn.nosum.wx.common.error.WxErrorException;
 
 import java.io.File;
-import java.io.IOException;
+
+import cn.nosum.wx.common.api.WxConsts;
+
 import java.io.InputStream;
+import java.io.OutputStream;
 
 /**
  * 媒体管理接口.
@@ -16,6 +20,20 @@ public interface WxCpMediaService {
 
     /**
      * <pre>
+     * 上传图片.
+     * 上传图片得到图片URL,该URL永久有效
+     * 返回的图片URL,仅能用于图文消息(mpnews)正文中的图片展示;若用于非企业微信域名下的页面,图片将被屏蔽。
+     * 每个企业每天最多可上传100张图片
+     * 接口url格式:https://qyapi.weixin.qq.com/cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN
+     * </pre>
+     *
+     * @param uploadRequest 上传文件对象封装
+     * @return 返回图片url
+     */
+    String uploadImg(UploadRequest uploadRequest) throws WxErrorException;
+
+    /**
+     * <pre>
      * 上传多媒体文件.
      * 上传的多媒体文件有格式和大小限制,如下:
      *   图片(image): 1M,支持JPG格式
@@ -25,20 +43,10 @@ public interface WxCpMediaService {
      * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=上传下载多媒体文件
      * </pre>
      *
-     * @param mediaType   媒体类型, 请看{@link cn.nosum.wx.common.api.WxConsts}
-     * @param fileType    文件类型,请看{@link cn.nosum.wx.common.api.WxConsts}
+     * @param mediaType   媒体类型, 请看{@link WxConsts}
      * @param inputStream 输入流,需要调用方控制关闭该输入流
      */
-    WxMediaUploadResult upload(String mediaType, String fileType, InputStream inputStream);
-
-    /**
-     * 上传多媒体文件.
-     *
-     * @param mediaType 媒体类型
-     * @param file      文件对象
-     * @see #upload(String, String, InputStream)
-     */
-    WxMediaUploadResult upload(String mediaType, File file);
+    WxMediaUploadResult upload(String mediaType, UploadRequest inputStream) throws WxErrorException;
 
     /**
      * <pre>
@@ -48,9 +56,10 @@ public interface WxCpMediaService {
      * </pre>
      *
      * @param mediaId 媒体id
-     * @return 保存到本地的临时文件
+     * @return 文件流
+     * @throws WxErrorException 企业微信接口调用异常
      */
-    File download(String mediaId);
+    OutputStream download(String mediaId) throws WxErrorException;
 
     /**
      * <pre>
@@ -65,19 +74,7 @@ public interface WxCpMediaService {
      * @param mediaId 媒体id
      * @return 保存到本地的临时文件
      */
-    File getJssdkFile(String mediaId);
+    OutputStream getJssdkFile(String mediaId) throws WxErrorException;
+
 
-    /**
-     * <pre>
-     * 上传图片.
-     * 上传图片得到图片URL,该URL永久有效
-     * 返回的图片URL,仅能用于图文消息(mpnews)正文中的图片展示;若用于非企业微信域名下的页面,图片将被屏蔽。
-     * 每个企业每天最多可上传100张图片
-     * 接口url格式:https://qyapi.weixin.qq.com/cgi-bin/media/uploadimg?access_token=ACCESS_TOKEN
-     * </pre>
-     *
-     * @param file 上传的文件对象
-     * @return 返回图片url
-     */
-    String uploadImg(File file);
 }

+ 58 - 0
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/api/impl/WxCpMediaServiceImpl.java

@@ -0,0 +1,58 @@
+package cn.nosum.wx.cp.api.impl;
+
+import cn.nosum.http.RequestExecutor;
+import cn.nosum.http.SimpleDownloadRequestExecutor;
+import cn.nosum.http.SimpleUploadRequestExecutor;
+import cn.nosum.http.entity.UploadRequest;
+import cn.nosum.wx.common.entity.result.WxMediaUploadResult;
+import cn.nosum.wx.common.error.WxErrorException;
+import cn.nosum.wx.cp.api.WxCpMediaService;
+import cn.nosum.wx.cp.api.WxCpService;
+import lombok.RequiredArgsConstructor;
+
+import java.io.OutputStream;
+
+import static cn.nosum.wx.cp.constant.WxCpApiPathConsts.Media.*;
+
+
+/**
+ * 媒体管理接口.
+ *
+ * @author Young
+ */
+@RequiredArgsConstructor
+public class WxCpMediaServiceImpl implements WxCpMediaService {
+
+    private final WxCpService mainService;
+
+    @Override
+    public String uploadImg(UploadRequest request) throws WxErrorException {
+        final String url = this.mainService.getWxCpConfigStorage().getApiUrl(IMG_UPLOAD);
+        return WxMediaUploadResult.fromJson(
+                this.mainService.execute(SimpleUploadRequestExecutor.create(this.mainService.getRequestHttp()), url, request)
+        ).getUrl();
+    }
+
+    @Override
+    public WxMediaUploadResult upload(String mediaType, UploadRequest request) throws WxErrorException {
+        RequestExecutor<UploadRequest, String> executor = SimpleUploadRequestExecutor.create(this.mainService.getRequestHttp());
+        return WxMediaUploadResult.fromJson(
+                this.mainService.execute(executor, this.mainService.getWxCpConfigStorage().getApiUrl(MEDIA_UPLOAD + mediaType), request
+                ));
+    }
+
+    @Override
+    public OutputStream download(String mediaId) throws WxErrorException {
+        return this.mainService.execute(
+                SimpleDownloadRequestExecutor.create(this.mainService.getRequestHttp()),
+                this.mainService.getWxCpConfigStorage().getApiUrl(MEDIA_GET), "media_id=" + mediaId);
+    }
+
+    @Override
+    public OutputStream getJssdkFile(String mediaId) throws WxErrorException {
+        return this.mainService.execute(
+                SimpleDownloadRequestExecutor.create(this.mainService.getRequestHttp()),
+                this.mainService.getWxCpConfigStorage().getApiUrl(JS_SDK_MEDIA_GET), "media_id=" + mediaId);
+    }
+
+}