فهرست منبع

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

Young 2 سال پیش
والد
کامیت
fb13b59396

+ 44 - 0
support-demo/src/main/java/cn/nosum/wx/cp/controller/MediaController.java

@@ -0,0 +1,44 @@
+package cn.nosum.wx.cp.controller;
+
+import cn.nosum.http.entity.DownloadResponse;
+import cn.nosum.http.entity.UploadRequest;
+import cn.nosum.wx.common.api.WxConsts;
+import cn.nosum.wx.common.entity.result.WxMediaUploadResult;
+import cn.nosum.wx.common.error.WxErrorException;
+import cn.nosum.wx.cp.config.WxCpConfiguration;
+import lombok.SneakyThrows;
+import org.apache.tomcat.util.http.fileupload.IOUtils;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.*;
+
+/**
+ * 素材管理.
+ *
+ * @author Young
+ */
+@RestController
+@RequestMapping("/media")
+public class MediaController {
+
+    @SneakyThrows
+    @RequestMapping("/upload")
+    public WxMediaUploadResult upload(MultipartFile file, Integer appId) {
+        UploadRequest request = UploadRequest.builder().inputStream(file.getInputStream()).fileName(file.getOriginalFilename()).build();
+        return WxCpConfiguration.getCpService(appId).getMediaService().upload(WxConsts.MediaFileType.IMAGE, request);
+    }
+
+    @RequestMapping("/download")
+    public DownloadResponse download(Integer appId, String mediaId) throws WxErrorException, IOException {
+        final DownloadResponse download = WxCpConfiguration.getCpService(appId).getMediaService().download(mediaId);
+        try (ByteArrayOutputStream output = (ByteArrayOutputStream) download.getOutputStream()) {
+            FileOutputStream fileOutputStream;
+            String fileName = "/Users/huanghuijie/Downloads/" + download.getFileName();
+            fileOutputStream = new FileOutputStream(fileName);
+            fileOutputStream.write(output.toByteArray());
+        }
+        return download;
+    }
+}

+ 2 - 15
support-demo/src/main/java/cn/nosum/wx/cp/controller/MessageController.java

@@ -9,7 +9,7 @@ import cn.nosum.wx.cp.config.WxCpConfiguration;
 import cn.nosum.wx.cp.entity.message.WxCpMessage;
 import cn.nosum.wx.cp.entity.message.WxCpMessageSendResult;
 import lombok.SneakyThrows;
-import org.apache.commons.io.IOUtils;
+import org.apache.tomcat.util.http.fileupload.IOUtils;
 import org.springframework.web.bind.annotation.RequestMapping;
 import org.springframework.web.bind.annotation.RestController;
 import org.springframework.web.multipart.MultipartFile;
