| @@ -1,292 +0,0 @@ | |||
| package me.chanjar.weixin.common.util.http; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.apache.http.annotation.NotThreadSafe; | |||
| import org.apache.http.auth.AuthScope; | |||
| import org.apache.http.auth.UsernamePasswordCredentials; | |||
| import org.apache.http.client.CredentialsProvider; | |||
| import org.apache.http.client.HttpRequestRetryHandler; | |||
| import org.apache.http.client.config.RequestConfig; | |||
| import org.apache.http.config.Registry; | |||
| import org.apache.http.config.RegistryBuilder; | |||
| import org.apache.http.config.SocketConfig; | |||
| import org.apache.http.conn.HttpClientConnectionManager; | |||
| import org.apache.http.conn.socket.ConnectionSocketFactory; | |||
| import org.apache.http.conn.socket.PlainConnectionSocketFactory; | |||
| import org.apache.http.conn.ssl.SSLConnectionSocketFactory; | |||
| import org.apache.http.impl.client.BasicCredentialsProvider; | |||
| import org.apache.http.impl.client.CloseableHttpClient; | |||
| import org.apache.http.impl.client.HttpClientBuilder; | |||
| import org.apache.http.impl.client.HttpClients; | |||
| import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; | |||
| import org.apache.http.protocol.HttpContext; | |||
| import org.slf4j.Logger; | |||
| import org.slf4j.LoggerFactory; | |||
| import java.io.IOException; | |||
| import java.util.concurrent.TimeUnit; | |||
| import java.util.concurrent.atomic.AtomicBoolean; | |||
| /** | |||
| * httpclient 连接管理器 | |||
| * | |||
| * @author kakotor | |||
| */ | |||
| @NotThreadSafe | |||
| public class DefaultApacheHttpClientBuilder implements ApacheHttpClientBuilder { | |||
| protected final Logger log = LoggerFactory.getLogger(DefaultApacheHttpClientBuilder.class); | |||
| private final AtomicBoolean prepared = new AtomicBoolean(false); | |||
| private int connectionRequestTimeout = 3000; | |||
| private int connectionTimeout = 5000; | |||
| private int soTimeout = 5000; | |||
| private int idleConnTimeout = 60000; | |||
| private int checkWaitTime = 60000; | |||
| private int maxConnPerHost = 10; | |||
| private int maxTotalConn = 50; | |||
| private String userAgent; | |||
| private HttpRequestRetryHandler httpRequestRetryHandler = new HttpRequestRetryHandler() { | |||
| @Override | |||
| public boolean retryRequest(IOException exception, int executionCount, HttpContext context) { | |||
| return false; | |||
| } | |||
| }; | |||
| private SSLConnectionSocketFactory sslConnectionSocketFactory = SSLConnectionSocketFactory.getSocketFactory(); | |||
| private PlainConnectionSocketFactory plainConnectionSocketFactory = PlainConnectionSocketFactory.getSocketFactory(); | |||
| private String httpProxyHost; | |||
| private int httpProxyPort; | |||
| private String httpProxyUsername; | |||
| private String httpProxyPassword; | |||
| /** | |||
| * 闲置连接监控线程 | |||
| */ | |||
| private IdleConnectionMonitorThread idleConnectionMonitorThread; | |||
| private HttpClientBuilder httpClientBuilder; | |||
| private DefaultApacheHttpClientBuilder() { | |||
| } | |||
| public static DefaultApacheHttpClientBuilder get() { | |||
| return new DefaultApacheHttpClientBuilder(); | |||
| } | |||
| @Override | |||
| public ApacheHttpClientBuilder httpProxyHost(String httpProxyHost) { | |||
| this.httpProxyHost = httpProxyHost; | |||
| return this; | |||
| } | |||
| @Override | |||
| public ApacheHttpClientBuilder httpProxyPort(int httpProxyPort) { | |||
| this.httpProxyPort = httpProxyPort; | |||
| return this; | |||
| } | |||
| @Override | |||
| public ApacheHttpClientBuilder httpProxyUsername(String httpProxyUsername) { | |||
| this.httpProxyUsername = httpProxyUsername; | |||
| return this; | |||
| } | |||
| @Override | |||
| public ApacheHttpClientBuilder httpProxyPassword(String httpProxyPassword) { | |||
| this.httpProxyPassword = httpProxyPassword; | |||
| return this; | |||
| } | |||
| @Override | |||
| public ApacheHttpClientBuilder sslConnectionSocketFactory(SSLConnectionSocketFactory sslConnectionSocketFactory) { | |||
| this.sslConnectionSocketFactory = sslConnectionSocketFactory; | |||
| return this; | |||
| } | |||
| /** | |||
| * 获取链接的超时时间设置,默认3000ms | |||
| * <p> | |||
| * 设置为零时不超时,一直等待. | |||
| * 设置为负数是使用系统默认设置(非上述的3000ms的默认值,而是httpclient的默认设置). | |||
| * </p> | |||
| * | |||
| * @param connectionRequestTimeout 获取链接的超时时间设置(单位毫秒),默认3000ms | |||
| */ | |||
| public void setConnectionRequestTimeout(int connectionRequestTimeout) { | |||
| this.connectionRequestTimeout = connectionRequestTimeout; | |||
| } | |||
| /** | |||
| * 建立链接的超时时间,默认为5000ms.由于是在链接池获取链接,此设置应该并不起什么作用 | |||
| * <p> | |||
| * 设置为零时不超时,一直等待. | |||
| * 设置为负数是使用系统默认设置(非上述的5000ms的默认值,而是httpclient的默认设置). | |||
| * </p> | |||
| * | |||
| * @param connectionTimeout 建立链接的超时时间设置(单位毫秒),默认5000ms | |||
| */ | |||
| public void setConnectionTimeout(int connectionTimeout) { | |||
| this.connectionTimeout = connectionTimeout; | |||
| } | |||
| /** | |||
| * 默认NIO的socket超时设置,默认5000ms. | |||
| * | |||
| * @param soTimeout 默认NIO的socket超时设置,默认5000ms. | |||
| * @see java.net.SocketOptions#SO_TIMEOUT | |||
| */ | |||
| public void setSoTimeout(int soTimeout) { | |||
| this.soTimeout = soTimeout; | |||
| } | |||
| /** | |||
| * 空闲链接的超时时间,默认60000ms. | |||
| * <p> | |||
| * 超时的链接将在下一次空闲链接检查是被销毁 | |||
| * </p> | |||
| * | |||
| * @param idleConnTimeout 空闲链接的超时时间,默认60000ms. | |||
| */ | |||
| public void setIdleConnTimeout(int idleConnTimeout) { | |||
| this.idleConnTimeout = idleConnTimeout; | |||
| } | |||
| /** | |||
| * 检查空间链接的间隔周期,默认60000ms. | |||
| * | |||
| * @param checkWaitTime 检查空间链接的间隔周期,默认60000ms. | |||
| */ | |||
| public void setCheckWaitTime(int checkWaitTime) { | |||
| this.checkWaitTime = checkWaitTime; | |||
| } | |||
| /** | |||
| * 每路的最大链接数,默认10 | |||
| * | |||
| * @param maxConnPerHost 每路的最大链接数,默认10 | |||
| */ | |||
| public void setMaxConnPerHost(int maxConnPerHost) { | |||
| this.maxConnPerHost = maxConnPerHost; | |||
| } | |||
| /** | |||
| * 最大总连接数,默认50 | |||
| * | |||
| * @param maxTotalConn 最大总连接数,默认50 | |||
| */ | |||
| public void setMaxTotalConn(int maxTotalConn) { | |||
| this.maxTotalConn = maxTotalConn; | |||
| } | |||
| /** | |||
| * 自定义httpclient的User Agent | |||
| * | |||
| * @param userAgent User Agent | |||
| */ | |||
| public void setUserAgent(String userAgent) { | |||
| this.userAgent = userAgent; | |||
| } | |||
| public IdleConnectionMonitorThread getIdleConnectionMonitorThread() { | |||
| return this.idleConnectionMonitorThread; | |||
| } | |||
| private synchronized void prepare() { | |||
| if(prepared.get()){ | |||
| return; | |||
| } | |||
| Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create() | |||
| .register("http", this.plainConnectionSocketFactory) | |||
| .register("https", this.sslConnectionSocketFactory) | |||
| .build(); | |||
| @SuppressWarnings("resource") | |||
| PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry); | |||
| connectionManager.setMaxTotal(this.maxTotalConn); | |||
| connectionManager.setDefaultMaxPerRoute(this.maxConnPerHost); | |||
| connectionManager.setDefaultSocketConfig( | |||
| SocketConfig.copy(SocketConfig.DEFAULT) | |||
| .setSoTimeout(this.soTimeout) | |||
| .build() | |||
| ); | |||
| this.idleConnectionMonitorThread = new IdleConnectionMonitorThread( | |||
| connectionManager, this.idleConnTimeout, this.checkWaitTime); | |||
| this.idleConnectionMonitorThread.setDaemon(true); | |||
| this.idleConnectionMonitorThread.start(); | |||
| this.httpClientBuilder = HttpClients.custom() | |||
| .setConnectionManager(connectionManager) | |||
| .setConnectionManagerShared(true) | |||
| .setDefaultRequestConfig( | |||
| RequestConfig.custom() | |||
| .setSocketTimeout(this.soTimeout) | |||
| .setConnectTimeout(this.connectionTimeout) | |||
| .setConnectionRequestTimeout(this.connectionRequestTimeout) | |||
| .build() | |||
| ) | |||
| .setRetryHandler(this.httpRequestRetryHandler); | |||
| if (StringUtils.isNotBlank(this.httpProxyHost) | |||
| && StringUtils.isNotBlank(this.httpProxyUsername)) { | |||
| // 使用代理服务器 需要用户认证的代理服务器 | |||
| CredentialsProvider provider = new BasicCredentialsProvider(); | |||
| provider.setCredentials( | |||
| new AuthScope(this.httpProxyHost, this.httpProxyPort), | |||
| new UsernamePasswordCredentials(this.httpProxyUsername, | |||
| this.httpProxyPassword)); | |||
| this.httpClientBuilder.setDefaultCredentialsProvider(provider); | |||
| } | |||
| if (StringUtils.isNotBlank(this.userAgent)) { | |||
| this.httpClientBuilder.setUserAgent(this.userAgent); | |||
| } | |||
| prepared.set(true); | |||
| } | |||
| @Override | |||
| public CloseableHttpClient build() { | |||
| if(!prepared.get()){ | |||
| prepare(); | |||
| } | |||
| return this.httpClientBuilder.build(); | |||
| } | |||
| public static class IdleConnectionMonitorThread extends Thread { | |||
| private final HttpClientConnectionManager connMgr; | |||
| private final int idleConnTimeout; | |||
| private final int checkWaitTime; | |||
| private volatile boolean shutdown; | |||
| public IdleConnectionMonitorThread(HttpClientConnectionManager connMgr, int idleConnTimeout, int checkWaitTime) { | |||
| super("IdleConnectionMonitorThread"); | |||
| this.connMgr = connMgr; | |||
| this.idleConnTimeout = idleConnTimeout; | |||
| this.checkWaitTime = checkWaitTime; | |||
| } | |||
| @Override | |||
| public void run() { | |||
| try { | |||
| while (!this.shutdown) { | |||
| synchronized (this) { | |||
| wait(this.checkWaitTime); | |||
| this.connMgr.closeExpiredConnections(); | |||
| this.connMgr.closeIdleConnections(this.idleConnTimeout, | |||
| TimeUnit.MILLISECONDS); | |||
| } | |||
| } | |||
| } catch (InterruptedException ignore) { | |||
| } | |||
| } | |||
| public void trigger() { | |||
| synchronized (this) { | |||
| notifyAll(); | |||
| } | |||
| } | |||
| public void shutdown() { | |||
| this.shutdown = true; | |||
| synchronized (this) { | |||
| notifyAll(); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -1,8 +1,6 @@ | |||
| package me.chanjar.weixin.common.util.http; | |||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||
| import org.apache.http.HttpHost; | |||
| import org.apache.http.impl.client.CloseableHttpClient; | |||
| import java.io.IOException; | |||
| @@ -12,16 +10,16 @@ import java.io.IOException; | |||
| * @param <T> 返回值类型 | |||
| * @param <E> 请求参数类型 | |||
| */ | |||
| public interface RequestExecutor<T, E> { | |||
| public interface RequestExecutor<T, H, P, E> { | |||
| /** | |||
| * @param httpclient 传入的httpClient | |||
| * @param httpClient | |||
| * @param httpProxy http代理对象,如果没有配置代理则为空 | |||
| * @param uri uri | |||
| * @param data 数据 | |||
| * @throws WxErrorException | |||
| * @throws IOException | |||
| */ | |||
| T execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, E data) throws WxErrorException, IOException; | |||
| T execute(H httpClient, P httpProxy, String uri, E data) throws WxErrorException, IOException; | |||
| } | |||
| @@ -1,33 +0,0 @@ | |||
| package me.chanjar.weixin.common.util.http; | |||
| import org.apache.http.Consts; | |||
| import org.apache.http.HttpEntity; | |||
| import org.apache.http.HttpResponse; | |||
| import org.apache.http.StatusLine; | |||
| import org.apache.http.client.HttpResponseException; | |||
| import org.apache.http.client.ResponseHandler; | |||
| import org.apache.http.util.EntityUtils; | |||
| import java.io.IOException; | |||
| /** | |||
| * copy from {@link org.apache.http.impl.client.BasicResponseHandler} | |||
| * | |||
| * @author Daniel Qian | |||
| */ | |||
| public class Utf8ResponseHandler implements ResponseHandler<String> { | |||
| public static final ResponseHandler<String> INSTANCE = new Utf8ResponseHandler(); | |||
| @Override | |||
| public String handleResponse(final HttpResponse response) throws IOException { | |||
| final StatusLine statusLine = response.getStatusLine(); | |||
| final HttpEntity entity = response.getEntity(); | |||
| if (statusLine.getStatusCode() >= 300) { | |||
| EntityUtils.consume(entity); | |||
| throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase()); | |||
| } | |||
| return entity == null ? null : EntityUtils.toString(entity, Consts.UTF_8); | |||
| } | |||
| } | |||
| @@ -1,4 +1,4 @@ | |||
| package me.chanjar.weixin.common.util.http; | |||
| package me.chanjar.weixin.common.util.http.apache; | |||
| import org.apache.http.conn.ssl.SSLConnectionSocketFactory; | |||
| import org.apache.http.impl.client.CloseableHttpClient; | |||
| @@ -1,4 +1,4 @@ | |||
| package me.chanjar.weixin.common.util.http.jodd; | |||
| package me.chanjar.weixin.common.util.http.apache; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import org.apache.http.annotation.NotThreadSafe; | |||
| @@ -1,4 +1,4 @@ | |||
| package me.chanjar.weixin.common.util.http; | |||
| package me.chanjar.weixin.common.util.http.apache; | |||
| import org.apache.http.HttpEntity; | |||
| import org.apache.http.HttpResponse; | |||
| @@ -1,8 +1,9 @@ | |||
| package me.chanjar.weixin.common.util.http; | |||
| 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; | |||
| @@ -23,7 +24,7 @@ import java.util.regex.Pattern; | |||
| * 视频文件不支持下载 | |||
| * @author Daniel Qian | |||
| */ | |||
| public class MediaDownloadRequestExecutor implements RequestExecutor<File, String> { | |||
| public class MediaDownloadRequestExecutor implements RequestExecutor<File, CloseableHttpClient, HttpHost,String> { | |||
| private File tmpDirFile; | |||
| @@ -1,8 +1,9 @@ | |||
| package me.chanjar.weixin.common.util.http; | |||
| 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; | |||
| @@ -21,7 +22,7 @@ import java.io.IOException; | |||
| * | |||
| * @author Daniel Qian | |||
| */ | |||
| public class MediaUploadRequestExecutor implements RequestExecutor<WxMediaUploadResult, File> { | |||
| public class MediaUploadRequestExecutor implements RequestExecutor<WxMediaUploadResult, CloseableHttpClient, HttpHost,File> { | |||
| @Override | |||
| public WxMediaUploadResult execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, File file) throws WxErrorException, IOException { | |||
| @@ -1,7 +1,8 @@ | |||
| package me.chanjar.weixin.common.util.http; | |||
| 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; | |||
| @@ -15,7 +16,7 @@ import java.io.IOException; | |||
| * | |||
| * @author Daniel Qian | |||
| */ | |||
| public class SimpleGetRequestExecutor implements RequestExecutor<String, String> { | |||
| public class SimpleGetRequestExecutor implements RequestExecutor<String, CloseableHttpClient, HttpHost, String> { | |||
| @Override | |||
| public String execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, String queryParam) throws WxErrorException, IOException { | |||
| @@ -1,7 +1,8 @@ | |||
| package me.chanjar.weixin.common.util.http; | |||
| import java.io.IOException; | |||
| 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; | |||
| @@ -10,15 +11,14 @@ import org.apache.http.client.methods.HttpPost; | |||
| import org.apache.http.entity.StringEntity; | |||
| import org.apache.http.impl.client.CloseableHttpClient; | |||
| import me.chanjar.weixin.common.bean.result.WxError; | |||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||
| import java.io.IOException; | |||
| /** | |||
| * 简单的POST请求执行器,请求的参数是String, 返回的结果也是String | |||
| * | |||
| * @author Daniel Qian | |||
| */ | |||
| public class SimplePostRequestExecutor implements RequestExecutor<String, String> { | |||
| public class SimplePostRequestExecutor implements RequestExecutor<String, CloseableHttpClient, HttpHost, String> { | |||
| @Override | |||
| public String execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, String postEntity) throws WxErrorException, IOException { | |||
| @@ -1,4 +1,4 @@ | |||
| package me.chanjar.weixin.common.util.http.jodd; | |||
| package me.chanjar.weixin.common.util.http.apache; | |||
| import org.apache.http.Consts; | |||
| import org.apache.http.HttpEntity; | |||
| @@ -1,53 +0,0 @@ | |||
| package me.chanjar.weixin.common.util.http.jodd; | |||
| import org.apache.http.conn.ssl.SSLConnectionSocketFactory; | |||
| import org.apache.http.impl.client.CloseableHttpClient; | |||
| /** | |||
| * httpclient build interface | |||
| * @author kakotor | |||
| */ | |||
| public interface ApacheHttpClientBuilder { | |||
| /** | |||
| * 构建httpclient实例 | |||
| * | |||
| * @return new instance of CloseableHttpClient | |||
| */ | |||
| CloseableHttpClient build(); | |||
| /** | |||
| * 代理服务器地址 | |||
| * | |||
| * @param httpProxyHost | |||
| */ | |||
| ApacheHttpClientBuilder httpProxyHost(String httpProxyHost); | |||
| /** | |||
| * 代理服务器端口 | |||
| * | |||
| * @param httpProxyPort | |||
| */ | |||
| ApacheHttpClientBuilder httpProxyPort(int httpProxyPort); | |||
| /** | |||
| * 代理服务器用户名 | |||
| * | |||
| * @param httpProxyUsername | |||
| */ | |||
| ApacheHttpClientBuilder httpProxyUsername(String httpProxyUsername); | |||
| /** | |||
| * 代理服务器密码 | |||
| * | |||
| * @param httpProxyPassword | |||
| */ | |||
| ApacheHttpClientBuilder httpProxyPassword(String httpProxyPassword); | |||
| /** | |||
| * ssl连接socket工厂 | |||
| * | |||
| * @param sslConnectionSocketFactory | |||
| */ | |||
| ApacheHttpClientBuilder sslConnectionSocketFactory(SSLConnectionSocketFactory sslConnectionSocketFactory); | |||
| } | |||
| @@ -1,28 +0,0 @@ | |||
| package me.chanjar.weixin.common.util.http.jodd; | |||
| import org.apache.http.HttpEntity; | |||
| import org.apache.http.HttpResponse; | |||
| import org.apache.http.StatusLine; | |||
| import org.apache.http.client.HttpResponseException; | |||
| import org.apache.http.client.ResponseHandler; | |||
| import org.apache.http.util.EntityUtils; | |||
| import java.io.IOException; | |||
| import java.io.InputStream; | |||
| public class InputStreamResponseHandler implements ResponseHandler<InputStream> { | |||
| public static final ResponseHandler<InputStream> INSTANCE = new InputStreamResponseHandler(); | |||
| @Override | |||
| public InputStream handleResponse(final HttpResponse response) throws IOException { | |||
| final StatusLine statusLine = response.getStatusLine(); | |||
| final HttpEntity entity = response.getEntity(); | |||
| if (statusLine.getStatusCode() >= 300) { | |||
| EntityUtils.consume(entity); | |||
| throw new HttpResponseException(statusLine.getStatusCode(), statusLine.getReasonPhrase()); | |||
| } | |||
| return entity == null ? null : entity.getContent(); | |||
| } | |||
| } | |||
| @@ -1,11 +1,13 @@ | |||
| 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; | |||
| @@ -21,7 +23,7 @@ import java.util.regex.Pattern; | |||
| * | |||
| * @author Daniel Qian | |||
| */ | |||
| public class MediaDownloadRequestExecutor implements RequestExecutor<File, String> { | |||
| public class MediaDownloadRequestExecutor implements RequestExecutor<File, HttpConnectionProvider, ProxyInfo, String> { | |||
| private File tmpDirFile; | |||
| @@ -33,7 +35,7 @@ public class MediaDownloadRequestExecutor implements RequestExecutor<File, Strin | |||
| } | |||
| @Override | |||
| public File execute(ProxyInfo httpProxy, String uri, String queryParam) throws WxErrorException, IOException { | |||
| public File execute(HttpConnectionProvider provider, ProxyInfo httpProxy, String uri, String queryParam) throws WxErrorException, IOException { | |||
| if (queryParam != null) { | |||
| if (uri.indexOf('?') == -1) { | |||
| uri += '?'; | |||
| @@ -41,8 +43,12 @@ public class MediaDownloadRequestExecutor implements RequestExecutor<File, Strin | |||
| uri += uri.endsWith("?") ? queryParam : '&' + queryParam; | |||
| } | |||
| HttpRequest httpRequest = HttpRequest.post(uri); | |||
| HttpResponse response = httpRequest.send(); | |||
| 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 下载媒体文件出错 | |||
| @@ -1,12 +1,13 @@ | |||
| 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.net.SocketHttpConnectionProvider; | |||
| 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; | |||
| @@ -16,16 +17,15 @@ import java.io.IOException; | |||
| * | |||
| * @author Daniel Qian | |||
| */ | |||
| public class MediaUploadRequestExecutor implements RequestExecutor<WxMediaUploadResult, File> { | |||
| public class MediaUploadRequestExecutor implements RequestExecutor<WxMediaUploadResult, HttpConnectionProvider, ProxyInfo, File> { | |||
| @Override | |||
| public WxMediaUploadResult execute(ProxyInfo httpProxy, String uri, File file) throws WxErrorException, IOException { | |||
| public WxMediaUploadResult execute(HttpConnectionProvider provider, ProxyInfo httpProxy, String uri, File file) throws WxErrorException, IOException { | |||
| HttpRequest request = HttpRequest.post(uri); | |||
| if (httpProxy != null) { | |||
| SocketHttpConnectionProvider provider = new SocketHttpConnectionProvider(); | |||
| provider.useProxy(httpProxy); | |||
| request.withConnectionProvider(provider); | |||
| } | |||
| request.withConnectionProvider(provider); | |||
| request.form("media", file); | |||
| HttpResponse response = request.send(); | |||
| String responseContent =response.bodyText(); | |||
| @@ -1,25 +0,0 @@ | |||
| package me.chanjar.weixin.common.util.http.jodd; | |||
| import jodd.http.ProxyInfo; | |||
| import me.chanjar.weixin.common.exception.WxErrorException; | |||
| import java.io.IOException; | |||
| /** | |||
| * http请求执行器 | |||
| * | |||
| * @param <T> 返回值类型 | |||
| * @param <E> 请求参数类型 | |||
| */ | |||
| public interface RequestExecutor<T, E> { | |||
| /** | |||
| * @param httpProxy http代理对象,如果没有配置代理则为空 | |||
| * @param uri uri | |||
| * @param data 数据 | |||
| * @throws WxErrorException | |||
| * @throws IOException | |||
| */ | |||
| T execute(ProxyInfo httpProxy, String uri, E data) throws WxErrorException, IOException; | |||
| } | |||
| @@ -1,11 +1,12 @@ | |||
| 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.net.SocketHttpConnectionProvider; | |||
| 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; | |||
| @@ -14,10 +15,10 @@ import java.io.IOException; | |||
| * | |||
| * @author Daniel Qian | |||
| */ | |||
| public class SimpleGetRequestExecutor implements RequestExecutor<String, String> { | |||
| public class SimpleGetRequestExecutor implements RequestExecutor<String, HttpConnectionProvider, ProxyInfo, String> { | |||
| @Override | |||
| public String execute(ProxyInfo httpProxy, String uri, String queryParam) throws WxErrorException, IOException { | |||
| public String execute(HttpConnectionProvider provider, ProxyInfo httpProxy, String uri, String queryParam) throws WxErrorException, IOException { | |||
| if (queryParam != null) { | |||
| if (uri.indexOf('?') == -1) { | |||
| uri += '?'; | |||
| @@ -27,10 +28,9 @@ public class SimpleGetRequestExecutor implements RequestExecutor<String, String> | |||
| HttpRequest request = HttpRequest.get(uri); | |||
| if (httpProxy != null) { | |||
| SocketHttpConnectionProvider provider = new SocketHttpConnectionProvider(); | |||
| provider.useProxy(httpProxy); | |||
| request.withConnectionProvider(provider); | |||
| } | |||
| request.withConnectionProvider(provider); | |||
| HttpResponse response = request.send(); | |||
| String responseContent = response.bodyText(); | |||
| WxError error = WxError.fromJson(responseContent); | |||
| @@ -1,11 +1,12 @@ | |||
| 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.net.SocketHttpConnectionProvider; | |||
| 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; | |||
| @@ -14,16 +15,15 @@ import java.io.IOException; | |||
| * | |||
| * @author Daniel Qian | |||
| */ | |||
| public class SimplePostRequestExecutor implements RequestExecutor<String, String> { | |||
| public class SimplePostRequestExecutor implements RequestExecutor<String, HttpConnectionProvider, ProxyInfo, String> { | |||
| @Override | |||
| public String execute(ProxyInfo httpProxy, String uri, String postEntity) throws WxErrorException, IOException { | |||
| public String execute(HttpConnectionProvider provider, ProxyInfo httpProxy, String uri, String postEntity) throws WxErrorException, IOException { | |||
| HttpRequest request = HttpRequest.post(uri); | |||
| if (httpProxy != null) { | |||
| SocketHttpConnectionProvider provider = new SocketHttpConnectionProvider(); | |||
| provider.useProxy(httpProxy); | |||
| request.withConnectionProvider(provider); | |||
| } | |||
| request.withConnectionProvider(provider); | |||
| if (postEntity != null) { | |||
| request.bodyText(postEntity); | |||
| } | |||
| @@ -1,48 +0,0 @@ | |||
| package me.chanjar.weixin.common.util.http.jodd; | |||
| import org.apache.commons.lang3.StringUtils; | |||
| import java.io.UnsupportedEncodingException; | |||
| public class URIUtil { | |||
| private static final String ALLOWED_CHARS = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_.!~*'()"; | |||
| public static String encodeURIComponent(String input) { | |||
| if (StringUtils.isEmpty(input)) { | |||
| return input; | |||
| } | |||
| int l = input.length(); | |||
| StringBuilder o = new StringBuilder(l * 3); | |||
| try { | |||
| for (int i = 0; i < l; i++) { | |||
| String e = input.substring(i, i + 1); | |||
| if (ALLOWED_CHARS.indexOf(e) == -1) { | |||
| byte[] b = e.getBytes("utf-8"); | |||
| o.append(getHex(b)); | |||
| continue; | |||
| } | |||
| o.append(e); | |||
| } | |||
| return o.toString(); | |||
| } catch (UnsupportedEncodingException e) { | |||
| e.printStackTrace(); | |||
| } | |||
| return input; | |||
| } | |||
| private static String getHex(byte buf[]) { | |||
| StringBuilder o = new StringBuilder(buf.length * 3); | |||
| for (int i = 0; i < buf.length; i++) { | |||
| int n = buf[i] & 0xff; | |||
| o.append("%"); | |||
| if (n < 0x10) { | |||
| o.append("0"); | |||
| } | |||
| o.append(Long.toString(n, 16).toUpperCase()); | |||
| } | |||
| return o.toString(); | |||
| } | |||
| } | |||