2、实现了okhttp请求方式 3、RequestExecute接口添加executeApache、executeJodd、executeOkhttp方法master
| @@ -39,11 +39,6 @@ | |||||
| <artifactId>jetty-servlet</artifactId> | <artifactId>jetty-servlet</artifactId> | ||||
| <scope>test</scope> | <scope>test</scope> | ||||
| </dependency> | </dependency> | ||||
| <dependency> | |||||
| <groupId>org.jodd</groupId> | |||||
| <artifactId>jodd-http</artifactId> | |||||
| <version>3.7</version> | |||||
| </dependency> | |||||
| </dependencies> | </dependencies> | ||||
| <build> | <build> | ||||
| @@ -0,0 +1,43 @@ | |||||
| package me.chanjar.weixin.common.util.http; | |||||
| import java.io.IOException; | |||||
| import org.apache.http.HttpHost; | |||||
| import org.apache.http.impl.client.CloseableHttpClient; | |||||
| import jodd.http.HttpConnectionProvider; | |||||
| import jodd.http.ProxyInfo; | |||||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||||
| import me.chanjar.weixin.common.util.http.okhttp.OkhttpProxyInfo; | |||||
| import okhttp3.ConnectionPool; | |||||
| /** | |||||
| * Created by ecoolper on 2017/4/27. | |||||
| */ | |||||
| public abstract class AbstractRequestExecutor<T, E> implements RequestExecutor<T, E> { | |||||
| @Override | |||||
| public T execute(RequestHttp requestHttp, String uri, E data) throws WxErrorException, IOException{ | |||||
| if (requestHttp.getRequestHttpClient() instanceof CloseableHttpClient) { | |||||
| //apache-http请求 | |||||
| CloseableHttpClient httpClient = (CloseableHttpClient) requestHttp.getRequestHttpClient(); | |||||
| HttpHost httpProxy = (HttpHost) requestHttp.getRequestHttpProxy(); | |||||
| return executeApache(httpClient, httpProxy, uri, data); | |||||
| } | |||||
| if (requestHttp.getRequestHttpClient() instanceof HttpConnectionProvider) { | |||||
| //jodd-http请求 | |||||
| HttpConnectionProvider provider = (HttpConnectionProvider) requestHttp.getRequestHttpClient(); | |||||
| ProxyInfo proxyInfo = (ProxyInfo) requestHttp.getRequestHttpProxy(); | |||||
| return executeJodd(provider, proxyInfo, uri, data); | |||||
| } else if (requestHttp.getRequestHttpClient() instanceof ConnectionPool) { | |||||
| //okhttp请求 | |||||
| ConnectionPool pool = (ConnectionPool) requestHttp.getRequestHttpClient(); | |||||
| OkhttpProxyInfo proxyInfo = (OkhttpProxyInfo) requestHttp.getRequestHttpProxy(); | |||||
| return executeOkhttp(pool, proxyInfo, uri, data); | |||||
| } else { | |||||
| //TODO 这里需要抛出异常,需要优化 | |||||
| return null; | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -5,10 +5,14 @@ import jodd.http.HttpRequest; | |||||
| import jodd.http.HttpResponse; | import jodd.http.HttpResponse; | ||||
| import jodd.http.ProxyInfo; | import jodd.http.ProxyInfo; | ||||
| import me.chanjar.weixin.common.bean.result.WxError; | 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.exception.WxErrorException; | ||||
| import me.chanjar.weixin.common.util.fs.FileUtils; | 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.InputStreamResponseHandler; | ||||
| import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; | import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; | ||||
| import me.chanjar.weixin.common.util.http.okhttp.OkhttpProxyInfo; | |||||
| import okhttp3.*; | |||||
| import org.apache.commons.lang3.StringUtils; | import org.apache.commons.lang3.StringUtils; | ||||
| import org.apache.http.Header; | import org.apache.http.Header; | ||||
| import org.apache.http.HttpHost; | import org.apache.http.HttpHost; | ||||
| @@ -22,6 +26,8 @@ import java.io.ByteArrayInputStream; | |||||
| import java.io.File; | import java.io.File; | ||||
| import java.io.IOException; | import java.io.IOException; | ||||
| import java.io.InputStream; | import java.io.InputStream; | ||||
| import java.net.InetSocketAddress; | |||||
| import java.net.Proxy; | |||||
| import java.util.regex.Matcher; | import java.util.regex.Matcher; | ||||
| import java.util.regex.Pattern; | import java.util.regex.Pattern; | ||||
| @@ -31,7 +37,7 @@ import java.util.regex.Pattern; | |||||
| * | * | ||||
| * @author Daniel Qian | * @author Daniel Qian | ||||
| */ | */ | ||||
| public class MediaDownloadRequestExecutor implements RequestExecutor<File, String> { | |||||
| public class MediaDownloadRequestExecutor extends AbstractRequestExecutor<File, String> { | |||||
| private File tmpDirFile; | private File tmpDirFile; | ||||
| @@ -39,24 +45,7 @@ public class MediaDownloadRequestExecutor implements RequestExecutor<File, Strin | |||||
| this.tmpDirFile = tmpDirFile; | this.tmpDirFile = tmpDirFile; | ||||
| } | } | ||||
| @Override | |||||
| public File execute(RequestHttp requestHttp, String uri, String queryParam) throws WxErrorException, IOException { | |||||
| if (requestHttp.getRequestHttpClient() instanceof CloseableHttpClient) { | |||||
| CloseableHttpClient httpClient = (CloseableHttpClient) requestHttp.getRequestHttpClient(); | |||||
| HttpHost httpProxy = (HttpHost) requestHttp.getRequestHttpProxy(); | |||||
| return executeApache(httpClient, httpProxy, uri, queryParam); | |||||
| } | |||||
| if (requestHttp.getRequestHttpClient() instanceof HttpConnectionProvider) { | |||||
| HttpConnectionProvider provider = (HttpConnectionProvider) requestHttp.getRequestHttpClient(); | |||||
| ProxyInfo proxyInfo = (ProxyInfo) requestHttp.getRequestHttpProxy(); | |||||
| return executeJodd(provider, proxyInfo, uri, queryParam); | |||||
| } else { | |||||
| //这里需要抛出异常,需要优化 | |||||
| return null; | |||||
| } | |||||
| } | |||||
| private String getFileNameJodd(HttpResponse response) throws WxErrorException { | |||||
| private String getFileName(HttpResponse response) throws WxErrorException { | |||||
| String content = response.header("Content-disposition"); | String content = response.header("Content-disposition"); | ||||
| if (content == null || content.length() == 0) { | if (content == null || content.length() == 0) { | ||||
| throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build()); | throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build()); | ||||
| @@ -70,15 +59,15 @@ public class MediaDownloadRequestExecutor implements RequestExecutor<File, Strin | |||||
| throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build()); | throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build()); | ||||
| } | } | ||||
| private String getFileNameApache(CloseableHttpResponse response) throws WxErrorException { | |||||
| private String getFileName(CloseableHttpResponse response) throws WxErrorException { | |||||
| Header[] contentDispositionHeader = response.getHeaders("Content-disposition"); | Header[] contentDispositionHeader = response.getHeaders("Content-disposition"); | ||||
| if(contentDispositionHeader == null || contentDispositionHeader.length == 0){ | |||||
| if (contentDispositionHeader == null || contentDispositionHeader.length == 0) { | |||||
| throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build()); | throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build()); | ||||
| } | } | ||||
| Pattern p = Pattern.compile(".*filename=\"(.*)\""); | Pattern p = Pattern.compile(".*filename=\"(.*)\""); | ||||
| Matcher m = p.matcher(contentDispositionHeader[0].getValue()); | Matcher m = p.matcher(contentDispositionHeader[0].getValue()); | ||||
| if(m.matches()){ | |||||
| if (m.matches()) { | |||||
| return m.group(1); | return m.group(1); | ||||
| } | } | ||||
| throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build()); | throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build()); | ||||
| @@ -87,6 +76,7 @@ public class MediaDownloadRequestExecutor implements RequestExecutor<File, Strin | |||||
| /** | /** | ||||
| * apache-http实现方式 | * apache-http实现方式 | ||||
| * | |||||
| * @param httpclient | * @param httpclient | ||||
| * @param httpProxy | * @param httpProxy | ||||
| * @param uri | * @param uri | ||||
| @@ -95,7 +85,7 @@ public class MediaDownloadRequestExecutor implements RequestExecutor<File, Strin | |||||
| * @throws WxErrorException | * @throws WxErrorException | ||||
| * @throws IOException | * @throws IOException | ||||
| */ | */ | ||||
| private File executeApache(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, String queryParam) throws WxErrorException, IOException { | |||||
| public File executeApache(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, String queryParam) throws WxErrorException, IOException { | |||||
| if (queryParam != null) { | if (queryParam != null) { | ||||
| if (uri.indexOf('?') == -1) { | if (uri.indexOf('?') == -1) { | ||||
| uri += '?'; | uri += '?'; | ||||
| @@ -112,7 +102,6 @@ public class MediaDownloadRequestExecutor implements RequestExecutor<File, Strin | |||||
| try (CloseableHttpResponse response = httpclient.execute(httpGet); | try (CloseableHttpResponse response = httpclient.execute(httpGet); | ||||
| InputStream inputStream = InputStreamResponseHandler.INSTANCE | InputStream inputStream = InputStreamResponseHandler.INSTANCE | ||||
| .handleResponse(response)) { | .handleResponse(response)) { | ||||
| Header[] contentTypeHeader = response.getHeaders("Content-Type"); | Header[] contentTypeHeader = response.getHeaders("Content-Type"); | ||||
| if (contentTypeHeader != null && contentTypeHeader.length > 0) { | if (contentTypeHeader != null && contentTypeHeader.length > 0) { | ||||
| if (contentTypeHeader[0].getValue().startsWith(ContentType.APPLICATION_JSON.getMimeType())) { | if (contentTypeHeader[0].getValue().startsWith(ContentType.APPLICATION_JSON.getMimeType())) { | ||||
| @@ -122,7 +111,7 @@ public class MediaDownloadRequestExecutor implements RequestExecutor<File, Strin | |||||
| } | } | ||||
| } | } | ||||
| String fileName = getFileNameApache(response); | |||||
| String fileName = getFileName(response); | |||||
| if (StringUtils.isBlank(fileName)) { | if (StringUtils.isBlank(fileName)) { | ||||
| return null; | return null; | ||||
| } | } | ||||
| @@ -139,6 +128,7 @@ public class MediaDownloadRequestExecutor implements RequestExecutor<File, Strin | |||||
| /** | /** | ||||
| * jodd-http实现方式 | * jodd-http实现方式 | ||||
| * | |||||
| * @param provider | * @param provider | ||||
| * @param proxyInfo | * @param proxyInfo | ||||
| * @param uri | * @param uri | ||||
| @@ -147,7 +137,7 @@ public class MediaDownloadRequestExecutor implements RequestExecutor<File, Strin | |||||
| * @throws WxErrorException | * @throws WxErrorException | ||||
| * @throws IOException | * @throws IOException | ||||
| */ | */ | ||||
| private File executeJodd(HttpConnectionProvider provider, ProxyInfo proxyInfo, String uri, String queryParam) throws WxErrorException, IOException { | |||||
| public File executeJodd(HttpConnectionProvider provider, ProxyInfo proxyInfo, String uri, String queryParam) throws WxErrorException, IOException { | |||||
| if (queryParam != null) { | if (queryParam != null) { | ||||
| if (uri.indexOf('?') == -1) { | if (uri.indexOf('?') == -1) { | ||||
| uri += '?'; | uri += '?'; | ||||
| @@ -160,6 +150,7 @@ public class MediaDownloadRequestExecutor implements RequestExecutor<File, Strin | |||||
| provider.useProxy(proxyInfo); | provider.useProxy(proxyInfo); | ||||
| } | } | ||||
| request.withConnectionProvider(provider); | request.withConnectionProvider(provider); | ||||
| HttpResponse response = request.send(); | HttpResponse response = request.send(); | ||||
| String contentType = response.header("Content-Type"); | String contentType = response.header("Content-Type"); | ||||
| if (contentType != null && contentType.startsWith("application/json")) { | if (contentType != null && contentType.startsWith("application/json")) { | ||||
| @@ -167,7 +158,7 @@ public class MediaDownloadRequestExecutor implements RequestExecutor<File, Strin | |||||
| throw new WxErrorException(WxError.fromJson(response.bodyText())); | throw new WxErrorException(WxError.fromJson(response.bodyText())); | ||||
| } | } | ||||
| String fileName = getFileNameJodd(response); | |||||
| String fileName = getFileName(response); | |||||
| if (StringUtils.isBlank(fileName)) { | if (StringUtils.isBlank(fileName)) { | ||||
| return null; | return null; | ||||
| } | } | ||||
| @@ -178,4 +169,75 @@ public class MediaDownloadRequestExecutor implements RequestExecutor<File, Strin | |||||
| } | } | ||||
| /** | |||||
| * okhttp现实方式 | |||||
| * | |||||
| * @param pool | |||||
| * @param proxyInfo | |||||
| * @param uri | |||||
| * @param queryParam | |||||
| * @return | |||||
| * @throws WxErrorException | |||||
| * @throws IOException | |||||
| */ | |||||
| public File executeOkhttp(ConnectionPool pool, final OkhttpProxyInfo proxyInfo, String uri, String queryParam) throws WxErrorException, IOException { | |||||
| if (queryParam != null) { | |||||
| if (uri.indexOf('?') == -1) { | |||||
| uri += '?'; | |||||
| } | |||||
| uri += uri.endsWith("?") ? queryParam : '&' + queryParam; | |||||
| } | |||||
| OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder().connectionPool(pool); | |||||
| //设置代理 | |||||
| if (proxyInfo != null) { | |||||
| clientBuilder.proxy(proxyInfo.getProxy()); | |||||
| } | |||||
| //设置授权 | |||||
| clientBuilder.authenticator(new Authenticator() { | |||||
| @Override | |||||
| public Request authenticate(Route route, Response response) throws IOException { | |||||
| String credential = Credentials.basic(proxyInfo.getProxyUsername(), proxyInfo.getProxyPassword()); | |||||
| return response.request().newBuilder() | |||||
| .header("Authorization", credential) | |||||
| .build(); | |||||
| } | |||||
| }); | |||||
| //得到httpClient | |||||
| OkHttpClient client = clientBuilder.build(); | |||||
| Request request = new Request.Builder().url(uri).get().build(); | |||||
| Response response = client.newCall(request).execute(); | |||||
| String contentType = response.header("Content-Type"); | |||||
| if (contentType != null && contentType.startsWith("application/json")) { | |||||
| // application/json; encoding=utf-8 下载媒体文件出错 | |||||
| throw new WxErrorException(WxError.fromJson(response.body().toString())); | |||||
| } | |||||
| String fileName = getFileName(response); | |||||
| if (StringUtils.isBlank(fileName)) { | |||||
| return null; | |||||
| } | |||||
| InputStream inputStream = new ByteArrayInputStream(response.body().bytes()); | |||||
| String[] nameAndExt = fileName.split("\\."); | |||||
| return FileUtils.createTmpFile(inputStream, nameAndExt[0], nameAndExt[1], this.tmpDirFile); | |||||
| } | |||||
| private String getFileName(Response 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()); | |||||
| } | |||||
| } | } | ||||
| @@ -8,6 +8,9 @@ import me.chanjar.weixin.common.bean.result.WxError; | |||||
| import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; | ||||
| import me.chanjar.weixin.common.exception.WxErrorException; | import me.chanjar.weixin.common.exception.WxErrorException; | ||||
| import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; | import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; | ||||
| import me.chanjar.weixin.common.util.http.okhttp.OkhttpProxyInfo; | |||||
| import okhttp3.*; | |||||
| import org.apache.http.HttpEntity; | import org.apache.http.HttpEntity; | ||||
| import org.apache.http.HttpHost; | import org.apache.http.HttpHost; | ||||
| import org.apache.http.client.config.RequestConfig; | import org.apache.http.client.config.RequestConfig; | ||||
| @@ -20,35 +23,19 @@ import org.apache.http.impl.client.CloseableHttpClient; | |||||
| import java.io.File; | import java.io.File; | ||||
| import java.io.IOException; | import java.io.IOException; | ||||
| import java.net.InetSocketAddress; | |||||
| import java.net.Proxy; | |||||
| /** | /** | ||||
| * 上传媒体文件请求执行器,请求的参数是File, 返回的结果是String | * 上传媒体文件请求执行器,请求的参数是File, 返回的结果是String | ||||
| * | * | ||||
| * @author Daniel Qian | * @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.getRequestHttpClient() instanceof CloseableHttpClient) { | |||||
| CloseableHttpClient httpClient = (CloseableHttpClient) requestHttp.getRequestHttpClient(); | |||||
| HttpHost httpProxy = (HttpHost) requestHttp.getRequestHttpProxy(); | |||||
| return executeApache(httpClient, httpProxy, uri, file); | |||||
| } | |||||
| if (requestHttp.getRequestHttpClient() instanceof HttpConnectionProvider) { | |||||
| HttpConnectionProvider provider = (HttpConnectionProvider) requestHttp.getRequestHttpClient(); | |||||
| ProxyInfo proxyInfo = (ProxyInfo) requestHttp.getRequestHttpProxy(); | |||||
| return executeJodd(provider, proxyInfo, uri, file); | |||||
| } else { | |||||
| //这里需要抛出异常,需要优化 | |||||
| return null; | |||||
| } | |||||
| } | |||||
| public class MediaUploadRequestExecutor extends AbstractRequestExecutor<WxMediaUploadResult, File> { | |||||
| /** | /** | ||||
| * apache-http实现方式 | * apache-http实现方式 | ||||
| * | |||||
| * @param httpclient | * @param httpclient | ||||
| * @param httpProxy | * @param httpProxy | ||||
| * @param uri | * @param uri | ||||
| @@ -57,7 +44,7 @@ public class MediaUploadRequestExecutor implements RequestExecutor<WxMediaUpload | |||||
| * @throws WxErrorException | * @throws WxErrorException | ||||
| * @throws IOException | * @throws IOException | ||||
| */ | */ | ||||
| private WxMediaUploadResult executeApache(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, File file) throws WxErrorException, IOException { | |||||
| public WxMediaUploadResult executeApache(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, File file) throws WxErrorException, IOException { | |||||
| HttpPost httpPost = new HttpPost(uri); | HttpPost httpPost = new HttpPost(uri); | ||||
| if (httpProxy != null) { | if (httpProxy != null) { | ||||
| RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build(); | RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build(); | ||||
| @@ -87,6 +74,7 @@ public class MediaUploadRequestExecutor implements RequestExecutor<WxMediaUpload | |||||
| /** | /** | ||||
| * jodd-http实现方式 | * jodd-http实现方式 | ||||
| * | |||||
| * @param provider | * @param provider | ||||
| * @param proxyInfo | * @param proxyInfo | ||||
| * @param uri | * @param uri | ||||
| @@ -95,7 +83,7 @@ public class MediaUploadRequestExecutor implements RequestExecutor<WxMediaUpload | |||||
| * @throws WxErrorException | * @throws WxErrorException | ||||
| * @throws IOException | * @throws IOException | ||||
| */ | */ | ||||
| private WxMediaUploadResult executeJodd(HttpConnectionProvider provider, ProxyInfo proxyInfo, String uri, File file) throws WxErrorException, IOException { | |||||
| public WxMediaUploadResult executeJodd(HttpConnectionProvider provider, ProxyInfo proxyInfo, String uri, File file) throws WxErrorException, IOException { | |||||
| HttpRequest request = HttpRequest.post(uri); | HttpRequest request = HttpRequest.post(uri); | ||||
| if (proxyInfo != null) { | if (proxyInfo != null) { | ||||
| provider.useProxy(proxyInfo); | provider.useProxy(proxyInfo); | ||||
| @@ -112,4 +100,48 @@ public class MediaUploadRequestExecutor implements RequestExecutor<WxMediaUpload | |||||
| } | } | ||||
| /** | |||||
| * okhttp现实方式 | |||||
| * | |||||
| * @param pool | |||||
| * @param proxyInfo | |||||
| * @param uri | |||||
| * @param file | |||||
| * @return | |||||
| * @throws WxErrorException | |||||
| * @throws IOException | |||||
| */ | |||||
| public WxMediaUploadResult executeOkhttp(ConnectionPool pool, final OkhttpProxyInfo proxyInfo, String uri, File file) throws WxErrorException, IOException { | |||||
| OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder().connectionPool(pool); | |||||
| //设置代理 | |||||
| if (proxyInfo != null) { | |||||
| clientBuilder.proxy(proxyInfo.getProxy()); | |||||
| } | |||||
| //设置授权 | |||||
| clientBuilder.authenticator(new Authenticator() { | |||||
| @Override | |||||
| public Request authenticate(Route route, Response response) throws IOException { | |||||
| String credential = Credentials.basic(proxyInfo.getProxyUsername(), proxyInfo.getProxyPassword()); | |||||
| return response.request().newBuilder() | |||||
| .header("Authorization", credential) | |||||
| .build(); | |||||
| } | |||||
| }); | |||||
| //得到httpClient | |||||
| OkHttpClient client = clientBuilder.build(); | |||||
| RequestBody fileBody = RequestBody.create(MediaType.parse("multipart/form-data"), file); | |||||
| RequestBody body = new MultipartBody.Builder().addFormDataPart("media", null, fileBody).build(); | |||||
| Request request = new Request.Builder().url(uri).post(body).build(); | |||||
| Response response = client.newCall(request).execute(); | |||||
| String responseContent = response.body().toString(); | |||||
| WxError error = WxError.fromJson(responseContent); | |||||
| if (error.getErrorCode() != 0) { | |||||
| throw new WxErrorException(error); | |||||
| } | |||||
| return WxMediaUploadResult.fromJson(responseContent); | |||||
| } | |||||
| } | } | ||||
| @@ -1,9 +1,16 @@ | |||||
| package me.chanjar.weixin.common.util.http; | package me.chanjar.weixin.common.util.http; | ||||
| import jodd.http.HttpConnectionProvider; | |||||
| import jodd.http.ProxyInfo; | |||||
| import me.chanjar.weixin.common.exception.WxErrorException; | import me.chanjar.weixin.common.exception.WxErrorException; | ||||
| import me.chanjar.weixin.common.util.http.okhttp.OkhttpProxyInfo; | |||||
| import okhttp3.ConnectionPool; | |||||
| import java.io.IOException; | import java.io.IOException; | ||||
| import org.apache.http.HttpHost; | |||||
| import org.apache.http.impl.client.CloseableHttpClient; | |||||
| /** | /** | ||||
| * http请求执行器 | * http请求执行器 | ||||
| * | * | ||||
| @@ -20,4 +27,41 @@ public interface RequestExecutor<T, E> { | |||||
| */ | */ | ||||
| T execute(RequestHttp requestHttp, String uri, E data) throws WxErrorException, IOException; | T execute(RequestHttp requestHttp, String uri, E data) throws WxErrorException, IOException; | ||||
| /** | |||||
| * apache-http实现方式 | |||||
| * @param httpclient | |||||
| * @param httpProxy | |||||
| * @param uri | |||||
| * @param data | |||||
| * @return | |||||
| * @throws WxErrorException | |||||
| * @throws IOException | |||||
| */ | |||||
| T executeApache(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, E data) throws WxErrorException, IOException; | |||||
| /** | |||||
| * jodd-http实现方式 | |||||
| * @param provider | |||||
| * @param proxyInfo | |||||
| * @param uri | |||||
| * @param data | |||||
| * @return | |||||
| * @throws WxErrorException | |||||
| * @throws IOException | |||||
| */ | |||||
| T executeJodd(HttpConnectionProvider provider, ProxyInfo proxyInfo, String uri, E data) throws WxErrorException, IOException; | |||||
| /** okhttp实现方式 | |||||
| * @param pool | |||||
| * @param proxyInfo | |||||
| * @param uri | |||||
| * @param data | |||||
| * @return | |||||
| * @throws WxErrorException | |||||
| * @throws IOException | |||||
| */ | |||||
| T executeOkhttp(ConnectionPool pool, final OkhttpProxyInfo proxyInfo, String uri, E data) throws WxErrorException, IOException; | |||||
| } | } | ||||
| @@ -3,18 +3,18 @@ package me.chanjar.weixin.common.util.http; | |||||
| /** | /** | ||||
| * Created by ecoolper on 2017/4/22. | * Created by ecoolper on 2017/4/22. | ||||
| */ | */ | ||||
| public interface RequestHttp { | |||||
| public interface RequestHttp<H,P> { | |||||
| /** | /** | ||||
| * 返回httpClient | * 返回httpClient | ||||
| * @return | * @return | ||||
| */ | */ | ||||
| Object getRequestHttpClient(); | |||||
| H getRequestHttpClient(); | |||||
| /** | /** | ||||
| * 返回httpProxy | * 返回httpProxy | ||||
| * @return | * @return | ||||
| */ | */ | ||||
| Object getRequestHttpProxy(); | |||||
| P getRequestHttpProxy(); | |||||
| } | } | ||||
| @@ -7,6 +7,9 @@ import jodd.http.ProxyInfo; | |||||
| import me.chanjar.weixin.common.bean.result.WxError; | import me.chanjar.weixin.common.bean.result.WxError; | ||||
| import me.chanjar.weixin.common.exception.WxErrorException; | import me.chanjar.weixin.common.exception.WxErrorException; | ||||
| import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; | import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; | ||||
| import me.chanjar.weixin.common.util.http.okhttp.OkhttpProxyInfo; | |||||
| import okhttp3.*; | |||||
| import org.apache.http.HttpHost; | import org.apache.http.HttpHost; | ||||
| import org.apache.http.client.config.RequestConfig; | import org.apache.http.client.config.RequestConfig; | ||||
| import org.apache.http.client.methods.CloseableHttpResponse; | import org.apache.http.client.methods.CloseableHttpResponse; | ||||
| @@ -14,34 +17,20 @@ import org.apache.http.client.methods.HttpGet; | |||||
| import org.apache.http.impl.client.CloseableHttpClient; | import org.apache.http.impl.client.CloseableHttpClient; | ||||
| import java.io.IOException; | import java.io.IOException; | ||||
| import java.net.InetSocketAddress; | |||||
| import java.net.Proxy; | |||||
| import java.util.concurrent.TimeUnit; | |||||
| /** | /** | ||||
| * 简单的GET请求执行器,请求的参数是String, 返回的结果也是String | * 简单的GET请求执行器,请求的参数是String, 返回的结果也是String | ||||
| * | * | ||||
| * @author Daniel Qian | * @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.getRequestHttpClient() instanceof CloseableHttpClient) { | |||||
| CloseableHttpClient httpClient = (CloseableHttpClient) requestHttp.getRequestHttpClient(); | |||||
| HttpHost httpProxy = (HttpHost) requestHttp.getRequestHttpProxy(); | |||||
| return executeApache(httpClient, httpProxy, uri, queryParam); | |||||
| } | |||||
| if (requestHttp.getRequestHttpClient() instanceof HttpConnectionProvider) { | |||||
| HttpConnectionProvider provider = (HttpConnectionProvider) requestHttp.getRequestHttpClient(); | |||||
| ProxyInfo proxyInfo = (ProxyInfo) requestHttp.getRequestHttpProxy(); | |||||
| return executeJodd(provider, proxyInfo, uri, queryParam); | |||||
| } else { | |||||
| //这里需要抛出异常,需要优化 | |||||
| return null; | |||||
| } | |||||
| } | |||||
| public class SimpleGetRequestExecutor extends AbstractRequestExecutor<String, String> { | |||||
| /** | /** | ||||
| * apache-http实现方式 | * apache-http实现方式 | ||||
| * | |||||
| * @param httpclient | * @param httpclient | ||||
| * @param httpProxy | * @param httpProxy | ||||
| * @param uri | * @param uri | ||||
| @@ -50,7 +39,7 @@ public class SimpleGetRequestExecutor implements RequestExecutor<String, String> | |||||
| * @throws WxErrorException | * @throws WxErrorException | ||||
| * @throws IOException | * @throws IOException | ||||
| */ | */ | ||||
| private String executeApache(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, String queryParam) throws WxErrorException, IOException { | |||||
| public String executeApache(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, String queryParam) throws WxErrorException, IOException { | |||||
| if (queryParam != null) { | if (queryParam != null) { | ||||
| if (uri.indexOf('?') == -1) { | if (uri.indexOf('?') == -1) { | ||||
| uri += '?'; | uri += '?'; | ||||
| @@ -78,6 +67,7 @@ public class SimpleGetRequestExecutor implements RequestExecutor<String, String> | |||||
| /** | /** | ||||
| * jodd-http实现方式 | * jodd-http实现方式 | ||||
| * | |||||
| * @param provider | * @param provider | ||||
| * @param proxyInfo | * @param proxyInfo | ||||
| * @param uri | * @param uri | ||||
| @@ -86,7 +76,7 @@ public class SimpleGetRequestExecutor implements RequestExecutor<String, String> | |||||
| * @throws WxErrorException | * @throws WxErrorException | ||||
| * @throws IOException | * @throws IOException | ||||
| */ | */ | ||||
| private String executeJodd(HttpConnectionProvider provider, ProxyInfo proxyInfo, String uri, String queryParam) throws WxErrorException, IOException { | |||||
| public String executeJodd(HttpConnectionProvider provider, ProxyInfo proxyInfo, String uri, String queryParam) throws WxErrorException, IOException { | |||||
| if (queryParam != null) { | if (queryParam != null) { | ||||
| if (uri.indexOf('?') == -1) { | if (uri.indexOf('?') == -1) { | ||||
| uri += '?'; | uri += '?'; | ||||
| @@ -108,4 +98,53 @@ public class SimpleGetRequestExecutor implements RequestExecutor<String, String> | |||||
| return responseContent; | return responseContent; | ||||
| } | } | ||||
| /** | |||||
| * okHttp实现方式 | |||||
| * | |||||
| * @param pool | |||||
| * @param proxyInfo | |||||
| * @param uri | |||||
| * @param queryParam | |||||
| * @return | |||||
| * @throws WxErrorException | |||||
| * @throws IOException | |||||
| */ | |||||
| public String executeOkhttp(ConnectionPool pool, final OkhttpProxyInfo proxyInfo, String uri, String queryParam) throws WxErrorException, IOException { | |||||
| if (queryParam != null) { | |||||
| if (uri.indexOf('?') == -1) { | |||||
| uri += '?'; | |||||
| } | |||||
| uri += uri.endsWith("?") ? queryParam : '&' + queryParam; | |||||
| } | |||||
| OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder().connectionPool(pool); | |||||
| //设置代理 | |||||
| if (proxyInfo != null) { | |||||
| clientBuilder.proxy(proxyInfo.getProxy()); | |||||
| } | |||||
| //设置授权 | |||||
| clientBuilder.authenticator(new Authenticator() { | |||||
| @Override | |||||
| public Request authenticate(Route route, Response response) throws IOException { | |||||
| String credential = Credentials.basic(proxyInfo.getProxyUsername(), proxyInfo.getProxyPassword()); | |||||
| return response.request().newBuilder() | |||||
| .header("Authorization", credential) | |||||
| .build(); | |||||
| } | |||||
| }); | |||||
| //得到httpClient | |||||
| OkHttpClient client =clientBuilder.build(); | |||||
| Request request = new Request.Builder().url(uri).build(); | |||||
| Response response = client.newCall(request).execute(); | |||||
| String responseContent = response.body().toString(); | |||||
| WxError error = WxError.fromJson(responseContent); | |||||
| if (error.getErrorCode() != 0) { | |||||
| throw new WxErrorException(error); | |||||
| } | |||||
| return responseContent; | |||||
| } | |||||
| } | } | ||||
| @@ -7,6 +7,9 @@ import jodd.http.ProxyInfo; | |||||
| import me.chanjar.weixin.common.bean.result.WxError; | import me.chanjar.weixin.common.bean.result.WxError; | ||||
| import me.chanjar.weixin.common.exception.WxErrorException; | import me.chanjar.weixin.common.exception.WxErrorException; | ||||
| import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; | import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler; | ||||
| import me.chanjar.weixin.common.util.http.okhttp.OkhttpProxyInfo; | |||||
| import okhttp3.*; | |||||
| import org.apache.http.Consts; | import org.apache.http.Consts; | ||||
| import org.apache.http.HttpHost; | import org.apache.http.HttpHost; | ||||
| import org.apache.http.client.config.RequestConfig; | import org.apache.http.client.config.RequestConfig; | ||||
| @@ -23,27 +26,11 @@ import java.io.IOException; | |||||
| * | * | ||||
| * @author Daniel Qian | * @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.getRequestHttpClient() instanceof CloseableHttpClient) { | |||||
| CloseableHttpClient httpClient = (CloseableHttpClient) requestHttp.getRequestHttpClient(); | |||||
| HttpHost httpProxy = (HttpHost) requestHttp.getRequestHttpProxy(); | |||||
| return executeApache(httpClient, httpProxy, uri, postEntity); | |||||
| } | |||||
| if (requestHttp.getRequestHttpClient() instanceof HttpConnectionProvider) { | |||||
| HttpConnectionProvider provider = (HttpConnectionProvider) requestHttp.getRequestHttpClient(); | |||||
| ProxyInfo proxyInfo = (ProxyInfo) requestHttp.getRequestHttpProxy(); | |||||
| return executeJodd(provider, proxyInfo, uri, postEntity); | |||||
| } else { | |||||
| //这里需要抛出异常,需要优化 | |||||
| return null; | |||||
| } | |||||
| } | |||||
| public class SimplePostRequestExecutor extends AbstractRequestExecutor<String, String> { | |||||
| /** | /** | ||||
| * apache-http实现方式 | * apache-http实现方式 | ||||
| * | |||||
| * @param httpclient | * @param httpclient | ||||
| * @param httpProxy | * @param httpProxy | ||||
| * @param uri | * @param uri | ||||
| @@ -52,7 +39,7 @@ public class SimplePostRequestExecutor implements RequestExecutor<String, String | |||||
| * @throws WxErrorException | * @throws WxErrorException | ||||
| * @throws IOException | * @throws IOException | ||||
| */ | */ | ||||
| private String executeApache(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, String postEntity) throws WxErrorException, IOException { | |||||
| public String executeApache(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, String postEntity) throws WxErrorException, IOException { | |||||
| HttpPost httpPost = new HttpPost(uri); | HttpPost httpPost = new HttpPost(uri); | ||||
| if (httpProxy != null) { | if (httpProxy != null) { | ||||
| RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build(); | RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build(); | ||||
| @@ -90,6 +77,7 @@ public class SimplePostRequestExecutor implements RequestExecutor<String, String | |||||
| /** | /** | ||||
| * jodd-http实现方式 | * jodd-http实现方式 | ||||
| * | |||||
| * @param provider | * @param provider | ||||
| * @param proxyInfo | * @param proxyInfo | ||||
| * @param uri | * @param uri | ||||
| @@ -98,7 +86,7 @@ public class SimplePostRequestExecutor implements RequestExecutor<String, String | |||||
| * @throws WxErrorException | * @throws WxErrorException | ||||
| * @throws IOException | * @throws IOException | ||||
| */ | */ | ||||
| private String executeJodd(HttpConnectionProvider provider, ProxyInfo proxyInfo, String uri, String postEntity) throws WxErrorException, IOException { | |||||
| public String executeJodd(HttpConnectionProvider provider, ProxyInfo proxyInfo, String uri, String postEntity) throws WxErrorException, IOException { | |||||
| HttpRequest request = HttpRequest.post(uri); | HttpRequest request = HttpRequest.post(uri); | ||||
| if (proxyInfo != null) { | if (proxyInfo != null) { | ||||
| provider.useProxy(proxyInfo); | provider.useProxy(proxyInfo); | ||||
| @@ -129,4 +117,50 @@ public class SimplePostRequestExecutor implements RequestExecutor<String, String | |||||
| } | } | ||||
| /** | |||||
| * okHttp实现方式 | |||||
| * | |||||
| * @param pool | |||||
| * @param proxyInfo | |||||
| * @param uri | |||||
| * @param postEntity | |||||
| * @return | |||||
| * @throws WxErrorException | |||||
| * @throws IOException | |||||
| */ | |||||
| public String executeOkhttp(ConnectionPool pool, final OkhttpProxyInfo proxyInfo, String uri, String postEntity) throws WxErrorException, IOException { | |||||
| OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder().connectionPool(pool); | |||||
| //设置代理 | |||||
| if (proxyInfo != null) { | |||||
| clientBuilder.proxy(proxyInfo.getProxy()); | |||||
| } | |||||
| //设置授权 | |||||
| clientBuilder.authenticator(new Authenticator() { | |||||
| @Override | |||||
| public Request authenticate(Route route, Response response) throws IOException { | |||||
| String credential = Credentials.basic(proxyInfo.getProxyUsername(), proxyInfo.getProxyPassword()); | |||||
| return response.request().newBuilder() | |||||
| .header("Authorization", credential) | |||||
| .build(); | |||||
| } | |||||
| }); | |||||
| //得到httpClient | |||||
| OkHttpClient client = clientBuilder.build(); | |||||
| MediaType mediaType = MediaType.parse("text/plain; charset=utf-8"); | |||||
| RequestBody body = RequestBody.create(mediaType, postEntity); | |||||
| Request request = new Request.Builder().url(uri).post(body).build(); | |||||
| Response response = client.newCall(request).execute(); | |||||
| String responseContent = response.body().toString(); | |||||
| WxError error = WxError.fromJson(responseContent); | |||||
| if (error.getErrorCode() != 0) { | |||||
| throw new WxErrorException(error); | |||||
| } | |||||
| return responseContent; | |||||
| } | |||||
| } | } | ||||
| @@ -0,0 +1,117 @@ | |||||
| package me.chanjar.weixin.common.util.http.okhttp; | |||||
| import java.net.InetSocketAddress; | |||||
| import java.net.Proxy; | |||||
| /** | |||||
| * Created by ecoolper on 2017/4/26. | |||||
| * Proxy information. | |||||
| */ | |||||
| public class OkhttpProxyInfo { | |||||
| /** | |||||
| * Proxy types. | |||||
| */ | |||||
| public enum ProxyType { | |||||
| NONE, HTTP, SOCKS4, SOCKS5 | |||||
| } | |||||
| private final String proxyAddress; | |||||
| private final int proxyPort; | |||||
| private final String proxyUsername; | |||||
| private final String proxyPassword; | |||||
| private final ProxyType proxyType; | |||||
| public OkhttpProxyInfo(ProxyType proxyType, String proxyHost, int proxyPort, String proxyUser, String proxyPassword) { | |||||
| this.proxyType = proxyType; | |||||
| this.proxyAddress = proxyHost; | |||||
| this.proxyPort = proxyPort; | |||||
| this.proxyUsername = proxyUser; | |||||
| this.proxyPassword = proxyPassword; | |||||
| } | |||||
| // ---------------------------------------------------------------- factory | |||||
| /** | |||||
| * Creates directProxy. | |||||
| */ | |||||
| public static OkhttpProxyInfo directProxy() { | |||||
| return new OkhttpProxyInfo(ProxyType.NONE, null, 0, null, null); | |||||
| } | |||||
| /** | |||||
| * Creates SOCKS4 proxy. | |||||
| */ | |||||
| public static OkhttpProxyInfo socks4Proxy(String proxyAddress, int proxyPort, String proxyUser) { | |||||
| return new OkhttpProxyInfo(ProxyType.SOCKS4, proxyAddress, proxyPort, proxyUser, null); | |||||
| } | |||||
| /** | |||||
| * Creates SOCKS5 proxy. | |||||
| */ | |||||
| public static OkhttpProxyInfo socks5Proxy(String proxyAddress, int proxyPort, String proxyUser, String proxyPassword) { | |||||
| return new OkhttpProxyInfo(ProxyType.SOCKS5, proxyAddress, proxyPort, proxyUser, proxyPassword); | |||||
| } | |||||
| /** | |||||
| * Creates HTTP proxy. | |||||
| */ | |||||
| public static OkhttpProxyInfo httpProxy(String proxyAddress, int proxyPort, String proxyUser, String proxyPassword) { | |||||
| return new OkhttpProxyInfo(ProxyType.HTTP, proxyAddress, proxyPort, proxyUser, proxyPassword); | |||||
| } | |||||
| // ---------------------------------------------------------------- getter | |||||
| /** | |||||
| * Returns proxy type. | |||||
| */ | |||||
| public ProxyType getProxyType() { | |||||
| return proxyType; | |||||
| } | |||||
| /** | |||||
| * Returns proxy address. | |||||
| */ | |||||
| public String getProxyAddress() { | |||||
| return proxyAddress; | |||||
| } | |||||
| /** | |||||
| * Returns proxy port. | |||||
| */ | |||||
| public int getProxyPort() { | |||||
| return proxyPort; | |||||
| } | |||||
| /** | |||||
| * Returns proxy user name or <code>null</code> if | |||||
| * no authentication required. | |||||
| */ | |||||
| public String getProxyUsername() { | |||||
| return proxyUsername; | |||||
| } | |||||
| /** | |||||
| * Returns proxy password or <code>null</code>. | |||||
| */ | |||||
| public String getProxyPassword() { | |||||
| return proxyPassword; | |||||
| } | |||||
| /** | |||||
| * 返回 java.net.Proxy | |||||
| * @return | |||||
| */ | |||||
| public Proxy getProxy() { | |||||
| Proxy proxy = null; | |||||
| if (getProxyType().equals(ProxyType.SOCKS5)) { | |||||
| proxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(getProxyAddress(), getProxyPort())); | |||||
| } else if (getProxyType().equals(ProxyType.SOCKS4)) { | |||||
| proxy = new Proxy(Proxy.Type.SOCKS, new InetSocketAddress(getProxyAddress(), getProxyPort())); | |||||
| } else if (getProxyType().equals(ProxyType.HTTP)) { | |||||
| proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(getProxyAddress(), getProxyPort())); | |||||
| } else if (getProxyType().equals(ProxyType.NONE)) { | |||||
| proxy = new Proxy(Proxy.Type.DIRECT, new InetSocketAddress(getProxyAddress(), getProxyPort())); | |||||
| } | |||||
| return proxy; | |||||
| } | |||||
| } | |||||