@@ -28,7 +28,7 @@ import static org.apache.commons.io.FileUtils.openOutputStream;
 @RequestMapping("/wx/message")
 public class MessageController {
 
-    @RequestMapping("/test")
+    @RequestMapping("/text")
     public WxCpMessageSendResult sendText(Integer appId){
         WxCpMessageService messageService = WxCpConfiguration.getCpService(appId).getMessageService();
         WxCpMessage wxCpMessage = WxCpMessage.TEXT()
@@ -37,17 +37,4 @@ public class MessageController {
                 .build().atAll();
         return messageService.send(wxCpMessage);
     }
-
-    @SneakyThrows
-    @RequestMapping("/upload")
-    public WxMediaUploadResult upload(MultipartFile file,Integer appId){
-        UploadRequest request = UploadRequest.builder().inputStream(file.getInputStream()).fileName(file.getOriginalFilename()).build();
-        return WxCpConfiguration.getCpService(appId).getMediaService().upload(WxConsts.MediaFileType.IMAGE, request);
-    }
-
-    @RequestMapping("/download")
-    public void download(Integer appId,String mediaId) throws WxErrorException, IOException {
-        OutputStream download = WxCpConfiguration.getCpService(appId).getMediaService().download(mediaId);
-        return;
-    }
 }

+ 5 - 0
support-http/pom.xml

@@ -55,6 +55,11 @@
             <groupId>org.projectlombok</groupId>
             <artifactId>lombok</artifactId>
         </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.core</groupId>
+            <artifactId>jackson-annotations</artifactId>
+            <scope>provided</scope>
+        </dependency>
     </dependencies>
 
 </project>

+ 6 - 13
support-http/src/main/java/cn/nosum/http/SimpleDownloadRequestExecutor.java

@@ -2,6 +2,7 @@ package cn.nosum.http;
 
 import cn.nosum.http.apache.ApacheDownloadRequestExecutor;
 import cn.nosum.http.apache.ApacheSimpleGetRequestExecutor;
+import cn.nosum.http.entity.DownloadResponse;
 import cn.nosum.http.exception.HttpErrorException;
 import cn.nosum.http.jodd.JoddDownloadRequestExecutor;
 import cn.nosum.http.jodd.JoddHttpSimpleGetRequestExecutor;
@@ -21,18 +22,18 @@ import java.io.OutputStream;
  * @param <P> 代理对象
  * @author Young
  */
-public abstract class SimpleDownloadRequestExecutor<H, P>  extends SimpleRequestExecutor<H, P, String, OutputStream> {
+public abstract class SimpleDownloadRequestExecutor<H, P>  extends SimpleRequestExecutor<H, P, String, DownloadResponse> {
 
     public SimpleDownloadRequestExecutor(RequestHttp<H, P> requestHttp) {
         super(requestHttp);
     }
 
-    public SimpleDownloadRequestExecutor(RequestHttp<H, P> requestHttp, ResponseHandler<OutputStream,OutputStream> responseHandler) {
+    public SimpleDownloadRequestExecutor(RequestHttp<H, P> requestHttp, ResponseHandler<DownloadResponse,DownloadResponse> responseHandler) {
         super(requestHttp, responseHandler);
     }
 
     @Override
-    public <V> V execute(String uri, String queryParam, ResponseHandler<OutputStream,V> handler) throws HttpErrorException, IOException {
+    public <V> V execute(String uri, String queryParam, ResponseHandler<DownloadResponse,V> handler) throws HttpErrorException, IOException {
         if (queryParam != null) {
             if (uri.indexOf('?') == -1) {
                 uri += '?';
@@ -42,7 +43,7 @@ public abstract class SimpleDownloadRequestExecutor<H, P>  extends SimpleRequest
         return handler.handle(doExecute(uri, queryParam));
     }
 
-    public static RequestExecutor<String, OutputStream> create(RequestHttp requestHttp) {
+    public static RequestExecutor<String, DownloadResponse> create(RequestHttp requestHttp) {
         switch (requestHttp.getRequestType()) {
             case APACHE_HTTP:
                 return new ApacheDownloadRequestExecutor(requestHttp);
@@ -55,13 +56,5 @@ public abstract class SimpleDownloadRequestExecutor<H, P>  extends SimpleRequest
         }
     }
 
-    protected OutputStream transfer(InputStream inputStream) throws IOException {
-        OutputStream output = new ByteArrayOutputStream();
-        byte[] buffer = new byte[4096];
-        int n;
-        while (-1 != (n = inputStream.read(buffer))) {
-            output.write(buffer, 0, n);
-        }
-        return output;
-    }
+
 }

+ 6 - 16
support-http/src/main/java/cn/nosum/http/apache/ApacheDownloadRequestExecutor.java

@@ -3,18 +3,16 @@ package cn.nosum.http.apache;
 import cn.nosum.http.RequestHttp;
 import cn.nosum.http.ResponseHandler;
 import cn.nosum.http.SimpleDownloadRequestExecutor;
+import cn.nosum.http.entity.DownloadResponse;
 import cn.nosum.http.exception.HttpErrorException;
-import org.apache.http.Header;
+import cn.nosum.http.proxy.HttpResponseProxy;
 import org.apache.http.HttpHost;
 import org.apache.http.client.config.RequestConfig;
 import org.apache.http.client.methods.CloseableHttpResponse;
 import org.apache.http.client.methods.HttpGet;
-import org.apache.http.entity.ContentType;
 import org.apache.http.impl.client.CloseableHttpClient;
 
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
 
 
 /**
@@ -29,28 +27,20 @@ public class ApacheDownloadRequestExecutor extends SimpleDownloadRequestExecutor
         super(requestHttp);
     }
 
-    public ApacheDownloadRequestExecutor(RequestHttp<CloseableHttpClient, HttpHost> requestHttp, ResponseHandler<OutputStream,OutputStream> responseHandler) {
+    public ApacheDownloadRequestExecutor(RequestHttp<CloseableHttpClient, HttpHost> requestHttp, ResponseHandler<DownloadResponse, DownloadResponse> responseHandler) {
         super(requestHttp, responseHandler);
     }
 
     @Override
-    public OutputStream doExecute(String uri, String data) throws HttpErrorException, IOException {
+    public DownloadResponse doExecute(String uri, String data) throws HttpErrorException, IOException {
         HttpGet httpGet = new HttpGet(uri);
         if (requestHttp.getRequestHttpProxy() != null) {
             RequestConfig config = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build();
             httpGet.setConfig(config);
         }
 
-        try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpGet);
-             InputStream inputStream = InputStreamResponseHandler.INSTANCE.handleResponse(response)) {
-            Header[] contentTypeHeader = response.getHeaders("Content-Type");
-            if (contentTypeHeader != null && contentTypeHeader.length > 0) {
-                // application/json; encoding=utf-8 下载媒体文件出错
-                if (contentTypeHeader[0].getValue().startsWith(ContentType.APPLICATION_JSON.getMimeType())) {
-                    throw new HttpErrorException(Utf8ResponseHandler.INSTANCE.handleResponse(response));
-                }
-            }
-            return transfer(inputStream);
+        try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpGet)) {
+            return new HttpResponseProxy(response).transferDownload();
         } finally {
             httpGet.releaseConnection();
         }

+ 34 - 0
support-http/src/main/java/cn/nosum/http/entity/DownloadResponse.java

@@ -0,0 +1,34 @@
+package cn.nosum.http.entity;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.Builder;
+import lombok.Data;
+
+import java.io.OutputStream;
+
+/**
+ * 文件下载响应.
+ *
+ * @author Young
+ */
+@Data
+@Builder
+public class DownloadResponse {
+
+    /**
+     * 响应流
+     */
+    @JsonIgnore
+    private transient OutputStream outputStream;
+
+    /**
+     * 文件名称
+     */
+    private String fileName;
+
+
+    /**
+     * 响应类型
+     */
+    private String contentType;
+}

+ 4 - 20
support-http/src/main/java/cn/nosum/http/jodd/JoddDownloadRequestExecutor.java

@@ -4,18 +4,15 @@ package cn.nosum.http.jodd;
 import cn.nosum.http.RequestHttp;
 import cn.nosum.http.ResponseHandler;
 import cn.nosum.http.SimpleDownloadRequestExecutor;
+import cn.nosum.http.entity.DownloadResponse;
 import cn.nosum.http.exception.HttpErrorException;
 import cn.nosum.http.proxy.HttpResponseProxy;
 import jodd.http.HttpConnectionProvider;
 import jodd.http.HttpRequest;
 import jodd.http.HttpResponse;
 import jodd.http.ProxyInfo;
-import org.apache.commons.lang3.StringUtils;
 
-import java.io.ByteArrayInputStream;
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
 import java.nio.charset.StandardCharsets;
 
 
@@ -30,12 +27,12 @@ public class JoddDownloadRequestExecutor extends SimpleDownloadRequestExecutor<H
         super(requestHttp);
     }
 
-    public JoddDownloadRequestExecutor(RequestHttp<HttpConnectionProvider, ProxyInfo> requestHttp, ResponseHandler<OutputStream,OutputStream> responseHandler) {
+    public JoddDownloadRequestExecutor(RequestHttp<HttpConnectionProvider, ProxyInfo> requestHttp, ResponseHandler<DownloadResponse,DownloadResponse> responseHandler) {
         super(requestHttp, responseHandler);
     }
 
     @Override
-    public OutputStream doExecute(String uri, String data) throws HttpErrorException, IOException {
+    public DownloadResponse doExecute(String uri, String data) throws HttpErrorException, IOException {
         HttpRequest request = HttpRequest.get(uri);
         if (requestHttp.getRequestHttpProxy() != null) {
             requestHttp.getRequestHttpClient().useProxy(requestHttp.getRequestHttpProxy());
@@ -44,19 +41,6 @@ public class JoddDownloadRequestExecutor extends SimpleDownloadRequestExecutor<H
 
         HttpResponse response = request.send();
         response.charset(StandardCharsets.UTF_8.name());
-
-        String contentType = response.header("Content-Type");
-        // application/json; encoding=utf-8 下载媒体文件出错
-        if (contentType != null && contentType.startsWith("application/json")) {
-            throw new HttpErrorException(response.bodyText());
-        }
-
-        String fileName = new HttpResponseProxy(response).getFileName();
-        if (StringUtils.isBlank(fileName)) {
-            return null;
-        }
-        try (InputStream inputStream = new ByteArrayInputStream(response.bodyBytes())) {
-            return transfer(inputStream);
-        }
+        return new HttpResponseProxy(response).transferDownload();
     }
 }

+ 5 - 13
support-http/src/main/java/cn/nosum/http/okhttp/OkHttpDownloadRequestExecutor.java

@@ -3,15 +3,14 @@ package cn.nosum.http.okhttp;
 import cn.nosum.http.RequestHttp;
 import cn.nosum.http.ResponseHandler;
 import cn.nosum.http.SimpleDownloadRequestExecutor;
+import cn.nosum.http.entity.DownloadResponse;
 import cn.nosum.http.exception.HttpErrorException;
+import cn.nosum.http.proxy.HttpResponseProxy;
 import okhttp3.OkHttpClient;
 import okhttp3.Request;
 import okhttp3.Response;
 
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.Objects;
 
 /**
  * OKHTTP 下载请求封装.
@@ -24,22 +23,15 @@ public class OkHttpDownloadRequestExecutor extends SimpleDownloadRequestExecutor
         super(requestHttp);
     }
 
-    public OkHttpDownloadRequestExecutor(RequestHttp<OkHttpClient, OkHttpProxyInfo> requestHttp, ResponseHandler<OutputStream,OutputStream> responseHandler) {
+    public OkHttpDownloadRequestExecutor(RequestHttp<OkHttpClient, OkHttpProxyInfo> requestHttp, ResponseHandler<DownloadResponse,DownloadResponse> responseHandler) {
         super(requestHttp, responseHandler);
     }
 
     @Override
-    public OutputStream doExecute(String uri, String data) throws HttpErrorException, IOException {
+    public DownloadResponse doExecute(String uri, String data) throws HttpErrorException, IOException {
         OkHttpClient client = requestHttp.getRequestHttpClient();
         Request request = new Request.Builder().url(uri).get().build();
         Response response = client.newCall(request).execute();
-        String contentType = response.header("Content-Type");
-        // application/json; encoding=utf-8 下载媒体文件出错
-        if (contentType != null && contentType.startsWith("application/json")) {
-            throw new HttpErrorException(Objects.requireNonNull(response.body()).string());
-        }
-        try (InputStream input = Objects.requireNonNull(response.body()).byteStream()) {
-            return transfer(input);
-        }
+        return new HttpResponseProxy(response).transferDownload();
     }
 }

+ 94 - 0
support-http/src/main/java/cn/nosum/http/proxy/HttpResponseProxy.java

@@ -1,11 +1,20 @@
 package cn.nosum.http.proxy;
 
+import cn.nosum.http.apache.InputStreamResponseHandler;
+import cn.nosum.http.apache.Utf8ResponseHandler;
+import cn.nosum.http.entity.DownloadResponse;
 import cn.nosum.http.exception.HttpErrorException;
 import jodd.http.HttpResponse;
 import okhttp3.Response;
 import org.apache.http.Header;
 import org.apache.http.client.methods.CloseableHttpResponse;
+import org.apache.http.entity.ContentType;
 
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Objects;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -53,6 +62,91 @@ public class HttpResponseProxy {
     }
 
     /**
+     * 获取下载文件响应流.
+     *
+     * @return 文件响应流
+     * @throws IOException IO 异常
+     */
+    public OutputStream getOutputStream() throws IOException {
+        if (this.apacheHttpResponse != null) {
+            try (InputStream inputStream = InputStreamResponseHandler.INSTANCE.handleResponse(this.apacheHttpResponse)) {
+                return transfer(inputStream);
+            }
+        }
+        if (this.joddHttpResponse != null) {
+            return transfer(joddHttpResponse.bodyBytes());
+        }
+        if (this.okHttpResponse != null) {
+            return transfer(this.okHttpResponse.body().bytes());
+        }
+        return null;
+    }
+
+    /**
+     * 获取响应类型.
+     *
+     * @return 响应类型
+     * @throws HttpErrorException HTTP 异常
+     */
+    public String getContentType() throws HttpErrorException, IOException {
+        String contentType = null;
+
+        // application/json; encoding=utf-8 下载媒体文件出错
+        final String mimeType = ContentType.APPLICATION_JSON.getMimeType();
+
+        if (this.apacheHttpResponse != null) {
+            Header[] contentTypeHeader = apacheHttpResponse.getHeaders("Content-Type");
+            if (contentTypeHeader[0].getValue().startsWith(mimeType)) {
+                throw new HttpErrorException(Utf8ResponseHandler.INSTANCE.handleResponse(this.apacheHttpResponse));
+            }
+            contentType = contentTypeHeader[0].getValue();
+        }
+
+        if (this.joddHttpResponse != null) {
+            contentType = this.joddHttpResponse.header("Content-Type");
+            if (contentType != null && contentType.startsWith(mimeType)) {
+                throw new HttpErrorException(this.joddHttpResponse.bodyText());
+            }
+        }
+
+        if (this.okHttpResponse != null) {
+            contentType = this.okHttpResponse.header("Content-Type");
+            if (contentType != null && contentType.startsWith(mimeType)) {
+                throw new HttpErrorException(Objects.requireNonNull(this.okHttpResponse.body()).string());
+            }
+        }
+        return contentType;
+    }
+
+
+    /**
+     * 转换响应流为下载文件响应.
+     *
+     * @return 下载文件响应
+     * @throws HttpErrorException HTTP 异常
+     * @throws IOException        IO 异常
+     */
+    public DownloadResponse transferDownload() throws HttpErrorException, IOException {
+        return DownloadResponse.builder().contentType(getContentType()).outputStream(getOutputStream()).fileName(getFileName()).build();
+    }
+
+    private OutputStream transfer(byte[] bytes) throws IOException {
+        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+        byteArrayOutputStream.write(bytes);
+        return byteArrayOutputStream;
+    }
+
+    private OutputStream transfer(InputStream inputStream) throws IOException {
+        OutputStream output = new ByteArrayOutputStream();
+        byte[] buffer = new byte[4096];
+        int n;
+        while (-1 != (n = inputStream.read(buffer))) {
+            output.write(buffer, 0, n);
+        }
+        return output;
+    }
+
+    /**
      * 获取文件名称
      *
      * @param response apache 文件响应

+ 3 - 2
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/api/WxCpMediaService.java

@@ -1,5 +1,6 @@
 package cn.nosum.wx.cp.api;
 
+import cn.nosum.http.entity.DownloadResponse;
 import cn.nosum.http.entity.UploadRequest;
 import cn.nosum.wx.common.entity.result.WxMediaUploadResult;
 import cn.nosum.wx.common.error.WxErrorException;
@@ -59,7 +60,7 @@ public interface WxCpMediaService {
      * @return 文件流
      * @throws WxErrorException 企业微信接口调用异常
      */
-    OutputStream download(String mediaId) throws WxErrorException;
+    DownloadResponse download(String mediaId) throws WxErrorException;
 
     /**
      * <pre>
@@ -74,7 +75,7 @@ public interface WxCpMediaService {
      * @param mediaId 媒体id
      * @return 保存到本地的临时文件
      */
-    OutputStream getJsSdk(String mediaId) throws WxErrorException;
+    DownloadResponse getJsSdk(String mediaId) throws WxErrorException;
 
 
 }

+ 3 - 2
wx-java-tools/wx-java-cp/src/main/java/cn/nosum/wx/cp/api/impl/WxCpMediaServiceImpl.java

@@ -3,6 +3,7 @@ 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.DownloadResponse;
 import cn.nosum.http.entity.UploadRequest;
 import cn.nosum.wx.common.entity.result.WxMediaUploadResult;
 import cn.nosum.wx.common.error.WxErrorException;
@@ -42,14 +43,14 @@ public class WxCpMediaServiceImpl implements WxCpMediaService {
     }
 
     @Override
-    public OutputStream download(String mediaId) throws WxErrorException {
+    public DownloadResponse 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 getJsSdk(String mediaId) throws WxErrorException {
+    public DownloadResponse getJsSdk(String mediaId) throws WxErrorException {
         return this.mainService.execute(
                 SimpleDownloadRequestExecutor.create(this.mainService.getRequestHttp()),
                 this.mainService.getWxCpConfigStorage().getApiUrl(JS_SDK_MEDIA_GET), "media_id=" + mediaId);