mirror of
				https://gitee.com/binary/weixin-java-tools.git
				synced 2025-10-31 16:36:54 +08:00 
			
		
		
		
	🆕 【企业微信】增加支持URL的素材文件上传接口
This commit is contained in:
		| @@ -0,0 +1,27 @@ | ||||
| package me.chanjar.weixin.common.util.http; | ||||
|  | ||||
| import lombok.AllArgsConstructor; | ||||
| import lombok.Data; | ||||
| import lombok.NoArgsConstructor; | ||||
| import lombok.experimental.Accessors; | ||||
|  | ||||
| import java.io.InputStream; | ||||
| import java.io.Serializable; | ||||
|  | ||||
| /** | ||||
|  * 输入流数据. | ||||
|  * <p/> | ||||
|  * InputStreamData | ||||
|  * | ||||
|  * @author zichuan.zhou91@gmail.com | ||||
|  * @date 2022/2/15 | ||||
|  */ | ||||
| @Data | ||||
| @Accessors(chain = true) | ||||
| @NoArgsConstructor | ||||
| @AllArgsConstructor | ||||
| public class InputStreamData implements Serializable { | ||||
|   private static final long serialVersionUID = -4627006604779378520L; | ||||
|   private InputStream inputStream; | ||||
|   private String filename; | ||||
| } | ||||
| @@ -0,0 +1,43 @@ | ||||
| package me.chanjar.weixin.common.util.http; | ||||
|  | ||||
| import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | ||||
| import me.chanjar.weixin.common.enums.WxType; | ||||
| import me.chanjar.weixin.common.error.WxErrorException; | ||||
| import me.chanjar.weixin.common.util.http.apache.ApacheMediaInputStreamUploadRequestExecutor; | ||||
| import me.chanjar.weixin.common.util.http.jodd.JoddHttpMediaInputStreamUploadRequestExecutor; | ||||
| import me.chanjar.weixin.common.util.http.okhttp.OkHttpMediaInputStreamUploadRequestExecutor; | ||||
|  | ||||
| import java.io.IOException; | ||||
|  | ||||
| /** | ||||
|  * 上传媒体文件请求执行器. | ||||
|  * 请求的参数是File, 返回的结果是String | ||||
|  * | ||||
|  * @author Daniel Qian | ||||
|  */ | ||||
| public abstract class MediaInputStreamUploadRequestExecutor<H, P> implements RequestExecutor<WxMediaUploadResult, InputStreamData> { | ||||
|   protected RequestHttp<H, P> requestHttp; | ||||
|  | ||||
|   public MediaInputStreamUploadRequestExecutor(RequestHttp requestHttp) { | ||||
|     this.requestHttp = requestHttp; | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public void execute(String uri, InputStreamData data, ResponseHandler<WxMediaUploadResult> handler, WxType wxType) throws WxErrorException, IOException { | ||||
|     handler.handle(this.execute(uri, data, wxType)); | ||||
|   } | ||||
|  | ||||
|   public static RequestExecutor<WxMediaUploadResult, InputStreamData> create(RequestHttp requestHttp) { | ||||
|     switch (requestHttp.getRequestType()) { | ||||
|       case APACHE_HTTP: | ||||
|         return new ApacheMediaInputStreamUploadRequestExecutor(requestHttp); | ||||
|       case JODD_HTTP: | ||||
|         return new JoddHttpMediaInputStreamUploadRequestExecutor(requestHttp); | ||||
|       case OK_HTTP: | ||||
|         return new OkHttpMediaInputStreamUploadRequestExecutor(requestHttp); | ||||
|       default: | ||||
|         return null; | ||||
|     } | ||||
|   } | ||||
|  | ||||
| } | ||||
| @@ -37,4 +37,6 @@ public interface RequestExecutor<T, E> { | ||||
|    * @throws IOException      io异常 | ||||
|    */ | ||||
|   void execute(String uri, E data, ResponseHandler<T> handler, WxType wxType) throws WxErrorException, IOException; | ||||
|  | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -0,0 +1,59 @@ | ||||
| package me.chanjar.weixin.common.util.http.apache; | ||||
|  | ||||
| import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | ||||
| import me.chanjar.weixin.common.enums.WxType; | ||||
| import me.chanjar.weixin.common.error.WxError; | ||||
| import me.chanjar.weixin.common.error.WxErrorException; | ||||
| import me.chanjar.weixin.common.util.http.InputStreamData; | ||||
| import me.chanjar.weixin.common.util.http.MediaInputStreamUploadRequestExecutor; | ||||
| import me.chanjar.weixin.common.util.http.RequestHttp; | ||||
| import org.apache.http.HttpEntity; | ||||
| 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.HttpPost; | ||||
| import org.apache.http.entity.ContentType; | ||||
| import org.apache.http.entity.mime.HttpMultipartMode; | ||||
| import org.apache.http.entity.mime.MultipartEntityBuilder; | ||||
| import org.apache.http.impl.client.CloseableHttpClient; | ||||
|  | ||||
| import java.io.IOException; | ||||
|  | ||||
| /** | ||||
|  * 文件输入流上传. | ||||
|  * | ||||
|  * @author meiqin.zhou91@gmail.com | ||||
|  * @date 2022/02/15 | ||||
|  */ | ||||
| public class ApacheMediaInputStreamUploadRequestExecutor extends MediaInputStreamUploadRequestExecutor<CloseableHttpClient, HttpHost> { | ||||
|   public ApacheMediaInputStreamUploadRequestExecutor(RequestHttp requestHttp) { | ||||
|     super(requestHttp); | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public WxMediaUploadResult execute(String uri, InputStreamData data, WxType wxType) throws WxErrorException, IOException { | ||||
|     HttpPost httpPost = new HttpPost(uri); | ||||
|     if (requestHttp.getRequestHttpProxy() != null) { | ||||
|       RequestConfig config = RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build(); | ||||
|       httpPost.setConfig(config); | ||||
|     } | ||||
|     if (data != null) { | ||||
|       HttpEntity entity = MultipartEntityBuilder | ||||
|         .create() | ||||
|         .addBinaryBody("media", data.getInputStream(), ContentType.DEFAULT_BINARY, data.getFilename()) | ||||
|         .setMode(HttpMultipartMode.RFC6532) | ||||
|         .build(); | ||||
|       httpPost.setEntity(entity); | ||||
|     } | ||||
|     try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) { | ||||
|       String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); | ||||
|       WxError error = WxError.fromJson(responseContent, wxType); | ||||
|       if (error.getErrorCode() != 0) { | ||||
|         throw new WxErrorException(error); | ||||
|       } | ||||
|       return WxMediaUploadResult.fromJson(responseContent); | ||||
|     } finally { | ||||
|       httpPost.releaseConnection(); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @@ -0,0 +1,61 @@ | ||||
| package me.chanjar.weixin.common.util.http.jodd; | ||||
|  | ||||
| import jodd.http.HttpConnectionProvider; | ||||
| import jodd.http.HttpRequest; | ||||
| import jodd.http.HttpResponse; | ||||
| import jodd.http.ProxyInfo; | ||||
| import jodd.http.up.ByteArrayUploadable; | ||||
| import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | ||||
| import me.chanjar.weixin.common.enums.WxType; | ||||
| import me.chanjar.weixin.common.error.WxError; | ||||
| import me.chanjar.weixin.common.error.WxErrorException; | ||||
| import me.chanjar.weixin.common.util.http.InputStreamData; | ||||
| import me.chanjar.weixin.common.util.http.MediaInputStreamUploadRequestExecutor; | ||||
| import me.chanjar.weixin.common.util.http.RequestHttp; | ||||
|  | ||||
| import java.io.ByteArrayOutputStream; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.nio.charset.StandardCharsets; | ||||
|  | ||||
| /** | ||||
|  * 文件输入流上传. | ||||
|  * | ||||
|  * @author meiqin.zhou91@gmail.com | ||||
|  * @date 2022/02/15 | ||||
|  */ | ||||
| public class JoddHttpMediaInputStreamUploadRequestExecutor extends MediaInputStreamUploadRequestExecutor<HttpConnectionProvider, ProxyInfo> { | ||||
|   public JoddHttpMediaInputStreamUploadRequestExecutor(RequestHttp requestHttp) { | ||||
|     super(requestHttp); | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public WxMediaUploadResult execute(String uri, InputStreamData data, WxType wxType) throws WxErrorException, IOException { | ||||
|     HttpRequest request = HttpRequest.post(uri); | ||||
|     if (requestHttp.getRequestHttpProxy() != null) { | ||||
|       requestHttp.getRequestHttpClient().useProxy(requestHttp.getRequestHttpProxy()); | ||||
|     } | ||||
|     request.withConnectionProvider(requestHttp.getRequestHttpClient()); | ||||
|     request.form("media", new ByteArrayUploadable(this.toByteArray(data.getInputStream()), data.getFilename())); | ||||
|     HttpResponse response = request.send(); | ||||
|     response.charset(StandardCharsets.UTF_8.name()); | ||||
|  | ||||
|     String responseContent = response.bodyText(); | ||||
|     WxError error = WxError.fromJson(responseContent, wxType); | ||||
|     if (error.getErrorCode() != 0) { | ||||
|       throw new WxErrorException(error); | ||||
|     } | ||||
|     return WxMediaUploadResult.fromJson(responseContent); | ||||
|   } | ||||
|  | ||||
|   public byte[] toByteArray(InputStream input) throws IOException { | ||||
|     try (ByteArrayOutputStream output = new ByteArrayOutputStream()) { | ||||
|       byte[] buffer = new byte[4096]; | ||||
|       int n = 0; | ||||
|       while (-1 != (n = input.read(buffer))) { | ||||
|         output.write(buffer, 0, n); | ||||
|       } | ||||
|       return output.toByteArray(); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @@ -0,0 +1,56 @@ | ||||
| package me.chanjar.weixin.common.util.http.okhttp; | ||||
|  | ||||
| import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | ||||
| import me.chanjar.weixin.common.enums.WxType; | ||||
| import me.chanjar.weixin.common.error.WxError; | ||||
| import me.chanjar.weixin.common.error.WxErrorException; | ||||
| import me.chanjar.weixin.common.util.http.InputStreamData; | ||||
| import me.chanjar.weixin.common.util.http.MediaInputStreamUploadRequestExecutor; | ||||
| import me.chanjar.weixin.common.util.http.RequestHttp; | ||||
| import okhttp3.*; | ||||
|  | ||||
| import java.io.ByteArrayOutputStream; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
|  | ||||
| /** | ||||
|  * 文件输入流上传. | ||||
|  * | ||||
|  * @author meiqin.zhou91@gmail.com | ||||
|  * @date 2022/02/15 | ||||
|  */ | ||||
| public class OkHttpMediaInputStreamUploadRequestExecutor extends MediaInputStreamUploadRequestExecutor<OkHttpClient, OkHttpProxyInfo> { | ||||
|   public OkHttpMediaInputStreamUploadRequestExecutor(RequestHttp requestHttp) { | ||||
|     super(requestHttp); | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public WxMediaUploadResult execute(String uri, InputStreamData data, WxType wxType) throws WxErrorException, IOException { | ||||
|  | ||||
|     RequestBody body = new MultipartBody.Builder() | ||||
|       .setType(MediaType.parse("multipart/form-data")) | ||||
|       .addFormDataPart("media", data.getFilename(), RequestBody.create(this.toByteArray(data.getInputStream()), MediaType.parse("application/octet-stream"))) | ||||
|       .build(); | ||||
|     Request request = new Request.Builder().url(uri).post(body).build(); | ||||
|  | ||||
|     Response response = requestHttp.getRequestHttpClient().newCall(request).execute(); | ||||
|     String responseContent = response.body().string(); | ||||
|     WxError error = WxError.fromJson(responseContent, wxType); | ||||
|     if (error.getErrorCode() != 0) { | ||||
|       throw new WxErrorException(error); | ||||
|     } | ||||
|     return WxMediaUploadResult.fromJson(responseContent); | ||||
|   } | ||||
|  | ||||
|  | ||||
|   public byte[] toByteArray(InputStream input) throws IOException { | ||||
|     try (ByteArrayOutputStream output = new ByteArrayOutputStream()) { | ||||
|       byte[] buffer = new byte[4096]; | ||||
|       int n = 0; | ||||
|       while (-1 != (n = input.read(buffer))) { | ||||
|         output.write(buffer, 0, n); | ||||
|       } | ||||
|       return output.toByteArray(); | ||||
|     } | ||||
|   } | ||||
| } | ||||
| @@ -35,6 +35,21 @@ public interface WxCpMediaService { | ||||
|   WxMediaUploadResult upload(String mediaType, String fileType, InputStream inputStream) | ||||
|     throws WxErrorException, IOException; | ||||
|  | ||||
|   /** | ||||
|    * <pre> | ||||
|    *   上传多媒体文件. | ||||
|    * </pre> | ||||
|    * | ||||
|    * @param mediaType 媒体类型, 请看{@link me.chanjar.weixin.common.api.WxConsts} | ||||
|    * @param filename  文件名.例如:wework.txt | ||||
|    * @param url       远程链接 | ||||
|    * @return | ||||
|    * @throws WxErrorException | ||||
|    * @throws IOException | ||||
|    */ | ||||
|   WxMediaUploadResult upload(String mediaType, String filename, String url) | ||||
|     throws WxErrorException, IOException; | ||||
|  | ||||
|   /** | ||||
|    * 上传多媒体文件. | ||||
|    * | ||||
|   | ||||
| @@ -5,6 +5,8 @@ import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | ||||
| import me.chanjar.weixin.common.error.WxErrorException; | ||||
| import me.chanjar.weixin.common.util.fs.FileUtils; | ||||
| import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor; | ||||
| import me.chanjar.weixin.common.util.http.InputStreamData; | ||||
| import me.chanjar.weixin.common.util.http.MediaInputStreamUploadRequestExecutor; | ||||
| import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor; | ||||
| import me.chanjar.weixin.cp.api.WxCpMediaService; | ||||
| import me.chanjar.weixin.cp.api.WxCpService; | ||||
| @@ -12,6 +14,8 @@ import me.chanjar.weixin.cp.api.WxCpService; | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.net.HttpURLConnection; | ||||
| import java.net.URL; | ||||
| import java.util.UUID; | ||||
|  | ||||
| import static me.chanjar.weixin.cp.constant.WxCpApiPathConsts.Media.*; | ||||
| @@ -34,6 +38,32 @@ public class WxCpMediaServiceImpl implements WxCpMediaService { | ||||
|     return this.upload(mediaType, FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType)); | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public WxMediaUploadResult upload(String mediaType, String filename, String url) throws WxErrorException, IOException { | ||||
|     HttpURLConnection conn = null; | ||||
|     InputStream inputStream = null; | ||||
|     try { | ||||
|       URL remote = new URL(url); | ||||
|       conn = (HttpURLConnection) remote.openConnection(); | ||||
|       //设置超时间为3秒 | ||||
|       conn.setConnectTimeout(60 * 1000); | ||||
|       //防止屏蔽程序抓取而返回403错误 | ||||
|       conn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)"); | ||||
|       inputStream = conn.getInputStream(); | ||||
|       return this.mainService.execute(MediaInputStreamUploadRequestExecutor.create(this.mainService.getRequestHttp()), this.mainService.getWxCpConfigStorage().getApiUrl(MEDIA_UPLOAD + mediaType), new InputStreamData(inputStream, filename)); | ||||
|     } finally { | ||||
|       if (inputStream != null) { | ||||
|         try { | ||||
|           inputStream.close(); | ||||
|         } catch (IOException e) { | ||||
|         } | ||||
|       } | ||||
|       if (conn != null) { | ||||
|         conn.disconnect(); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   @Override | ||||
|   public WxMediaUploadResult upload(String mediaType, File file) throws WxErrorException { | ||||
|     return this.mainService.execute(MediaUploadRequestExecutor.create(this.mainService.getRequestHttp()), | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Green Years
					Green Years