| @@ -0,0 +1,161 @@ | |||||
| package me.chanjar.weixin.common.util.http; | |||||
| import jodd.http.HttpConnectionProvider; | |||||
| import jodd.http.HttpRequest; | |||||
| import jodd.http.HttpResponse; | |||||
| import jodd.http.ProxyInfo; | |||||
| import me.chanjar.weixin.common.bean.result.WxError; | |||||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||||
| import me.chanjar.weixin.common.util.fs.FileUtils; | |||||
| import me.chanjar.weixin.common.util.http.apache.InputStreamResponseHandler; | |||||
| import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; | |||||
| import org.apache.commons.lang3.StringUtils; | |||||
| import org.apache.http.Header; | |||||
| 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.ByteArrayInputStream; | |||||
| import java.io.File; | |||||
| import java.io.IOException; | |||||
| import java.io.InputStream; | |||||
| import java.util.regex.Matcher; | |||||
| import java.util.regex.Pattern; | |||||
| /** | |||||
| * 下载媒体文件请求执行器,请求的参数是String, 返回的结果是File | |||||
| * 视频文件不支持下载 | |||||
| * | |||||
| * @author Daniel Qian | |||||
| */ | |||||
| public class MediaDownloadRequestExecutor implements RequestExecutor<File, String> { | |||||
| private File tmpDirFile; | |||||
| public MediaDownloadRequestExecutor(File tmpDirFile) { | |||||
| this.tmpDirFile = tmpDirFile; | |||||
| } | |||||
| @Override | |||||
| public File execute(RequestHttp requestHttp, String uri, String queryParam) throws WxErrorException, IOException { | |||||
| if (requestHttp.getHttpClient() instanceof CloseableHttpClient) { | |||||
| CloseableHttpClient httpClient = (CloseableHttpClient) requestHttp.getHttpClient(); | |||||
| HttpHost httpProxy = (HttpHost) requestHttp.getHttpProxy(); | |||||
| return executeApache(httpClient, httpProxy, uri, queryParam); | |||||
| } | |||||
| if (requestHttp.getHttpClient() instanceof HttpConnectionProvider) { | |||||
| HttpConnectionProvider provider = (HttpConnectionProvider) requestHttp.getHttpClient(); | |||||
| ProxyInfo proxyInfo = (ProxyInfo) requestHttp.getHttpProxy(); | |||||
| return executeJodd(provider, proxyInfo, uri, queryParam); | |||||
| } else { | |||||
| //这里需要抛出异常,需要优化 | |||||
| return null; | |||||
| } | |||||
| } | |||||
| private String getFileNameJodd(HttpResponse response) throws WxErrorException { | |||||
| String content = response.header("Content-disposition"); | |||||
| if (content == null || content.length() == 0) { | |||||
| throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build()); | |||||
| } | |||||
| Pattern p = Pattern.compile(".*filename=\"(.*)\""); | |||||
| Matcher m = p.matcher(content); | |||||
| if (m.matches()) { | |||||
| return m.group(1); | |||||
| } | |||||
| throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build()); | |||||
| } | |||||
| private String getFileNameApache(CloseableHttpResponse response) throws WxErrorException { | |||||
| Header[] contentDispositionHeader = response.getHeaders("Content-disposition"); | |||||
| if(contentDispositionHeader == null || contentDispositionHeader.length == 0){ | |||||
| throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build()); | |||||
| } | |||||
| Pattern p = Pattern.compile(".*filename=\"(.*)\""); | |||||
| Matcher m = p.matcher(contentDispositionHeader[0].getValue()); | |||||
| if(m.matches()){ | |||||
| return m.group(1); | |||||
| } | |||||
| throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build()); | |||||
| } | |||||
| private File executeApache(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, String queryParam) throws WxErrorException, IOException { | |||||
| if (queryParam != null) { | |||||
| if (uri.indexOf('?') == -1) { | |||||
| uri += '?'; | |||||
| } | |||||
| uri += uri.endsWith("?") ? queryParam : '&' + queryParam; | |||||
| } | |||||
| HttpGet httpGet = new HttpGet(uri); | |||||
| if (httpProxy != null) { | |||||
| RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build(); | |||||
| httpGet.setConfig(config); | |||||
| } | |||||
| try (CloseableHttpResponse response = httpclient.execute(httpGet); | |||||
| InputStream inputStream = InputStreamResponseHandler.INSTANCE | |||||
| .handleResponse(response)) { | |||||
| Header[] contentTypeHeader = response.getHeaders("Content-Type"); | |||||
| if (contentTypeHeader != null && contentTypeHeader.length > 0) { | |||||
| if (contentTypeHeader[0].getValue().startsWith(ContentType.APPLICATION_JSON.getMimeType())) { | |||||
| // application/json; encoding=utf-8 下载媒体文件出错 | |||||
| String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); | |||||
| throw new WxErrorException(WxError.fromJson(responseContent)); | |||||
| } | |||||
| } | |||||
| String fileName = getFileNameApache(response); | |||||
| if (StringUtils.isBlank(fileName)) { | |||||
| return null; | |||||
| } | |||||
| String[] nameAndExt = fileName.split("\\."); | |||||
| return FileUtils.createTmpFile(inputStream, nameAndExt[0], nameAndExt[1], this.tmpDirFile); | |||||
| } finally { | |||||
| httpGet.releaseConnection(); | |||||
| } | |||||
| } | |||||
| private File executeJodd(HttpConnectionProvider provider, ProxyInfo proxyInfo, String uri, String queryParam) throws WxErrorException, IOException { | |||||
| if (queryParam != null) { | |||||
| if (uri.indexOf('?') == -1) { | |||||
| uri += '?'; | |||||
| } | |||||
| uri += uri.endsWith("?") ? queryParam : '&' + queryParam; | |||||
| } | |||||
| HttpRequest request = HttpRequest.post(uri); | |||||
| if (proxyInfo != null) { | |||||
| provider.useProxy(proxyInfo); | |||||
| } | |||||
| request.withConnectionProvider(provider); | |||||
| HttpResponse response = request.send(); | |||||
| String contentType = response.header("Content-Type"); | |||||
| if (contentType != null && contentType.startsWith("application/json")) { | |||||
| // application/json; encoding=utf-8 下载媒体文件出错 | |||||
| throw new WxErrorException(WxError.fromJson(response.bodyText())); | |||||
| } | |||||
| String fileName = getFileNameJodd(response); | |||||
| if (StringUtils.isBlank(fileName)) { | |||||
| return null; | |||||
| } | |||||
| InputStream inputStream = new ByteArrayInputStream(response.bodyBytes()); | |||||
| String[] nameAndExt = fileName.split("\\."); | |||||
| return FileUtils.createTmpFile(inputStream, nameAndExt[0], nameAndExt[1], this.tmpDirFile); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,95 @@ | |||||
| package me.chanjar.weixin.common.util.http; | |||||
| import jodd.http.HttpConnectionProvider; | |||||
| import jodd.http.HttpRequest; | |||||
| import jodd.http.HttpResponse; | |||||
| import jodd.http.ProxyInfo; | |||||
| import me.chanjar.weixin.common.bean.result.WxError; | |||||
| import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | |||||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||||
| import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; | |||||
| 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.File; | |||||
| import java.io.IOException; | |||||
| /** | |||||
| * 上传媒体文件请求执行器,请求的参数是File, 返回的结果是String | |||||
| * | |||||
| * @author Daniel Qian | |||||
| */ | |||||
| public class MediaUploadRequestExecutor implements RequestExecutor<WxMediaUploadResult, File> { | |||||
| @Override | |||||
| public WxMediaUploadResult execute(RequestHttp requestHttp, String uri, File file) throws WxErrorException, IOException { | |||||
| if (requestHttp.getHttpClient() instanceof CloseableHttpClient) { | |||||
| CloseableHttpClient httpClient = (CloseableHttpClient) requestHttp.getHttpClient(); | |||||
| HttpHost httpProxy = (HttpHost) requestHttp.getHttpProxy(); | |||||
| return executeApache(httpClient, httpProxy, uri, file); | |||||
| } | |||||
| if (requestHttp.getHttpClient() instanceof HttpConnectionProvider) { | |||||
| HttpConnectionProvider provider = (HttpConnectionProvider) requestHttp.getHttpClient(); | |||||
| ProxyInfo proxyInfo = (ProxyInfo) requestHttp.getHttpProxy(); | |||||
| return executeJodd(provider, proxyInfo, uri, file); | |||||
| } else { | |||||
| //这里需要抛出异常,需要优化 | |||||
| return null; | |||||
| } | |||||
| } | |||||
| private WxMediaUploadResult executeApache(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, File file) throws WxErrorException, IOException { | |||||
| HttpPost httpPost = new HttpPost(uri); | |||||
| if (httpProxy != null) { | |||||
| RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build(); | |||||
| httpPost.setConfig(config); | |||||
| } | |||||
| if (file != null) { | |||||
| HttpEntity entity = MultipartEntityBuilder | |||||
| .create() | |||||
| .addBinaryBody("media", file) | |||||
| .setMode(HttpMultipartMode.RFC6532) | |||||
| .build(); | |||||
| httpPost.setEntity(entity); | |||||
| httpPost.setHeader("Content-Type", ContentType.MULTIPART_FORM_DATA.toString()); | |||||
| } | |||||
| try (CloseableHttpResponse response = httpclient.execute(httpPost)) { | |||||
| String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); | |||||
| WxError error = WxError.fromJson(responseContent); | |||||
| if (error.getErrorCode() != 0) { | |||||
| throw new WxErrorException(error); | |||||
| } | |||||
| return WxMediaUploadResult.fromJson(responseContent); | |||||
| } finally { | |||||
| httpPost.releaseConnection(); | |||||
| } | |||||
| } | |||||
| private WxMediaUploadResult executeJodd(HttpConnectionProvider provider, ProxyInfo proxyInfo, String uri, File file) throws WxErrorException, IOException { | |||||
| HttpRequest request = HttpRequest.post(uri); | |||||
| if (proxyInfo != null) { | |||||
| provider.useProxy(proxyInfo); | |||||
| } | |||||
| request.withConnectionProvider(provider); | |||||
| request.form("media", file); | |||||
| HttpResponse response = request.send(); | |||||
| String responseContent = response.bodyText(); | |||||
| WxError error = WxError.fromJson(responseContent); | |||||
| if (error.getErrorCode() != 0) { | |||||
| throw new WxErrorException(error); | |||||
| } | |||||
| return WxMediaUploadResult.fromJson(responseContent); | |||||
| } | |||||
| } | |||||
| @@ -10,16 +10,14 @@ import java.io.IOException; | |||||
| * @param <T> 返回值类型 | * @param <T> 返回值类型 | ||||
| * @param <E> 请求参数类型 | * @param <E> 请求参数类型 | ||||
| */ | */ | ||||
| public interface RequestExecutor<T, H, P, E> { | |||||
| public interface RequestExecutor<T, E> { | |||||
| /** | /** | ||||
| * @param httpClient | |||||
| * @param httpProxy http代理对象,如果没有配置代理则为空 | |||||
| * @param uri uri | |||||
| * @param data 数据 | |||||
| * @param uri uri | |||||
| * @param data 数据 | |||||
| * @throws WxErrorException | * @throws WxErrorException | ||||
| * @throws IOException | * @throws IOException | ||||
| */ | */ | ||||
| T execute(H httpClient, P httpProxy, String uri, E data) throws WxErrorException, IOException; | |||||
| T execute(RequestHttp requestHttp, String uri, E data) throws WxErrorException, IOException; | |||||
| } | } | ||||
| @@ -0,0 +1,20 @@ | |||||
| package me.chanjar.weixin.common.util.http; | |||||
| /** | |||||
| * Created by ecoolper on 2017/4/22. | |||||
| */ | |||||
| public interface RequestHttp { | |||||
| /** | |||||
| * httpClient | |||||
| * @return | |||||
| */ | |||||
| Object getHttpClient(); | |||||
| /** | |||||
| * httpProxy | |||||
| * @return | |||||
| */ | |||||
| Object getHttpProxy(); | |||||
| } | |||||
| @@ -0,0 +1,91 @@ | |||||
| package me.chanjar.weixin.common.util.http; | |||||
| import jodd.http.HttpConnectionProvider; | |||||
| import jodd.http.HttpRequest; | |||||
| import jodd.http.HttpResponse; | |||||
| import jodd.http.ProxyInfo; | |||||
| import me.chanjar.weixin.common.bean.result.WxError; | |||||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||||
| import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; | |||||
| 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.impl.client.CloseableHttpClient; | |||||
| import java.io.IOException; | |||||
| /** | |||||
| * 简单的GET请求执行器,请求的参数是String, 返回的结果也是String | |||||
| * | |||||
| * @author Daniel Qian | |||||
| */ | |||||
| public class SimpleGetRequestExecutor implements RequestExecutor<String, String> { | |||||
| @Override | |||||
| public String execute(RequestHttp requestHttp, String uri, String queryParam) throws WxErrorException, IOException { | |||||
| if (requestHttp.getHttpClient() instanceof CloseableHttpClient) { | |||||
| CloseableHttpClient httpClient = (CloseableHttpClient) requestHttp.getHttpClient(); | |||||
| HttpHost httpProxy = (HttpHost) requestHttp.getHttpProxy(); | |||||
| return executeApache(httpClient, httpProxy, uri, queryParam); | |||||
| } | |||||
| if (requestHttp.getHttpClient() instanceof HttpConnectionProvider) { | |||||
| HttpConnectionProvider provider = (HttpConnectionProvider) requestHttp.getHttpClient(); | |||||
| ProxyInfo proxyInfo = (ProxyInfo) requestHttp.getHttpProxy(); | |||||
| return executeJodd(provider, proxyInfo, uri, queryParam); | |||||
| } else { | |||||
| //这里需要抛出异常,需要优化 | |||||
| return null; | |||||
| } | |||||
| } | |||||
| private String executeApache(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, String queryParam) throws WxErrorException, IOException { | |||||
| if (queryParam != null) { | |||||
| if (uri.indexOf('?') == -1) { | |||||
| uri += '?'; | |||||
| } | |||||
| uri += uri.endsWith("?") ? queryParam : '&' + queryParam; | |||||
| } | |||||
| HttpGet httpGet = new HttpGet(uri); | |||||
| if (httpProxy != null) { | |||||
| RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build(); | |||||
| httpGet.setConfig(config); | |||||
| } | |||||
| try (CloseableHttpResponse response = httpclient.execute(httpGet)) { | |||||
| String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); | |||||
| WxError error = WxError.fromJson(responseContent); | |||||
| if (error.getErrorCode() != 0) { | |||||
| throw new WxErrorException(error); | |||||
| } | |||||
| return responseContent; | |||||
| } finally { | |||||
| httpGet.releaseConnection(); | |||||
| } | |||||
| } | |||||
| private String executeJodd(HttpConnectionProvider provider, ProxyInfo proxyInfo, String uri, String queryParam) throws WxErrorException, IOException { | |||||
| if (queryParam != null) { | |||||
| if (uri.indexOf('?') == -1) { | |||||
| uri += '?'; | |||||
| } | |||||
| uri += uri.endsWith("?") ? queryParam : '&' + queryParam; | |||||
| } | |||||
| HttpRequest request = HttpRequest.get(uri); | |||||
| if (proxyInfo != null) { | |||||
| provider.useProxy(proxyInfo); | |||||
| } | |||||
| request.withConnectionProvider(provider); | |||||
| HttpResponse response = request.send(); | |||||
| String responseContent = response.bodyText(); | |||||
| WxError error = WxError.fromJson(responseContent); | |||||
| if (error.getErrorCode() != 0) { | |||||
| throw new WxErrorException(error); | |||||
| } | |||||
| return responseContent; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,112 @@ | |||||
| package me.chanjar.weixin.common.util.http; | |||||
| import jodd.http.HttpConnectionProvider; | |||||
| import jodd.http.HttpRequest; | |||||
| import jodd.http.HttpResponse; | |||||
| import jodd.http.ProxyInfo; | |||||
| import me.chanjar.weixin.common.bean.result.WxError; | |||||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||||
| import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; | |||||
| import org.apache.http.Consts; | |||||
| 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.StringEntity; | |||||
| import org.apache.http.impl.client.CloseableHttpClient; | |||||
| import java.io.IOException; | |||||
| /** | |||||
| * 用装饰模式实现 | |||||
| * 简单的POST请求执行器,请求的参数是String, 返回的结果也是String | |||||
| * | |||||
| * @author Daniel Qian | |||||
| */ | |||||
| public class SimplePostRequestExecutor implements RequestExecutor<String, String> { | |||||
| @Override | |||||
| public String execute(RequestHttp requestHttp, String uri, String postEntity) throws WxErrorException, IOException { | |||||
| if (requestHttp.getHttpClient() instanceof CloseableHttpClient) { | |||||
| CloseableHttpClient httpClient = (CloseableHttpClient) requestHttp.getHttpClient(); | |||||
| HttpHost httpProxy = (HttpHost) requestHttp.getHttpProxy(); | |||||
| return executeApache(httpClient, httpProxy, uri, postEntity); | |||||
| } | |||||
| if (requestHttp.getHttpClient() instanceof HttpConnectionProvider) { | |||||
| HttpConnectionProvider provider = (HttpConnectionProvider) requestHttp.getHttpClient(); | |||||
| ProxyInfo proxyInfo = (ProxyInfo) requestHttp.getHttpProxy(); | |||||
| return executeJodd(provider, proxyInfo, uri, postEntity); | |||||
| } else { | |||||
| //这里需要抛出异常,需要优化 | |||||
| return null; | |||||
| } | |||||
| } | |||||
| private String executeApache(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, String postEntity) throws WxErrorException, IOException { | |||||
| HttpPost httpPost = new HttpPost(uri); | |||||
| if (httpProxy != null) { | |||||
| RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build(); | |||||
| httpPost.setConfig(config); | |||||
| } | |||||
| if (postEntity != null) { | |||||
| StringEntity entity = new StringEntity(postEntity, Consts.UTF_8); | |||||
| httpPost.setEntity(entity); | |||||
| } | |||||
| try (CloseableHttpResponse response = httpclient.execute(httpPost)) { | |||||
| String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); | |||||
| if (responseContent.isEmpty()) { | |||||
| throw new WxErrorException( | |||||
| WxError.newBuilder().setErrorCode(9999).setErrorMsg("无响应内容") | |||||
| .build()); | |||||
| } | |||||
| if (responseContent.startsWith("<xml>")) { | |||||
| //xml格式输出直接返回 | |||||
| return responseContent; | |||||
| } | |||||
| WxError error = WxError.fromJson(responseContent); | |||||
| if (error.getErrorCode() != 0) { | |||||
| throw new WxErrorException(error); | |||||
| } | |||||
| return responseContent; | |||||
| } finally { | |||||
| httpPost.releaseConnection(); | |||||
| } | |||||
| } | |||||
| private String executeJodd(HttpConnectionProvider provider, ProxyInfo proxyInfo, String uri, String postEntity) throws WxErrorException, IOException { | |||||
| HttpRequest request = HttpRequest.post(uri); | |||||
| if (proxyInfo != null) { | |||||
| provider.useProxy(proxyInfo); | |||||
| } | |||||
| request.withConnectionProvider(provider); | |||||
| if (postEntity != null) { | |||||
| request.bodyText(postEntity); | |||||
| } | |||||
| HttpResponse response = request.send(); | |||||
| String responseContent = response.bodyText(); | |||||
| if (responseContent.isEmpty()) { | |||||
| throw new WxErrorException( | |||||
| WxError.newBuilder().setErrorCode(9999).setErrorMsg("无响应内容") | |||||
| .build()); | |||||
| } | |||||
| if (responseContent.startsWith("<xml>")) { | |||||
| //xml格式输出直接返回 | |||||
| return responseContent; | |||||
| } | |||||
| WxError error = WxError.fromJson(responseContent); | |||||
| if (error.getErrorCode() != 0) { | |||||
| throw new WxErrorException(error); | |||||
| } | |||||
| return responseContent; | |||||
| } | |||||
| } | |||||
| @@ -1,94 +0,0 @@ | |||||
| package me.chanjar.weixin.common.util.http.apache; | |||||
| import me.chanjar.weixin.common.bean.result.WxError; | |||||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||||
| import me.chanjar.weixin.common.util.fs.FileUtils; | |||||
| import me.chanjar.weixin.common.util.http.RequestExecutor; | |||||
| import org.apache.commons.lang3.StringUtils; | |||||
| import org.apache.http.Header; | |||||
| 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.File; | |||||
| import java.io.IOException; | |||||
| import java.io.InputStream; | |||||
| import java.util.regex.Matcher; | |||||
| import java.util.regex.Pattern; | |||||
| /** | |||||
| * 下载媒体文件请求执行器,请求的参数是String, 返回的结果是File | |||||
| * 视频文件不支持下载 | |||||
| * @author Daniel Qian | |||||
| */ | |||||
| public class MediaDownloadRequestExecutor implements RequestExecutor<File, CloseableHttpClient, HttpHost,String> { | |||||
| private File tmpDirFile; | |||||
| public MediaDownloadRequestExecutor() { | |||||
| } | |||||
| public MediaDownloadRequestExecutor(File tmpDirFile) { | |||||
| this.tmpDirFile = tmpDirFile; | |||||
| } | |||||
| @Override | |||||
| public File execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, String queryParam) throws WxErrorException, IOException { | |||||
| if (queryParam != null) { | |||||
| if (uri.indexOf('?') == -1) { | |||||
| uri += '?'; | |||||
| } | |||||
| uri += uri.endsWith("?") ? queryParam : '&' + queryParam; | |||||
| } | |||||
| HttpGet httpGet = new HttpGet(uri); | |||||
| if (httpProxy != null) { | |||||
| RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build(); | |||||
| httpGet.setConfig(config); | |||||
| } | |||||
| try (CloseableHttpResponse response = httpclient.execute(httpGet); | |||||
| InputStream inputStream = InputStreamResponseHandler.INSTANCE | |||||
| .handleResponse(response)) { | |||||
| Header[] contentTypeHeader = response.getHeaders("Content-Type"); | |||||
| if (contentTypeHeader != null && contentTypeHeader.length > 0) { | |||||
| if (contentTypeHeader[0].getValue().startsWith(ContentType.APPLICATION_JSON.getMimeType())) { | |||||
| // application/json; encoding=utf-8 下载媒体文件出错 | |||||
| String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); | |||||
| throw new WxErrorException(WxError.fromJson(responseContent)); | |||||
| } | |||||
| } | |||||
| String fileName = getFileName(response); | |||||
| if (StringUtils.isBlank(fileName)) { | |||||
| return null; | |||||
| } | |||||
| String[] nameAndExt = fileName.split("\\."); | |||||
| return FileUtils.createTmpFile(inputStream, nameAndExt[0], nameAndExt[1], this.tmpDirFile); | |||||
| } finally { | |||||
| httpGet.releaseConnection(); | |||||
| } | |||||
| } | |||||
| private String getFileName(CloseableHttpResponse response) throws WxErrorException { | |||||
| Header[] contentDispositionHeader = response.getHeaders("Content-disposition"); | |||||
| if(contentDispositionHeader == null || contentDispositionHeader.length == 0){ | |||||
| throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build()); | |||||
| } | |||||
| Pattern p = Pattern.compile(".*filename=\"(.*)\""); | |||||
| Matcher m = p.matcher(contentDispositionHeader[0].getValue()); | |||||
| if(m.matches()){ | |||||
| return m.group(1); | |||||
| } | |||||
| throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build()); | |||||
| } | |||||
| } | |||||
| @@ -1,55 +0,0 @@ | |||||
| package me.chanjar.weixin.common.util.http.apache; | |||||
| import me.chanjar.weixin.common.bean.result.WxError; | |||||
| import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | |||||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||||
| import me.chanjar.weixin.common.util.http.RequestExecutor; | |||||
| 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.File; | |||||
| import java.io.IOException; | |||||
| /** | |||||
| * 上传媒体文件请求执行器,请求的参数是File, 返回的结果是String | |||||
| * | |||||
| * @author Daniel Qian | |||||
| */ | |||||
| public class MediaUploadRequestExecutor implements RequestExecutor<WxMediaUploadResult, CloseableHttpClient, HttpHost,File> { | |||||
| @Override | |||||
| public WxMediaUploadResult execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, File file) throws WxErrorException, IOException { | |||||
| HttpPost httpPost = new HttpPost(uri); | |||||
| if (httpProxy != null) { | |||||
| RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build(); | |||||
| httpPost.setConfig(config); | |||||
| } | |||||
| if (file != null) { | |||||
| HttpEntity entity = MultipartEntityBuilder | |||||
| .create() | |||||
| .addBinaryBody("media", file) | |||||
| .setMode(HttpMultipartMode.RFC6532) | |||||
| .build(); | |||||
| httpPost.setEntity(entity); | |||||
| httpPost.setHeader("Content-Type", ContentType.MULTIPART_FORM_DATA.toString()); | |||||
| } | |||||
| try (CloseableHttpResponse response = httpclient.execute(httpPost)) { | |||||
| String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); | |||||
| WxError error = WxError.fromJson(responseContent); | |||||
| if (error.getErrorCode() != 0) { | |||||
| throw new WxErrorException(error); | |||||
| } | |||||
| return WxMediaUploadResult.fromJson(responseContent); | |||||
| } finally { | |||||
| httpPost.releaseConnection(); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -1,47 +0,0 @@ | |||||
| package me.chanjar.weixin.common.util.http.apache; | |||||
| import me.chanjar.weixin.common.bean.result.WxError; | |||||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||||
| import me.chanjar.weixin.common.util.http.RequestExecutor; | |||||
| 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.impl.client.CloseableHttpClient; | |||||
| import java.io.IOException; | |||||
| /** | |||||
| * 简单的GET请求执行器,请求的参数是String, 返回的结果也是String | |||||
| * | |||||
| * @author Daniel Qian | |||||
| */ | |||||
| public class SimpleGetRequestExecutor implements RequestExecutor<String, CloseableHttpClient, HttpHost, String> { | |||||
| @Override | |||||
| public String execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, String queryParam) throws WxErrorException, IOException { | |||||
| if (queryParam != null) { | |||||
| if (uri.indexOf('?') == -1) { | |||||
| uri += '?'; | |||||
| } | |||||
| uri += uri.endsWith("?") ? queryParam : '&' + queryParam; | |||||
| } | |||||
| HttpGet httpGet = new HttpGet(uri); | |||||
| if (httpProxy != null) { | |||||
| RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build(); | |||||
| httpGet.setConfig(config); | |||||
| } | |||||
| try (CloseableHttpResponse response = httpclient.execute(httpGet)) { | |||||
| String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); | |||||
| WxError error = WxError.fromJson(responseContent); | |||||
| if (error.getErrorCode() != 0) { | |||||
| throw new WxErrorException(error); | |||||
| } | |||||
| return responseContent; | |||||
| } finally { | |||||
| httpGet.releaseConnection(); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -1,59 +0,0 @@ | |||||
| package me.chanjar.weixin.common.util.http.apache; | |||||
| import me.chanjar.weixin.common.bean.result.WxError; | |||||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||||
| import me.chanjar.weixin.common.util.http.RequestExecutor; | |||||
| import org.apache.http.Consts; | |||||
| 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.StringEntity; | |||||
| import org.apache.http.impl.client.CloseableHttpClient; | |||||
| import java.io.IOException; | |||||
| /** | |||||
| * 简单的POST请求执行器,请求的参数是String, 返回的结果也是String | |||||
| * | |||||
| * @author Daniel Qian | |||||
| */ | |||||
| public class SimplePostRequestExecutor implements RequestExecutor<String, CloseableHttpClient, HttpHost, String> { | |||||
| @Override | |||||
| public String execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, String postEntity) throws WxErrorException, IOException { | |||||
| HttpPost httpPost = new HttpPost(uri); | |||||
| if (httpProxy != null) { | |||||
| RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build(); | |||||
| httpPost.setConfig(config); | |||||
| } | |||||
| if (postEntity != null) { | |||||
| StringEntity entity = new StringEntity(postEntity, Consts.UTF_8); | |||||
| httpPost.setEntity(entity); | |||||
| } | |||||
| try (CloseableHttpResponse response = httpclient.execute(httpPost)) { | |||||
| String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); | |||||
| if (responseContent.isEmpty()) { | |||||
| throw new WxErrorException( | |||||
| WxError.newBuilder().setErrorCode(9999).setErrorMsg("无响应内容") | |||||
| .build()); | |||||
| } | |||||
| if (responseContent.startsWith("<xml>")) { | |||||
| //xml格式输出直接返回 | |||||
| return responseContent; | |||||
| } | |||||
| WxError error = WxError.fromJson(responseContent); | |||||
| if (error.getErrorCode() != 0) { | |||||
| throw new WxErrorException(error); | |||||
| } | |||||
| return responseContent; | |||||
| } finally { | |||||
| httpPost.releaseConnection(); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -1,82 +0,0 @@ | |||||
| 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 me.chanjar.weixin.common.bean.result.WxError; | |||||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||||
| import me.chanjar.weixin.common.util.fs.FileUtils; | |||||
| import me.chanjar.weixin.common.util.http.RequestExecutor; | |||||
| import org.apache.commons.lang3.StringUtils; | |||||
| import java.io.ByteArrayInputStream; | |||||
| import java.io.File; | |||||
| import java.io.IOException; | |||||
| import java.io.InputStream; | |||||
| import java.util.regex.Matcher; | |||||
| import java.util.regex.Pattern; | |||||
| /** | |||||
| * 下载媒体文件请求执行器,请求的参数是String, 返回的结果是File | |||||
| * 视频文件不支持下载 | |||||
| * | |||||
| * @author Daniel Qian | |||||
| */ | |||||
| public class MediaDownloadRequestExecutor implements RequestExecutor<File, HttpConnectionProvider, ProxyInfo, String> { | |||||
| private File tmpDirFile; | |||||
| public MediaDownloadRequestExecutor() { | |||||
| } | |||||
| public MediaDownloadRequestExecutor(File tmpDirFile) { | |||||
| this.tmpDirFile = tmpDirFile; | |||||
| } | |||||
| @Override | |||||
| public File execute(HttpConnectionProvider provider, ProxyInfo httpProxy, String uri, String queryParam) throws WxErrorException, IOException { | |||||
| if (queryParam != null) { | |||||
| if (uri.indexOf('?') == -1) { | |||||
| uri += '?'; | |||||
| } | |||||
| uri += uri.endsWith("?") ? queryParam : '&' + queryParam; | |||||
| } | |||||
| HttpRequest request = HttpRequest.post(uri); | |||||
| if (httpProxy != null) { | |||||
| provider.useProxy(httpProxy); | |||||
| } | |||||
| request.withConnectionProvider(provider); | |||||
| HttpResponse response = request.send(); | |||||
| String contentType = response.header("Content-Type"); | |||||
| if (contentType != null && contentType.startsWith("application/json")) { | |||||
| // application/json; encoding=utf-8 下载媒体文件出错 | |||||
| throw new WxErrorException(WxError.fromJson(response.bodyText())); | |||||
| } | |||||
| String fileName = getFileName(response); | |||||
| if (StringUtils.isBlank(fileName)) { | |||||
| return null; | |||||
| } | |||||
| InputStream inputStream = new ByteArrayInputStream(response.bodyBytes()); | |||||
| String[] nameAndExt = fileName.split("\\."); | |||||
| return FileUtils.createTmpFile(inputStream, nameAndExt[0], nameAndExt[1], this.tmpDirFile); | |||||
| } | |||||
| private String getFileName(HttpResponse response) throws WxErrorException { | |||||
| String content = response.header("Content-disposition"); | |||||
| if (content == null || content.length() == 0) { | |||||
| throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build()); | |||||
| } | |||||
| Pattern p = Pattern.compile(".*filename=\"(.*)\""); | |||||
| Matcher m = p.matcher(content); | |||||
| if (m.matches()) { | |||||
| return m.group(1); | |||||
| } | |||||
| throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build()); | |||||
| } | |||||
| } | |||||
| @@ -1,39 +0,0 @@ | |||||
| 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 me.chanjar.weixin.common.bean.result.WxError; | |||||
| import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | |||||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||||
| import me.chanjar.weixin.common.util.http.RequestExecutor; | |||||
| import java.io.File; | |||||
| import java.io.IOException; | |||||
| /** | |||||
| * 上传媒体文件请求执行器,请求的参数是File, 返回的结果是String | |||||
| * | |||||
| * @author Daniel Qian | |||||
| */ | |||||
| public class MediaUploadRequestExecutor implements RequestExecutor<WxMediaUploadResult, HttpConnectionProvider, ProxyInfo, File> { | |||||
| @Override | |||||
| public WxMediaUploadResult execute(HttpConnectionProvider provider, ProxyInfo httpProxy, String uri, File file) throws WxErrorException, IOException { | |||||
| HttpRequest request = HttpRequest.post(uri); | |||||
| if (httpProxy != null) { | |||||
| provider.useProxy(httpProxy); | |||||
| } | |||||
| request.withConnectionProvider(provider); | |||||
| request.form("media", file); | |||||
| HttpResponse response = request.send(); | |||||
| String responseContent =response.bodyText(); | |||||
| WxError error = WxError.fromJson(responseContent); | |||||
| if (error.getErrorCode() != 0) { | |||||
| throw new WxErrorException(error); | |||||
| } | |||||
| return WxMediaUploadResult.fromJson(responseContent); | |||||
| } | |||||
| } | |||||
| @@ -1,43 +0,0 @@ | |||||
| 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 me.chanjar.weixin.common.bean.result.WxError; | |||||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||||
| import me.chanjar.weixin.common.util.http.RequestExecutor; | |||||
| import java.io.IOException; | |||||
| /** | |||||
| * 简单的GET请求执行器,请求的参数是String, 返回的结果也是String | |||||
| * | |||||
| * @author Daniel Qian | |||||
| */ | |||||
| public class SimpleGetRequestExecutor implements RequestExecutor<String, HttpConnectionProvider, ProxyInfo, String> { | |||||
| @Override | |||||
| public String execute(HttpConnectionProvider provider, ProxyInfo httpProxy, String uri, String queryParam) throws WxErrorException, IOException { | |||||
| if (queryParam != null) { | |||||
| if (uri.indexOf('?') == -1) { | |||||
| uri += '?'; | |||||
| } | |||||
| uri += uri.endsWith("?") ? queryParam : '&' + queryParam; | |||||
| } | |||||
| HttpRequest request = HttpRequest.get(uri); | |||||
| if (httpProxy != null) { | |||||
| provider.useProxy(httpProxy); | |||||
| } | |||||
| request.withConnectionProvider(provider); | |||||
| HttpResponse response = request.send(); | |||||
| String responseContent = response.bodyText(); | |||||
| WxError error = WxError.fromJson(responseContent); | |||||
| if (error.getErrorCode() != 0) { | |||||
| throw new WxErrorException(error); | |||||
| } | |||||
| return responseContent; | |||||
| } | |||||
| } | |||||
| @@ -1,51 +0,0 @@ | |||||
| 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 me.chanjar.weixin.common.bean.result.WxError; | |||||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||||
| import me.chanjar.weixin.common.util.http.RequestExecutor; | |||||
| import java.io.IOException; | |||||
| /** | |||||
| * 简单的POST请求执行器,请求的参数是String, 返回的结果也是String | |||||
| * | |||||
| * @author Daniel Qian | |||||
| */ | |||||
| public class SimplePostRequestExecutor implements RequestExecutor<String, HttpConnectionProvider, ProxyInfo, String> { | |||||
| @Override | |||||
| public String execute(HttpConnectionProvider provider, ProxyInfo httpProxy, String uri, String postEntity) throws WxErrorException, IOException { | |||||
| HttpRequest request = HttpRequest.post(uri); | |||||
| if (httpProxy != null) { | |||||
| provider.useProxy(httpProxy); | |||||
| } | |||||
| request.withConnectionProvider(provider); | |||||
| if (postEntity != null) { | |||||
| request.bodyText(postEntity); | |||||
| } | |||||
| HttpResponse response = request.send(); | |||||
| String responseContent = response.bodyText(); | |||||
| if (responseContent.isEmpty()) { | |||||
| throw new WxErrorException( | |||||
| WxError.newBuilder().setErrorCode(9999).setErrorMsg("无响应内容") | |||||
| .build()); | |||||
| } | |||||
| if (responseContent.startsWith("<xml>")) { | |||||
| //xml格式输出直接返回 | |||||
| return responseContent; | |||||
| } | |||||
| WxError error = WxError.fromJson(responseContent); | |||||
| if (error.getErrorCode() != 0) { | |||||
| throw new WxErrorException(error); | |||||
| } | |||||
| return responseContent; | |||||
| } | |||||
| } | |||||