重新整理HttpClinet & 新增OkHttp实现

This commit is contained in:
jinyu 2016-07-30 14:56:27 +08:00
parent e9cd349c8c
commit 5ea7fee142
62 changed files with 1913 additions and 844 deletions

View File

@ -149,4 +149,10 @@
* 2016-05-12 * 2016-05-12
+ 添加MemcacheTokenStorager支持 + 添加MemcacheTokenStorager支持
* 2016-07-30
+ 重新整理HttpClinet
+ 新增OkHttp实现

View File

@ -39,6 +39,18 @@
<version>4.0.30.Final</version> <version>4.0.30.Final</version>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.4.1</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.squareup.okhttp</groupId>
<artifactId>okhttp</artifactId>
<version>2.7.5</version>
<optional>true</optional>
</dependency>
<dependency> <dependency>
<groupId>redis.clients</groupId> <groupId>redis.clients</groupId>
<artifactId>jedis</artifactId> <artifactId>jedis</artifactId>

View File

@ -25,12 +25,12 @@ public abstract class BaseApi {
protected final WeixinRequestExecutor weixinExecutor; protected final WeixinRequestExecutor weixinExecutor;
protected abstract ResourceBundle weixinBundle();
public BaseApi() { public BaseApi() {
this.weixinExecutor = new WeixinRequestExecutor(); this.weixinExecutor = new WeixinRequestExecutor();
} }
protected abstract ResourceBundle weixinBundle();
protected String getRequestUri(String key) { protected String getRequestUri(String key) {
String url = weixinBundle().getString(key); String url = weixinBundle().getString(key);
Pattern p = Pattern.compile("(\\{[^\\}]*\\})"); Pattern p = Pattern.compile("(\\{[^\\}]*\\})");

View File

@ -7,7 +7,6 @@ import java.util.ResourceBundle;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.weixin.WeixinRequestExecutor; import com.foxinmy.weixin4j.http.weixin.WeixinRequestExecutor;
import com.foxinmy.weixin4j.http.weixin.WeixinSSLRequestExecutor;
import com.foxinmy.weixin4j.model.WeixinPayAccount; import com.foxinmy.weixin4j.model.WeixinPayAccount;
import com.foxinmy.weixin4j.payment.mch.MerchantResult; import com.foxinmy.weixin4j.payment.mch.MerchantResult;
import com.foxinmy.weixin4j.sign.WeixinPaymentSignature; import com.foxinmy.weixin4j.sign.WeixinPaymentSignature;
@ -58,8 +57,8 @@ public class MchApi extends BaseApi {
*/ */
protected WeixinRequestExecutor createSSLRequestExecutor( protected WeixinRequestExecutor createSSLRequestExecutor(
InputStream certificate) throws WeixinException { InputStream certificate) throws WeixinException {
return new WeixinSSLRequestExecutor(weixinAccount.getCertificateKey(), return weixinExecutor.createSSLRequestExecutor(
certificate); weixinAccount.getCertificateKey(), certificate);
} }
/** /**

View File

@ -12,7 +12,7 @@ import java.io.InputStream;
* @see * @see
*/ */
public abstract class AbstractHttpResponse implements HttpResponse { public abstract class AbstractHttpResponse implements HttpResponse {
protected final static String KEEP_ALIVE = "keep-alive";
private final byte[] content; private final byte[] content;
public AbstractHttpResponse(byte[] content) { public AbstractHttpResponse(byte[] content) {

View File

@ -24,12 +24,14 @@ public final class ContentType implements Serializable {
private final Charset charset; private final Charset charset;
private static final Charset DEFAULT_CHARSET = Consts.UTF_8; private static final Charset DEFAULT_CHARSET = Consts.UTF_8;
public static final ContentType APPLICATION_JSON;
public static final ContentType APPLICATION_FORM_URLENCODED; public static final ContentType APPLICATION_FORM_URLENCODED;
public static final ContentType MULTIPART_FORM_DATA; public static final ContentType MULTIPART_FORM_DATA;
public static final ContentType DEFAULT_BINARY; public static final ContentType DEFAULT_BINARY;
public static final ContentType DEFAULT_TEXT; public static final ContentType DEFAULT_TEXT;
static { static {
APPLICATION_JSON = new ContentType(MimeType.APPLICATION_JSON);
APPLICATION_FORM_URLENCODED = new ContentType(MimeType.APPLICATION_FORM_URLENCODED); APPLICATION_FORM_URLENCODED = new ContentType(MimeType.APPLICATION_FORM_URLENCODED);
MULTIPART_FORM_DATA = new ContentType(MimeType.MULTIPART_FORM_DATA); MULTIPART_FORM_DATA = new ContentType(MimeType.MULTIPART_FORM_DATA);
DEFAULT_BINARY = new ContentType(MimeType.APPLICATION_OCTET_STREAM); DEFAULT_BINARY = new ContentType(MimeType.APPLICATION_OCTET_STREAM);

View File

@ -12,16 +12,16 @@ import javax.net.ssl.SSLContext;
* @author jinyu(foxinmy@gmail.com) * @author jinyu(foxinmy@gmail.com)
* @date 2015年8月13日 * @date 2015年8月13日
* @since JDK 1.6 * @since JDK 1.6
* @see
*/ */
public final class HttpParams { public final class HttpParams {
/**
private boolean allowUserInteraction; * 连接超时时间(单位毫秒)
*/
private int connectTimeout; private int connectTimeout;
private int socketTimeout; /**
* 读取超时时间(单位毫秒)
*/
private int readTimeout; private int readTimeout;
private int chunkSize;
private boolean followRedirects;
/** /**
* 代理对象 * 代理对象
*/ */
@ -35,73 +35,26 @@ public final class HttpParams {
*/ */
private HostnameVerifier hostnameVerifier; private HostnameVerifier hostnameVerifier;
/**
* connectTimeout = 15000,readTimeout=20000
*/
public HttpParams() { public HttpParams() {
this(5000, 5000, 5000); this(15000, 20000);
} }
public HttpParams(int connectTimeout, int socketTimeout, int readTimeout) { public HttpParams(int connectTimeout, int readTimeout) {
this.allowUserInteraction = true;
this.connectTimeout = connectTimeout; this.connectTimeout = connectTimeout;
this.socketTimeout = socketTimeout;
this.readTimeout = readTimeout; this.readTimeout = readTimeout;
this.chunkSize = 4096;
this.followRedirects = false;
}
public boolean isAllowUserInteraction() {
return allowUserInteraction;
}
public HttpParams setAllowUserInteraction(boolean allowUserInteraction) {
this.allowUserInteraction = allowUserInteraction;
return this;
} }
public int getConnectTimeout() { public int getConnectTimeout() {
return connectTimeout; return connectTimeout;
} }
public HttpParams setConnectTimeout(int connectTimeout) {
this.connectTimeout = connectTimeout;
return this;
}
public int getSocketTimeout() {
return socketTimeout;
}
public HttpParams setSocketTimeout(int socketTimeout) {
this.socketTimeout = socketTimeout;
return this;
}
public int getReadTimeout() { public int getReadTimeout() {
return readTimeout; return readTimeout;
} }
public HttpParams setReadTimeout(int readTimeout) {
this.readTimeout = readTimeout;
return this;
}
public int getChunkSize() {
return chunkSize;
}
public HttpParams setChunkSize(int chunkSize) {
this.chunkSize = chunkSize;
return this;
}
public boolean isFollowRedirects() {
return followRedirects;
}
public HttpParams setFollowRedirects(boolean followRedirects) {
this.followRedirects = followRedirects;
return this;
}
public Proxy getProxy() { public Proxy getProxy() {
return proxy; return proxy;
} }
@ -130,22 +83,17 @@ public final class HttpParams {
} }
public static HttpParams copy(final HttpParams params) { public static HttpParams copy(final HttpParams params) {
return new HttpParams() return new HttpParams(params.getConnectTimeout(),
.setAllowUserInteraction(params.isAllowUserInteraction()) params.getReadTimeout()).setProxy(params.getProxy())
.setConnectTimeout(params.getConnectTimeout()) .setHostnameVerifier(params.getHostnameVerifier())
.setSocketTimeout(params.getSocketTimeout()) .setSSLContext(params.getSSLContext());
.setReadTimeout(params.getReadTimeout())
.setChunkSize(params.getChunkSize())
.setFollowRedirects(params.isFollowRedirects());
} }
@Override @Override
public String toString() { public String toString() {
return "HttpParams [allowUserInteraction=" + allowUserInteraction return "HttpParams [connectTimeout=" + connectTimeout
+ ", connectTimeout=" + connectTimeout + ", socketTimeout=" + ", readTimeout=" + readTimeout + ", proxy=" + proxy
+ socketTimeout + ", readTimeout=" + readTimeout + ", sslContext=" + sslContext + ", hostnameVerifier="
+ ", chunkSize=" + chunkSize + ", followRedirects=" + hostnameVerifier + "]";
+ followRedirects + ", proxy=" + proxy + ", sslContext="
+ sslContext + ", hostnameVerifier=" + hostnameVerifier + "]";
} }
} }

View File

@ -27,12 +27,6 @@ public class HttpRequest implements HttpMessage {
* @return * @return
*/ */
private final URI uri; private final URI uri;
/**
* 协议参数
*
* @return
*/
private HttpParams params;
/** /**
* 内容参数 * 内容参数
*/ */
@ -59,14 +53,6 @@ public class HttpRequest implements HttpMessage {
return uri; return uri;
} }
public HttpParams getParams() {
return params;
}
public void setParams(HttpParams params) {
this.params = params;
}
public HttpEntity getEntity() { public HttpEntity getEntity() {
return entity; return entity;
} }

View File

@ -11,7 +11,7 @@ import com.foxinmy.weixin4j.util.StringUtil;
* @className MimeType * @className MimeType
* @author jinyu * @author jinyu
* @date Jul 20, 2016 * @date Jul 20, 2016
* @since JDK 1.8 * @since JDK 1.6
*/ */
public class MimeType implements Serializable { public class MimeType implements Serializable {
@ -33,6 +33,7 @@ public class MimeType implements Serializable {
public static final MimeType AUDIO_MP3; public static final MimeType AUDIO_MP3;
public static final MimeType VIDEO_MPEG4; public static final MimeType VIDEO_MPEG4;
public static final MimeType TEXT_XML; public static final MimeType TEXT_XML;
public static final MimeType TEXT_JSON;
static { static {
APPLICATION_FORM_URLENCODED = valueOf("application/x-www-form-urlencoded"); APPLICATION_FORM_URLENCODED = valueOf("application/x-www-form-urlencoded");
@ -46,6 +47,7 @@ public class MimeType implements Serializable {
AUDIO_MP3 = valueOf("audio/mp3"); AUDIO_MP3 = valueOf("audio/mp3");
VIDEO_MPEG4 = valueOf("video/mpeg4"); VIDEO_MPEG4 = valueOf("video/mpeg4");
TEXT_XML = valueOf("text/xml"); TEXT_XML = valueOf("text/xml");
TEXT_JSON = valueOf("text/json");
} }
public MimeType(String type) { public MimeType(String type) {

View File

@ -13,7 +13,6 @@ import java.util.Map.Entry;
import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import com.foxinmy.weixin4j.http.entity.HttpEntity; import com.foxinmy.weixin4j.http.entity.HttpEntity;
import com.foxinmy.weixin4j.http.factory.HttpClientFactory; import com.foxinmy.weixin4j.http.factory.HttpClientFactory;
@ -31,19 +30,15 @@ import com.foxinmy.weixin4j.util.StringUtil;
*/ */
public class SimpleHttpClient extends AbstractHttpClient implements HttpClient { public class SimpleHttpClient extends AbstractHttpClient implements HttpClient {
protected HostnameVerifier createHostnameVerifier() { private final HttpParams params;
return new HostnameVerifier() {
@Override public SimpleHttpClient(HttpParams params) {
public boolean verify(String hostname, SSLSession session) { this.params = params;
return true;
}
};
} }
protected HttpURLConnection createHttpConnection(HttpRequest request) protected HttpURLConnection createHttpConnection(HttpRequest request)
throws IOException { throws IOException {
URI uri = request.getURI(); URI uri = request.getURI();
HttpParams params = request.getParams();
Proxy proxy = params != null ? params.getProxy() : null; Proxy proxy = params != null ? params.getProxy() : null;
URLConnection urlConnection = proxy != null ? uri.toURL() URLConnection urlConnection = proxy != null ? uri.toURL()
.openConnection(proxy) : uri.toURL().openConnection(); .openConnection(proxy) : uri.toURL().openConnection();
@ -59,7 +54,7 @@ public class SimpleHttpClient extends AbstractHttpClient implements HttpClient {
sslContext = HttpClientFactory.allowSSLContext(); sslContext = HttpClientFactory.allowSSLContext();
} }
if (hostnameVerifier == null) { if (hostnameVerifier == null) {
hostnameVerifier = createHostnameVerifier(); hostnameVerifier = HttpClientFactory.AllowHostnameVerifier.GLOBAL;
} }
HttpsURLConnection connection = (HttpsURLConnection) urlConnection; HttpsURLConnection connection = (HttpsURLConnection) urlConnection;
connection.setSSLSocketFactory(sslContext.getSocketFactory()); connection.setSSLSocketFactory(sslContext.getSocketFactory());
@ -81,14 +76,9 @@ public class SimpleHttpClient extends AbstractHttpClient implements HttpClient {
HttpURLConnection connection = createHttpConnection(request); HttpURLConnection connection = createHttpConnection(request);
String method = request.getMethod().name(); String method = request.getMethod().name();
// set parameters // set parameters
HttpParams params = request.getParams();
if (params != null) { if (params != null) {
connection.setAllowUserInteraction(params
.isAllowUserInteraction());
connection.setConnectTimeout(params.getConnectTimeout()); connection.setConnectTimeout(params.getConnectTimeout());
connection.setReadTimeout(params.getReadTimeout()); connection.setReadTimeout(params.getReadTimeout());
connection.setInstanceFollowRedirects(params
.isFollowRedirects());
} }
connection.setRequestMethod(method); connection.setRequestMethod(method);
connection.setDoInput(true); connection.setDoInput(true);
@ -134,14 +124,6 @@ public class SimpleHttpClient extends AbstractHttpClient implements HttpClient {
HttpEntity httpEntity = request.getEntity(); HttpEntity httpEntity = request.getEntity();
if (httpEntity != null) { if (httpEntity != null) {
connection.setUseCaches(false); connection.setUseCaches(false);
// Read Out Exception when connection.disconnect();
/*
* if (httpEntity.getContentLength() > 0l) {
* connection.setFixedLengthStreamingMode(httpEntity
* .getContentLength()); } else { connection
* .setChunkedStreamingMode(params != null ? params
* .getChunkSize() : 4096); }
*/
if (httpEntity.getContentLength() > 0l) { if (httpEntity.getContentLength() > 0l) {
connection.setRequestProperty(HttpHeaders.CONTENT_LENGTH, connection.setRequestProperty(HttpHeaders.CONTENT_LENGTH,
Long.toString(httpEntity.getContentLength())); Long.toString(httpEntity.getContentLength()));

View File

@ -42,7 +42,7 @@ public class SimpleHttpResponse extends AbstractHttpResponse {
} else { } else {
String connect = connection.getHeaderField("Connection"); String connect = connection.getHeaderField("Connection");
protocol = new HttpVersion(version, protocol = new HttpVersion(version,
"keep-alive".equalsIgnoreCase(connect)); KEEP_ALIVE.equalsIgnoreCase(connect));
} }
} }
return protocol; return protocol;

View File

@ -85,7 +85,11 @@ public class InputStreamBody extends AbstractContentBody {
} }
public long getContentLength() { public long getContentLength() {
return this.contentLength; try {
return Math.max(contentLength, this.in.available());
} catch (IOException e) {
return -1;
}
} }
public String getFilename() { public String getFilename() {

View File

@ -5,11 +5,18 @@ import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.X509TrustManager; import javax.net.ssl.X509TrustManager;
import com.foxinmy.weixin4j.http.HttpClient; import com.foxinmy.weixin4j.http.HttpClient;
import com.foxinmy.weixin4j.http.HttpClientException; import com.foxinmy.weixin4j.http.HttpClientException;
import com.foxinmy.weixin4j.http.HttpParams;
import com.foxinmy.weixin4j.http.support.apache3.HttpComponent3Factory;
import com.foxinmy.weixin4j.http.support.apache4.HttpComponent4Factory;
import com.foxinmy.weixin4j.http.support.netty.Netty4HttpClientFactory;
import com.foxinmy.weixin4j.http.support.okhttp.OkHttpClientFactory;
/** /**
* HttpClient工厂生产类:参考netty的InternalLoggerFactory * HttpClient工厂生产类:参考netty的InternalLoggerFactory
@ -29,7 +36,7 @@ public abstract class HttpClientFactory {
/** /**
* NettyHttpClient -> ApacheHttpClient(HttpComponent3&4) -> * NettyHttpClient -> ApacheHttpClient(HttpComponent3&4) ->
* SimpleHttpClient(HttpURLConnection) * OkHttpClient(2&3) -> SimpleHttpClient(HttpURLConnection)
* *
* @return * @return
*/ */
@ -44,7 +51,11 @@ public abstract class HttpClientFactory {
try { try {
f = new HttpComponent3Factory(); f = new HttpComponent3Factory();
} catch (Throwable e3) { } catch (Throwable e3) {
f = new SimpleHttpClientFactory(); try {
f = new OkHttpClientFactory();
} catch (Throwable e4) {
f = new SimpleHttpClientFactory();
}
} }
} }
} }
@ -67,7 +78,8 @@ public abstract class HttpClientFactory {
*/ */
public static void setDefaultFactory(HttpClientFactory defaultFactory) { public static void setDefaultFactory(HttpClientFactory defaultFactory) {
if (defaultFactory == null) { if (defaultFactory == null) {
throw new NullPointerException("defaultFactory"); throw new IllegalArgumentException(
"'defaultFactory' must not be empty");
} }
HttpClientFactory.defaultFactory = defaultFactory; HttpClientFactory.defaultFactory = defaultFactory;
} }
@ -81,6 +93,40 @@ public abstract class HttpClientFactory {
return getDefaultFactory().newInstance(); return getDefaultFactory().newInstance();
} }
/**
* 获取HttpClient实例
*
* @param params Http参数
*
* @return HttpClinet实例
*/
public static HttpClient getInstance(HttpParams params) {
HttpClientFactory clientFactory = getDefaultFactory();
clientFactory.resolveHttpParams(params);
return clientFactory.newInstance();
}
/**
* Resolve the Http Parameter
*
* @param params
* 请求参数
*/
public void resolveHttpParams(HttpParams params) {
if (params == null) {
throw new IllegalArgumentException("'params' must not be empty");
}
resolveHttpParams0(params);
}
/**
* Resolve the Http Parameter
*
* @param params
* 请求参数
*/
protected abstract void resolveHttpParams0(HttpParams params);
/** /**
* 获取HttpClient实例 * 获取HttpClient实例
* *
@ -92,7 +138,7 @@ public abstract class HttpClientFactory {
try { try {
SSLContext sslContext = SSLContext.getInstance("TLS"); SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, sslContext.init(null,
new X509TrustManager[] { createX509TrustManager() }, new X509TrustManager[] { AllowX509TrustManager.GLOBAL },
new java.security.SecureRandom()); new java.security.SecureRandom());
return sslContext; return sslContext;
} catch (NoSuchAlgorithmException e) { } catch (NoSuchAlgorithmException e) {
@ -104,24 +150,39 @@ public abstract class HttpClientFactory {
} }
} }
protected static X509TrustManager createX509TrustManager() { public static class AllowX509TrustManager implements X509TrustManager {
return new X509TrustManager() { public static final X509TrustManager GLOBAL = new AllowX509TrustManager();
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
@Override private AllowX509TrustManager() {
public void checkServerTrusted( }
X509Certificate[] paramArrayOfX509Certificate,
String paramString) throws CertificateException {
}
@Override @Override
public void checkClientTrusted( public X509Certificate[] getAcceptedIssuers() {
X509Certificate[] paramArrayOfX509Certificate, return new X509Certificate[0];
String paramString) throws CertificateException { }
}
}; @Override
public void checkServerTrusted(
X509Certificate[] paramArrayOfX509Certificate,
String paramString) throws CertificateException {
}
@Override
public void checkClientTrusted(
X509Certificate[] paramArrayOfX509Certificate,
String paramString) throws CertificateException {
}
}
public static class AllowHostnameVerifier implements HostnameVerifier {
public static final HostnameVerifier GLOBAL = new AllowHostnameVerifier();
private AllowHostnameVerifier() {
}
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
} }
} }

View File

@ -1,25 +0,0 @@
package com.foxinmy.weixin4j.http.factory;
import org.apache.commons.httpclient.HttpClient;
/**
* 使用commons-httpclient3.x
*
* @className HttpComponent3Factory
* @author jinyu(foxinmy@gmail.com)
* @date 2015年8月12日
* @since JDK 1.6
* @see
*/
public class HttpComponent3Factory extends HttpClientFactory {
public HttpComponent3Factory() {
// odd code
Class<HttpClient> _dead = HttpClient.class;
}
@Override
public com.foxinmy.weixin4j.http.HttpClient newInstance() {
return new HttpComponent3(new HttpClient());
}
}

View File

@ -1,39 +0,0 @@
package com.foxinmy.weixin4j.http.factory;
import org.apache.http.util.VersionInfo;
import com.foxinmy.weixin4j.http.HttpClient;
/**
* 使用Apache的HttpClient4.x
*
* @className HttpComponent4Factory
* @author jinyu(foxinmy@gmail.com)
* @date 2015年8月12日
* @since JDK 1.6
* @see
*/
public class HttpComponent4Factory extends HttpClientFactory {
private final VersionInfo version;
public HttpComponent4Factory() {
version = VersionInfo.loadVersionInfo("org.apache.http.client",
HttpClient.class.getClassLoader());
}
@Override
public HttpClient newInstance() {
String release = (version != null) ? version.getRelease()
: VersionInfo.UNAVAILABLE;
if (release.startsWith("4.")) {
if (release.startsWith("4.0") || release.startsWith("4.1")
|| release.startsWith("4.2")) {
return new HttpComponent4_1();
} else {
return new HttpComponent4_2();
}
}
throw new RuntimeException("unknown the HttpClient version:" + release);
}
}

View File

@ -1,119 +0,0 @@
package com.foxinmy.weixin4j.http.factory;
import java.io.IOException;
import java.net.InetSocketAddress;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpHost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.CoreProtocolPNames;
import com.foxinmy.weixin4j.http.HttpClientException;
import com.foxinmy.weixin4j.http.HttpHeaders;
import com.foxinmy.weixin4j.http.HttpParams;
import com.foxinmy.weixin4j.http.HttpRequest;
import com.foxinmy.weixin4j.http.HttpResponse;
import com.foxinmy.weixin4j.model.Consts;
/**
* Requires Apache HttpComponents 4.2 or lower
*
* @className HttpComponent4_1
* @author jinyu(foxinmy@gmail.com)
* @date 2015年8月18日
* @since JDK 1.6
* @see
*/
public class HttpComponent4_1 extends HttpComponent4 {
private final org.apache.http.client.HttpClient httpClient;
public HttpComponent4_1() {
this.httpClient = new DefaultHttpClient();
}
@Override
public HttpResponse execute(HttpRequest request) throws HttpClientException {
HttpResponse response = null;
try {
HttpRequestBase uriRequest = createHttpRequest(request.getMethod(),
request.getURI());
boolean useSSL = "https".equals(request.getURI().getScheme());
SSLContext sslContext = null;
X509HostnameVerifier hostnameVerifier = null;
HttpParams params = request.getParams();
if (params != null) {
if (params.getProxy() != null) {
InetSocketAddress socketAddress = (InetSocketAddress) params
.getProxy().address();
HttpHost proxy = new HttpHost(socketAddress.getHostName(),
socketAddress.getPort());
uriRequest.getParams().setParameter(
ConnRoutePNames.DEFAULT_PROXY, proxy);
useSSL = false;
}
uriRequest.getParams().setIntParameter(
CoreConnectionPNames.SOCKET_BUFFER_SIZE,
params.getChunkSize());
uriRequest.getParams().setIntParameter(
CoreConnectionPNames.SO_TIMEOUT,
params.getSocketTimeout());
uriRequest.getParams().setIntParameter(
CoreConnectionPNames.CONNECTION_TIMEOUT,
params.getConnectTimeout());
uriRequest.getParams().setParameter(
CoreProtocolPNames.HTTP_CONTENT_CHARSET, Consts.UTF_8);
uriRequest.getParams().setParameter(
CoreProtocolPNames.HTTP_ELEMENT_CHARSET, Consts.UTF_8.name());
uriRequest.getParams().setParameter(
CoreProtocolPNames.STRICT_TRANSFER_ENCODING, Consts.UTF_8);
uriRequest.getParams().setParameter(
HttpHeaders.CONTENT_ENCODING, Consts.UTF_8);
uriRequest.getParams().setParameter(HttpHeaders.ACCEPT_CHARSET,
Consts.UTF_8);
sslContext = params.getSSLContext();
if (params.getHostnameVerifier() != null) {
hostnameVerifier = new CustomHostnameVerifier(
params.getHostnameVerifier());
}
}
if (useSSL) {
if (sslContext == null) {
sslContext = HttpClientFactory.allowSSLContext();
}
if (hostnameVerifier == null) {
hostnameVerifier = SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
}
SSLSocketFactory socketFactory = new SSLSocketFactory(
sslContext);
socketFactory.setHostnameVerifier(hostnameVerifier);
Scheme scheme = new Scheme("https", socketFactory, 443);
httpClient.getConnectionManager().getSchemeRegistry()
.register(scheme);
}
addHeaders(request.getHeaders(), uriRequest);
addEntity(request.getEntity(), uriRequest);
org.apache.http.HttpResponse httpResponse = httpClient
.execute(uriRequest);
response = new HttpComponent4_1Response(httpResponse,
getContent(httpResponse));
handleResponse(response);
} catch (IOException e) {
throw new HttpClientException("I/O error on "
+ request.getMethod().name() + " request for \""
+ request.getURI().toString() + "\":" + e.getMessage(), e);
} finally {
if (response != null) {
response.close();
}
}
return response;
}
}

View File

@ -1,109 +0,0 @@
package com.foxinmy.weixin4j.http.factory;
import java.io.IOException;
import java.net.InetSocketAddress;
import javax.net.ssl.SSLContext;
import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.config.RequestConfig.Builder;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.config.ConnectionConfig;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import com.foxinmy.weixin4j.http.HttpClientException;
import com.foxinmy.weixin4j.http.HttpParams;
import com.foxinmy.weixin4j.http.HttpRequest;
import com.foxinmy.weixin4j.http.HttpResponse;
import com.foxinmy.weixin4j.model.Consts;
/**
* Requires Apache HttpComponents 4.3 or higher
*
* @className HttpComponent4_2
* @author jinyu(foxinmy@gmail.com)
* @date 2015年8月18日
* @since JDK 1.6
* @see
*/
public class HttpComponent4_2 extends HttpComponent4 {
private CloseableHttpClient httpClient;
public HttpComponent4_2() {
this.httpClient = HttpClientBuilder
.create()
.setDefaultConnectionConfig(
ConnectionConfig.custom().setCharset(Consts.UTF_8)
.build()).build();
}
@Override
public HttpResponse execute(HttpRequest request) throws HttpClientException {
HttpResponse response = null;
try {
HttpRequestBase uriRequest = createHttpRequest(request.getMethod(),
request.getURI());
boolean useSSL = "https".equals(request.getURI().getScheme());
SSLContext sslContext = null;
X509HostnameVerifier hostnameVerifier = null;
HttpParams params = request.getParams();
if (params != null) {
Builder requestConfig = RequestConfig.custom()
.setSocketTimeout(params.getSocketTimeout())
.setConnectTimeout(params.getConnectTimeout())
.setConnectionRequestTimeout(params.getReadTimeout());
if (params.getProxy() != null) {
InetSocketAddress socketAddress = (InetSocketAddress) params
.getProxy().address();
HttpHost proxy = new HttpHost(socketAddress.getHostName(),
socketAddress.getPort());
requestConfig.setProxy(proxy);
useSSL = false;
}
uriRequest.setConfig(requestConfig.build());
sslContext = params.getSSLContext();
if (params.getHostnameVerifier() != null) {
hostnameVerifier = new CustomHostnameVerifier(
params.getHostnameVerifier());
}
}
if (useSSL) {
if (sslContext == null) {
sslContext = HttpClientFactory.allowSSLContext();
}
if (hostnameVerifier == null) {
hostnameVerifier = SSLConnectionSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
}
httpClient = HttpClients
.custom()
.setHostnameVerifier(hostnameVerifier)
.setDefaultConnectionConfig(
ConnectionConfig.custom()
.setCharset(Consts.UTF_8).build())
.setSslcontext(sslContext).build();
}
addHeaders(request.getHeaders(), uriRequest);
addEntity(request.getEntity(), uriRequest);
CloseableHttpResponse httpResponse = httpClient.execute(uriRequest);
response = new HttpComponent4_2Response(httpResponse,
getContent(httpResponse));
handleResponse(response);
} catch (IOException e) {
throw new HttpClientException("I/O error on "
+ request.getMethod().name() + " request for \""
+ request.getURI().toString() + "\":" + e.getMessage(), e);
} finally {
if (response != null) {
response.close();
}
}
return response;
}
}

View File

@ -1,6 +1,7 @@
package com.foxinmy.weixin4j.http.factory; package com.foxinmy.weixin4j.http.factory;
import com.foxinmy.weixin4j.http.HttpClient; import com.foxinmy.weixin4j.http.HttpClient;
import com.foxinmy.weixin4j.http.HttpParams;
import com.foxinmy.weixin4j.http.SimpleHttpClient; import com.foxinmy.weixin4j.http.SimpleHttpClient;
/** /**
@ -14,8 +15,19 @@ import com.foxinmy.weixin4j.http.SimpleHttpClient;
*/ */
public class SimpleHttpClientFactory extends HttpClientFactory { public class SimpleHttpClientFactory extends HttpClientFactory {
private volatile SimpleHttpClient httpClient;
private HttpParams params;
@Override
protected void resolveHttpParams0(HttpParams params) {
this.params = params;
}
@Override @Override
public HttpClient newInstance() { public HttpClient newInstance() {
return new SimpleHttpClient(); if (this.httpClient == null) {
this.httpClient = new SimpleHttpClient(params);
}
return this.httpClient;
} }
} }

View File

@ -29,15 +29,19 @@ public class JsonMessageConverter extends AbstractMessageConverter {
private static final int MASK = BRACE | BRACKET; private static final int MASK = BRACE | BRACKET;
public JsonMessageConverter() { public JsonMessageConverter() {
super(MimeType.APPLICATION_JSON, new MimeType("application", "*+json")); super(MimeType.APPLICATION_JSON, MimeType.TEXT_JSON, new MimeType(
"application", "*+json"));
} }
@Override @Override
public boolean canConvert(Class<?> clazz, HttpResponse response) { public boolean canConvert(Class<?> clazz, HttpResponse response) {
if (!super.canConvert(clazz, response)) { if (!super.canConvert(clazz, response)) {
String disposition = response.getHeaders().getFirst(HttpHeaders.CONTENT_DISPOSITION); String disposition = response.getHeaders().getFirst(
String fileName = RegexUtil.regexFileNameFromContentDispositionHeader(disposition); HttpHeaders.CONTENT_DISPOSITION);
return (fileName != null && FileUtil.getFileExtension(fileName).equalsIgnoreCase(JSO)); String fileName = RegexUtil
.regexFileNameFromContentDispositionHeader(disposition);
return (fileName != null && FileUtil.getFileExtension(fileName)
.equalsIgnoreCase(JSO));
} }
return true; return true;
} }
@ -48,8 +52,10 @@ public class JsonMessageConverter extends AbstractMessageConverter {
} }
@Override @Override
protected <T> T convertInternal(Class<? extends T> clazz, InputStream body) throws IOException { protected <T> T convertInternal(Class<? extends T> clazz, InputStream body)
throws IOException {
byte[] bytes = IOUtil.toByteArray(body); byte[] bytes = IOUtil.toByteArray(body);
return JSON.parseObject(bytes, 0, bytes.length, charset.newDecoder(), clazz); return JSON.parseObject(bytes, 0, bytes.length, charset.newDecoder(),
clazz);
} }
} }

View File

@ -1,10 +1,8 @@
package com.foxinmy.weixin4j.http.factory; package com.foxinmy.weixin4j.http.support.apache3;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Socket; import java.net.Socket;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.List; import java.util.List;
@ -27,14 +25,12 @@ import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.methods.TraceMethod; import org.apache.commons.httpclient.methods.TraceMethod;
import org.apache.commons.httpclient.params.HttpConnectionParams; import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.ControllerThreadSocketFactory; import org.apache.commons.httpclient.protocol.ControllerThreadSocketFactory;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory; import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
import com.foxinmy.weixin4j.http.AbstractHttpClient; import com.foxinmy.weixin4j.http.AbstractHttpClient;
import com.foxinmy.weixin4j.http.HttpClientException; import com.foxinmy.weixin4j.http.HttpClientException;
import com.foxinmy.weixin4j.http.HttpHeaders; import com.foxinmy.weixin4j.http.HttpHeaders;
import com.foxinmy.weixin4j.http.HttpMethod; import com.foxinmy.weixin4j.http.HttpMethod;
import com.foxinmy.weixin4j.http.HttpParams;
import com.foxinmy.weixin4j.http.HttpRequest; import com.foxinmy.weixin4j.http.HttpRequest;
import com.foxinmy.weixin4j.http.HttpResponse; import com.foxinmy.weixin4j.http.HttpResponse;
import com.foxinmy.weixin4j.http.apache.MultipartEntity; import com.foxinmy.weixin4j.http.apache.MultipartEntity;
@ -59,11 +55,47 @@ public class HttpComponent3 extends AbstractHttpClient {
this.httpClient = httpClient; this.httpClient = httpClient;
} }
private org.apache.commons.httpclient.HttpMethod createHttpMethod( @Override
HttpMethod method, java.net.URI url) throws HttpClientException { public HttpResponse execute(HttpRequest request) throws HttpClientException {
HttpResponse response = null;
try {
org.apache.commons.httpclient.HttpMethod httpMethod = createRequest(request);
httpClient.executeMethod(httpMethod);
response = new HttpComponent3Response(httpMethod);
handleResponse(response);
} catch (IOException e) {
throw new HttpClientException("I/O error on "
+ request.getMethod().name() + " request for \""
+ request.getURI().toString() + "\":" + e.getMessage(), e);
} finally {
if (response != null) {
response.close();
}
}
return response;
}
/**
* Create HttpMethod
*/
protected org.apache.commons.httpclient.HttpMethod createRequest(
HttpRequest request) throws HttpClientException, IOException {
org.apache.commons.httpclient.HttpMethod httpMethod = createMethod(request);
resolveHeaders(request, httpMethod);
resolveContent(request, httpMethod);
return httpMethod;
}
/**
* Create HttpMethod
*/
protected org.apache.commons.httpclient.HttpMethod createMethod(
HttpRequest request) throws HttpClientException {
HttpMethod method = request.getMethod();
org.apache.commons.httpclient.HttpMethod httpMethod = null; org.apache.commons.httpclient.HttpMethod httpMethod = null;
try { try {
URI uri = new URI(url.toString(), false, Consts.UTF_8.name()); URI uri = new URI(request.getURI().toString(), false,
Consts.UTF_8.name());
if (method == HttpMethod.GET) { if (method == HttpMethod.GET) {
httpMethod = new GetMethod(); httpMethod = new GetMethod();
} else if (method == HttpMethod.HEAD) { } else if (method == HttpMethod.HEAD) {
@ -85,121 +117,79 @@ public class HttpComponent3 extends AbstractHttpClient {
httpMethod.setURI(uri); httpMethod.setURI(uri);
} catch (IOException e) { } catch (IOException e) {
throw new HttpClientException("I/O error on " + method.name() throw new HttpClientException("I/O error on " + method.name()
+ " setURI for \"" + url.toString() + "\":" + " setURI for \"" + request.toString() + "\":"
+ e.getMessage(), e); + e.getMessage(), e);
} }
return httpMethod; return httpMethod;
} }
@Override /**
public HttpResponse execute(HttpRequest request) throws HttpClientException { * Resolve Headers
HttpResponse response = null; */
try { protected void resolveHeaders(HttpRequest request,
org.apache.commons.httpclient.HttpMethod httpMethod = createHttpMethod( org.apache.commons.httpclient.HttpMethod httpMethod) {
request.getMethod(), request.getURI()); com.foxinmy.weixin4j.http.HttpHeaders headers = request.getHeaders();
boolean useSSL = "https".equals(request.getURI().getScheme()); if (headers == null) {
SSLContext sslContext = null; headers = new HttpHeaders();
HttpParams params = request.getParams(); }
if (params != null) { if (!headers.containsKey(HttpHeaders.HOST)) {
Proxy proxy = params.getProxy(); headers.set(HttpHeaders.HOST, request.getURI().getHost());
if (proxy != null) { }
InetSocketAddress socketAddress = (InetSocketAddress) proxy // Add default accept headers
.address(); if (!headers.containsKey(HttpHeaders.ACCEPT)) {
httpClient.getHostConfiguration().setProxy( headers.set(HttpHeaders.ACCEPT, "*/*");
socketAddress.getHostName(), }
socketAddress.getPort()); // Add default user agent
useSSL = false; if (!headers.containsKey(HttpHeaders.USER_AGENT)) {
} headers.set(HttpHeaders.USER_AGENT, "apache/httpclient3");
sslContext = params.getSSLContext(); }
httpClient.getHttpConnectionManager().getParams() for (Entry<String, List<String>> header : headers.entrySet()) {
.setConnectionTimeout(params.getConnectTimeout()); if (HttpHeaders.COOKIE.equalsIgnoreCase(header.getKey())) {
httpClient.getHttpConnectionManager().getParams() httpMethod.setRequestHeader(header.getKey(),
.setSendBufferSize(params.getChunkSize()); StringUtil.join(header.getValue(), ';'));
httpMethod.getParams().setSoTimeout(params.getSocketTimeout()); } else {
httpMethod.getParams().setHttpElementCharset( for (String headerValue : header.getValue()) {
Consts.UTF_8.name());
httpMethod.getParams().setParameter(
"http.protocol.uri-charset", Consts.UTF_8.name());
// httpMethod.getParams().setUriCharset(Consts.UTF_8.name());
httpMethod.getParams().setContentCharset(Consts.UTF_8.name());
}
if (useSSL) {
if (sslContext == null) {
sslContext = HttpClientFactory.allowSSLContext();
}
Protocol.registerProtocol("https", new Protocol("https",
new SSLProtocolSocketFactory(sslContext), 443));
}
com.foxinmy.weixin4j.http.HttpHeaders headers = request
.getHeaders();
if (headers == null) {
headers = new HttpHeaders();
}
if (!headers.containsKey(HttpHeaders.HOST)) {
headers.set(HttpHeaders.HOST, request.getURI().getHost());
}
// Add default accept headers
if (!headers.containsKey(HttpHeaders.ACCEPT)) {
headers.set(HttpHeaders.ACCEPT, "*/*");
}
// Add default user agent
if (!headers.containsKey(HttpHeaders.USER_AGENT)) {
headers.set(HttpHeaders.USER_AGENT, "apache/httpclient3");
}
for (Entry<String, List<String>> header : headers.entrySet()) {
if (HttpHeaders.COOKIE.equalsIgnoreCase(header.getKey())) {
httpMethod.setRequestHeader(header.getKey(), httpMethod.setRequestHeader(header.getKey(),
StringUtil.join(header.getValue(), ';')); headerValue != null ? headerValue : "");
} else {
for (String headerValue : header.getValue()) {
httpMethod.setRequestHeader(header.getKey(),
headerValue != null ? headerValue : "");
}
} }
} }
HttpEntity entity = request.getEntity();
if (entity != null) {
if (entity.getContentLength() > 0l) {
httpMethod.addRequestHeader(HttpHeaders.CONTENT_LENGTH,
Long.toString(entity.getContentLength()));
}
if (entity.getContentType() != null) {
httpMethod.addRequestHeader(HttpHeaders.CONTENT_TYPE,
entity.getContentType().toString());
}
RequestEntity requestEntity = null;
if (entity instanceof MultipartEntity) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
entity.writeTo(os);
os.flush();
requestEntity = new ByteArrayRequestEntity(
os.toByteArray(), entity.getContentType()
.toString());
os.close();
} else {
requestEntity = new InputStreamRequestEntity(
entity.getContent(), entity.getContentType()
.toString());
}
((EntityEnclosingMethod) httpMethod)
.setRequestEntity(requestEntity);
}
httpClient.executeMethod(httpMethod);
response = new HttpComponent3Response(httpMethod);
handleResponse(response);
} catch (IOException e) {
throw new HttpClientException("I/O error on "
+ request.getMethod().name() + " request for \""
+ request.getURI().toString() + "\":" + e.getMessage(), e);
} finally {
if (response != null) {
response.close();
}
} }
return response;
} }
private static class SSLProtocolSocketFactory implements /**
* Resolve Content
*/
protected void resolveContent(HttpRequest request,
org.apache.commons.httpclient.HttpMethod httpMethod)
throws IOException {
HttpEntity entity = request.getEntity();
if (entity != null) {
if (entity.getContentLength() > 0l) {
httpMethod.addRequestHeader(HttpHeaders.CONTENT_LENGTH,
Long.toString(entity.getContentLength()));
}
if (entity.getContentType() != null) {
httpMethod.addRequestHeader(HttpHeaders.CONTENT_TYPE, entity
.getContentType().toString());
}
RequestEntity requestEntity = null;
if (entity instanceof MultipartEntity) {
ByteArrayOutputStream os = new ByteArrayOutputStream();
entity.writeTo(os);
os.flush();
requestEntity = new ByteArrayRequestEntity(os.toByteArray(),
entity.getContentType().toString());
os.close();
} else {
requestEntity = new InputStreamRequestEntity(
entity.getContent(), entity.getContentType().toString());
}
((EntityEnclosingMethod) httpMethod)
.setRequestEntity(requestEntity);
}
}
public static class SSLProtocolSocketFactory implements
SecureProtocolSocketFactory { SecureProtocolSocketFactory {
private final SSLContext sslContext; private final SSLContext sslContext;

View File

@ -0,0 +1,80 @@
package com.foxinmy.weixin4j.http.support.apache3;
import java.net.InetSocketAddress;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpConnectionManager;
import org.apache.commons.httpclient.params.HttpClientParams;
import org.apache.commons.httpclient.protocol.Protocol;
import com.foxinmy.weixin4j.http.HttpParams;
import com.foxinmy.weixin4j.http.factory.HttpClientFactory;
import com.foxinmy.weixin4j.http.support.apache3.HttpComponent3.SSLProtocolSocketFactory;
import com.foxinmy.weixin4j.model.Consts;
/**
* 使用commons-httpclient3.x
*
* @className HttpComponent3Factory
* @author jinyu(foxinmy@gmail.com)
* @date 2015年8月12日
* @since JDK 1.6
*/
public class HttpComponent3Factory extends HttpClientFactory {
private final HttpClient httpClient;
public HttpComponent3Factory() {
this(new HttpClient());
}
public HttpComponent3Factory(HttpClient httpClient) {
this.httpClient = httpClient;
this.httpClient.getParams().setHttpElementCharset(Consts.UTF_8.name());
this.httpClient.getParams().setParameter("http.protocol.uri-charset",
Consts.UTF_8.name());
// httpMethod.getParams().setUriCharset(Consts.UTF_8.name());
this.httpClient.getParams().setContentCharset(Consts.UTF_8.name());
}
/**
* Resolve Parameter
*/
@Override
protected void resolveHttpParams0(HttpParams params) {
if (params.getProxy() != null) {
InetSocketAddress socketAddress = (InetSocketAddress) params
.getProxy().address();
httpClient.getHostConfiguration().setProxy(
socketAddress.getHostName(), socketAddress.getPort());
}
if (params.getSSLContext() != null) {
Protocol.registerProtocol("https", new Protocol("https",
new SSLProtocolSocketFactory(params.getSSLContext()), 443));
}
httpClient.getHttpConnectionManager().getParams()
.setConnectionTimeout(params.getConnectTimeout());
}
public void setHttpConnectionManager(
HttpConnectionManager httpConnectionManager) {
if (httpConnectionManager == null) {
throw new IllegalArgumentException(
"'httpConnectionManager' must not be null");
}
httpClient.setHttpConnectionManager(httpConnectionManager);
}
public void setHttpClientParams(HttpClientParams httpClientParams) {
if (httpClientParams == null) {
throw new IllegalArgumentException(
"'httpClientParams' must not be null");
}
httpClient.setParams(httpClientParams);
}
@Override
public com.foxinmy.weixin4j.http.HttpClient newInstance() {
return new HttpComponent3(httpClient);
}
}

View File

@ -1,4 +1,4 @@
package com.foxinmy.weixin4j.http.factory; package com.foxinmy.weixin4j.http.support.apache3;
import java.io.IOException; import java.io.IOException;
@ -54,9 +54,9 @@ public class HttpComponent3Response extends AbstractHttpResponse {
} }
Header connection = httpMethod.getResponseHeader("Connection"); Header connection = httpMethod.getResponseHeader("Connection");
if (protocol == null) { if (protocol == null) {
protocol = new HttpVersion("HTTP", version.getMinor(), protocol = new HttpVersion("HTTP", version.getMajor(),
version.getMajor(), connection != null version.getMinor(), connection != null
&& "keep-alive".equalsIgnoreCase(connection && KEEP_ALIVE.equalsIgnoreCase(connection
.getValue())); .getValue()));
} }
return protocol; return protocol;

View File

@ -1,7 +1,8 @@
package com.foxinmy.weixin4j.http.factory; package com.foxinmy.weixin4j.http.support.apache4;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.net.URI;
import java.security.cert.X509Certificate; import java.security.cert.X509Certificate;
import java.util.List; import java.util.List;
import java.util.Map.Entry; import java.util.Map.Entry;
@ -29,6 +30,7 @@ import com.foxinmy.weixin4j.http.AbstractHttpClient;
import com.foxinmy.weixin4j.http.HttpClientException; import com.foxinmy.weixin4j.http.HttpClientException;
import com.foxinmy.weixin4j.http.HttpHeaders; import com.foxinmy.weixin4j.http.HttpHeaders;
import com.foxinmy.weixin4j.http.HttpMethod; import com.foxinmy.weixin4j.http.HttpMethod;
import com.foxinmy.weixin4j.http.HttpRequest;
import com.foxinmy.weixin4j.http.apache.MultipartEntity; import com.foxinmy.weixin4j.http.apache.MultipartEntity;
import com.foxinmy.weixin4j.http.entity.HttpEntity; import com.foxinmy.weixin4j.http.entity.HttpEntity;
import com.foxinmy.weixin4j.util.StringUtil; import com.foxinmy.weixin4j.util.StringUtil;
@ -43,8 +45,25 @@ import com.foxinmy.weixin4j.util.StringUtil;
* @see * @see
*/ */
public abstract class HttpComponent4 extends AbstractHttpClient { public abstract class HttpComponent4 extends AbstractHttpClient {
protected HttpRequestBase createHttpRequest(HttpMethod method,
java.net.URI uri) throws HttpClientException { /**
* Create HttpRequest
*/
protected HttpRequestBase createRequest(HttpRequest request)
throws HttpClientException, IOException {
HttpRequestBase httpRequest = createMethod(request);
resolveHeaders(request.getHeaders(), httpRequest);
resolveContent(request.getEntity(), httpRequest);
return httpRequest;
}
/**
* Create HttpMethod
*/
protected HttpRequestBase createMethod(HttpRequest request)
throws HttpClientException {
HttpMethod method = request.getMethod();
URI uri = request.getURI();
if (method == HttpMethod.GET) { if (method == HttpMethod.GET) {
return new HttpGet(uri); return new HttpGet(uri);
} else if (method == HttpMethod.HEAD) { } else if (method == HttpMethod.HEAD) {
@ -65,7 +84,11 @@ public abstract class HttpComponent4 extends AbstractHttpClient {
} }
} }
protected void addHeaders(HttpHeaders headers, HttpRequestBase uriRequest) { /**
* Resolve Headers
*/
protected void resolveHeaders(HttpHeaders headers,
HttpRequestBase httpRequest) {
if (headers == null) { if (headers == null) {
headers = new HttpHeaders(); headers = new HttpHeaders();
} }
@ -77,21 +100,23 @@ public abstract class HttpComponent4 extends AbstractHttpClient {
if (!headers.containsKey(HttpHeaders.USER_AGENT)) { if (!headers.containsKey(HttpHeaders.USER_AGENT)) {
headers.set(HttpHeaders.USER_AGENT, "apache/httpclient4"); headers.set(HttpHeaders.USER_AGENT, "apache/httpclient4");
} }
for (Entry<String, List<String>> header : headers for (Entry<String, List<String>> header : headers.entrySet()) {
.entrySet()) {
if (HttpHeaders.COOKIE.equalsIgnoreCase(header.getKey())) { if (HttpHeaders.COOKIE.equalsIgnoreCase(header.getKey())) {
uriRequest.setHeader(header.getKey(), httpRequest.setHeader(header.getKey(),
StringUtil.join(header.getValue(), ';')); StringUtil.join(header.getValue(), ';'));
} else { } else {
for (String headerValue : header.getValue()) { for (String headerValue : header.getValue()) {
uriRequest.setHeader(header.getKey(), httpRequest.setHeader(header.getKey(),
headerValue != null ? headerValue : ""); headerValue != null ? headerValue : "");
} }
} }
} }
} }
protected void addEntity(HttpEntity entity, HttpRequestBase uriRequest) /**
* Resolve Content
*/
protected void resolveContent(HttpEntity entity, HttpRequestBase httpRequest)
throws IOException { throws IOException {
if (entity != null) { if (entity != null) {
AbstractHttpEntity httpEntity = null; AbstractHttpEntity httpEntity = null;
@ -107,7 +132,8 @@ public abstract class HttpComponent4 extends AbstractHttpClient {
entity.getContentLength()); entity.getContentLength());
} }
httpEntity.setContentType(entity.getContentType().toString()); httpEntity.setContentType(entity.getContentType().toString());
((HttpEntityEnclosingRequestBase) uriRequest).setEntity(httpEntity); ((HttpEntityEnclosingRequestBase) httpRequest)
.setEntity(httpEntity);
} }
} }

View File

@ -0,0 +1,47 @@
package com.foxinmy.weixin4j.http.support.apache4;
import org.apache.http.util.VersionInfo;
import com.foxinmy.weixin4j.http.HttpClient;
import com.foxinmy.weixin4j.http.HttpParams;
import com.foxinmy.weixin4j.http.factory.HttpClientFactory;
/**
* 使用Apache的HttpClient4.x
*
* @className HttpComponent4Factory
* @author jinyu(foxinmy@gmail.com)
* @date 2015年8月12日
* @since JDK 1.6
*/
public class HttpComponent4Factory extends HttpClientFactory {
private static HttpClientFactory httpComponentFactory;
static {
VersionInfo version = VersionInfo.loadVersionInfo(
"org.apache.http.client", HttpClient.class.getClassLoader());
String release = (version != null) ? version.getRelease()
: VersionInfo.UNAVAILABLE;
if (release.startsWith("4.")) {
if (release.startsWith("4.0") || release.startsWith("4.1")
|| release.startsWith("4.2")) {
httpComponentFactory = new HttpComponent4_1Factory();
} else {
httpComponentFactory = new HttpComponent4_2Factory();
}
} else {
throw new RuntimeException("unknown the HttpComponent version:"
+ release);
}
}
@Override
public HttpClient newInstance() {
return httpComponentFactory.newInstance();
}
@Override
protected void resolveHttpParams0(HttpParams params) {
httpComponentFactory.resolveHttpParams(params);
}
}

View File

@ -0,0 +1,49 @@
package com.foxinmy.weixin4j.http.support.apache4;
import java.io.IOException;
import org.apache.http.client.methods.HttpRequestBase;
import com.foxinmy.weixin4j.http.HttpClientException;
import com.foxinmy.weixin4j.http.HttpRequest;
import com.foxinmy.weixin4j.http.HttpResponse;
/**
* Requires Apache HttpComponents 4.2 or lower
*
* @className HttpComponent4_1
* @author jinyu(foxinmy@gmail.com)
* @date 2015年8月18日
* @since JDK 1.6
* @see
*/
public class HttpComponent4_1 extends HttpComponent4 {
private final org.apache.http.client.HttpClient httpClient;
public HttpComponent4_1(org.apache.http.client.HttpClient httpClient) {
this.httpClient = httpClient;
}
@Override
public HttpResponse execute(HttpRequest request) throws HttpClientException {
HttpResponse response = null;
try {
HttpRequestBase uriRequest = createRequest(request);
org.apache.http.HttpResponse httpResponse = httpClient
.execute(uriRequest);
response = new HttpComponent4_1Response(httpResponse,
getContent(httpResponse));
handleResponse(response);
} catch (IOException e) {
throw new HttpClientException("I/O error on "
+ request.getMethod().name() + " request for \""
+ request.getURI().toString() + "\":" + e.getMessage(), e);
} finally {
if (response != null) {
response.close();
}
}
return response;
}
}

View File

@ -0,0 +1,105 @@
package com.foxinmy.weixin4j.http.support.apache4;
import java.net.InetSocketAddress;
import org.apache.http.HttpHost;
import org.apache.http.conn.params.ConnRoutePNames;
import org.apache.http.conn.scheme.Scheme;
import org.apache.http.conn.ssl.SSLSocketFactory;
import org.apache.http.conn.ssl.X509HostnameVerifier;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.CoreConnectionPNames;
import org.apache.http.params.CoreProtocolPNames;
import com.foxinmy.weixin4j.http.HttpClient;
import com.foxinmy.weixin4j.http.HttpHeaders;
import com.foxinmy.weixin4j.http.HttpParams;
import com.foxinmy.weixin4j.http.factory.HttpClientFactory;
import com.foxinmy.weixin4j.http.support.apache4.HttpComponent4.CustomHostnameVerifier;
import com.foxinmy.weixin4j.model.Consts;
/**
* 使用Apache的HttpClient<=4.2
*
* @className HttpComponent4Factory
* @author jinyu(foxinmy@gmail.com)
* @date 2015年8月12日
* @since JDK 1.6
*/
public class HttpComponent4_1Factory extends HttpClientFactory {
private final org.apache.http.client.HttpClient httpClient;
public HttpComponent4_1Factory() {
this(new DefaultHttpClient());
}
public HttpComponent4_1Factory(org.apache.http.client.HttpClient httpClient) {
this.httpClient = httpClient;
}
@Override
protected void resolveHttpParams0(HttpParams params) {
if (params == null) {
throw new IllegalArgumentException("'params' must not be empty");
}
if (params.getProxy() != null) {
InetSocketAddress socketAddress = (InetSocketAddress) params
.getProxy().address();
HttpHost proxy = new HttpHost(socketAddress.getHostName(),
socketAddress.getPort());
httpClient.getParams().setParameter(ConnRoutePNames.DEFAULT_PROXY,
proxy);
}
httpClient.getParams().setIntParameter(
CoreConnectionPNames.CONNECTION_TIMEOUT,
params.getConnectTimeout());
httpClient.getParams().setIntParameter(
CoreConnectionPNames.SO_TIMEOUT,
params.getReadTimeout());
httpClient.getParams().setParameter(
CoreProtocolPNames.HTTP_CONTENT_CHARSET, Consts.UTF_8);
httpClient.getParams().setParameter(
CoreProtocolPNames.HTTP_ELEMENT_CHARSET, Consts.UTF_8.name());
httpClient.getParams().setParameter(
CoreProtocolPNames.STRICT_TRANSFER_ENCODING, Consts.UTF_8);
httpClient.getParams().setParameter(HttpHeaders.CONTENT_ENCODING,
Consts.UTF_8);
httpClient.getParams().setParameter(HttpHeaders.ACCEPT_CHARSET,
Consts.UTF_8);
if (params.getSSLContext() != null) {
X509HostnameVerifier hostnameVerifier = null;
if (params.getHostnameVerifier() != null) {
hostnameVerifier = new CustomHostnameVerifier(
params.getHostnameVerifier());
}
if (hostnameVerifier == null) {
hostnameVerifier = SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER;
}
SSLSocketFactory socketFactory = new SSLSocketFactory(
params.getSSLContext());
socketFactory.setHostnameVerifier(hostnameVerifier);
Scheme scheme = new Scheme("https", socketFactory, 443);
httpClient.getConnectionManager().getSchemeRegistry()
.register(scheme);
}
}
/**
* 设置Http参数
*
* @see org.apache.http.params.HttpParams
* @param name
* 参数名
* @param value
* 参数值
*/
public void setParameter(String name, Object value) {
httpClient.getParams().setParameter(name, value);
}
@Override
public HttpClient newInstance() {
return new HttpComponent4_1(httpClient);
}
}

View File

@ -1,4 +1,4 @@
package com.foxinmy.weixin4j.http.factory; package com.foxinmy.weixin4j.http.support.apache4;
import java.io.IOException; import java.io.IOException;
@ -52,8 +52,8 @@ public class HttpComponent4_1Response extends AbstractHttpResponse {
Header connection = httpResponse.getFirstHeader("Connection"); Header connection = httpResponse.getFirstHeader("Connection");
protocol = new HttpVersion(version.getProtocol(), protocol = new HttpVersion(version.getProtocol(),
version.getMajor(), version.getMinor(), connection != null version.getMajor(), version.getMinor(), connection != null
&& connection.getValue().equalsIgnoreCase( && KEEP_ALIVE.equalsIgnoreCase(connection
"keep-alive")); .getValue()));
} }
return protocol; return protocol;
} }

View File

@ -0,0 +1,50 @@
package com.foxinmy.weixin4j.http.support.apache4;
import java.io.IOException;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.CloseableHttpClient;
import com.foxinmy.weixin4j.http.HttpClientException;
import com.foxinmy.weixin4j.http.HttpRequest;
import com.foxinmy.weixin4j.http.HttpResponse;
/**
* Requires Apache HttpComponents 4.3 or higher
*
* @className HttpComponent4_2
* @author jinyu(foxinmy@gmail.com)
* @date 2015年8月18日
* @since JDK 1.6
* @see
*/
public class HttpComponent4_2 extends HttpComponent4 {
private final CloseableHttpClient httpClient;
public HttpComponent4_2(CloseableHttpClient httpClient) {
this.httpClient = httpClient;
}
@Override
public HttpResponse execute(HttpRequest request) throws HttpClientException {
HttpResponse response = null;
try {
HttpRequestBase uriRequest = createRequest(request);
CloseableHttpResponse httpResponse = httpClient.execute(uriRequest);
response = new HttpComponent4_2Response(httpResponse,
getContent(httpResponse));
handleResponse(response);
} catch (IOException e) {
throw new HttpClientException("I/O error on "
+ request.getMethod().name() + " request for \""
+ request.getURI().toString() + "\":" + e.getMessage(), e);
} finally {
if (response != null) {
response.close();
}
}
return response;
}
}

View File

@ -0,0 +1,101 @@
package com.foxinmy.weixin4j.http.support.apache4;
import java.net.InetSocketAddress;
import org.apache.http.HttpHost;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.ConnectionConfig;
import org.apache.http.config.SocketConfig;
import org.apache.http.conn.HttpClientConnectionManager;
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.protocol.HttpProcessor;
import com.foxinmy.weixin4j.http.HttpClient;
import com.foxinmy.weixin4j.http.HttpParams;
import com.foxinmy.weixin4j.http.factory.HttpClientFactory;
import com.foxinmy.weixin4j.http.support.apache4.HttpComponent4.CustomHostnameVerifier;
import com.foxinmy.weixin4j.model.Consts;
/**
* 使用Apache的HttpClient>=4.3
*
* @className HttpComponent4Factory
* @author jinyu(foxinmy@gmail.com)
* @date 2015年8月12日
* @since JDK 1.6
*/
public class HttpComponent4_2Factory extends HttpClientFactory {
private volatile CloseableHttpClient httpClient;
private final HttpClientBuilder clientBuilder;
public HttpComponent4_2Factory() {
this(HttpClients.custom().setDefaultConnectionConfig(
ConnectionConfig.custom().setCharset(Consts.UTF_8).build()));
}
public HttpComponent4_2Factory(HttpClientBuilder clientBuilder) {
this.clientBuilder = clientBuilder;
}
@Override
public void resolveHttpParams0(HttpParams params) {
clientBuilder.setDefaultRequestConfig(RequestConfig.custom()
.setConnectTimeout(params.getConnectTimeout())
.setConnectionRequestTimeout(params.getReadTimeout()).build());
if (params.getProxy() != null) {
InetSocketAddress socketAddress = (InetSocketAddress) params
.getProxy().address();
HttpHost proxy = new HttpHost(socketAddress.getHostName(),
socketAddress.getPort());
clientBuilder.setProxy(proxy);
}
if (params.getHostnameVerifier() != null) {
clientBuilder.setHostnameVerifier(new CustomHostnameVerifier(params
.getHostnameVerifier()));
}
if (params.getSSLContext() != null) {
clientBuilder.setSslcontext(params.getSSLContext());
}
}
public HttpComponent4_2Factory setDefaultConnectionConfig(
ConnectionConfig connectionConfig) {
clientBuilder.setDefaultConnectionConfig(connectionConfig);
return this;
}
public HttpComponent4_2Factory setDefaultSocketConfig(
SocketConfig socketConfig) {
clientBuilder.setDefaultSocketConfig(socketConfig);
return this;
}
public HttpComponent4_2Factory setConnectionManager(
HttpClientConnectionManager connectionManager) {
clientBuilder.setConnectionManager(connectionManager);
return this;
}
public HttpComponent4_2Factory setHttpProcessor(HttpProcessor httpprocessor) {
clientBuilder.setHttpProcessor(httpprocessor);
return this;
}
public HttpComponent4_2Factory retryHandler(
HttpRequestRetryHandler retryHandler) {
clientBuilder.setRetryHandler(retryHandler);
return this;
}
@Override
public HttpClient newInstance() {
if (httpClient == null) {
this.httpClient = clientBuilder.build();
}
return new HttpComponent4_2(httpClient);
}
}

View File

@ -1,4 +1,4 @@
package com.foxinmy.weixin4j.http.factory; package com.foxinmy.weixin4j.http.support.apache4;
import java.io.IOException; import java.io.IOException;
@ -55,8 +55,8 @@ public class HttpComponent4_2Response extends AbstractHttpResponse {
Header connection = httpResponse.getFirstHeader("Connection"); Header connection = httpResponse.getFirstHeader("Connection");
protocol = new HttpVersion(version.getProtocol(), protocol = new HttpVersion(version.getProtocol(),
version.getMajor(), version.getMinor(), connection != null version.getMajor(), version.getMinor(), connection != null
&& connection.getValue().equalsIgnoreCase( && KEEP_ALIVE.equalsIgnoreCase(connection
"keep-alive")); .getValue()));
} }
return protocol; return protocol;
} }

View File

@ -1,4 +1,4 @@
package com.foxinmy.weixin4j.http.factory; package com.foxinmy.weixin4j.http.support.netty;
import io.netty.bootstrap.Bootstrap; import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
@ -8,7 +8,6 @@ import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener; import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOption;
import io.netty.channel.SimpleChannelInboundHandler; import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.DefaultFullHttpRequest; import io.netty.handler.codec.http.DefaultFullHttpRequest;
import io.netty.handler.codec.http.DefaultHttpRequest; import io.netty.handler.codec.http.DefaultHttpRequest;
@ -16,7 +15,6 @@ import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpMethod; import io.netty.handler.codec.http.HttpMethod;
import io.netty.handler.codec.http.HttpVersion; import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.ssl.SslHandler; import io.netty.handler.ssl.SslHandler;
import io.netty.handler.timeout.ReadTimeoutHandler;
import java.io.IOException; import java.io.IOException;
import java.net.InetAddress; import java.net.InetAddress;
@ -25,7 +23,6 @@ import java.net.URI;
import java.util.List; import java.util.List;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLEngine;
@ -37,6 +34,7 @@ import com.foxinmy.weixin4j.http.HttpParams;
import com.foxinmy.weixin4j.http.HttpRequest; import com.foxinmy.weixin4j.http.HttpRequest;
import com.foxinmy.weixin4j.http.HttpResponse; import com.foxinmy.weixin4j.http.HttpResponse;
import com.foxinmy.weixin4j.http.entity.HttpEntity; import com.foxinmy.weixin4j.http.entity.HttpEntity;
import com.foxinmy.weixin4j.http.factory.HttpClientFactory;
import com.foxinmy.weixin4j.model.Consts; import com.foxinmy.weixin4j.model.Consts;
import com.foxinmy.weixin4j.util.SettableFuture; import com.foxinmy.weixin4j.util.SettableFuture;
import com.foxinmy.weixin4j.util.StringUtil; import com.foxinmy.weixin4j.util.StringUtil;
@ -53,25 +51,19 @@ import com.foxinmy.weixin4j.util.StringUtil;
public class Netty4HttpClient extends AbstractHttpClient { public class Netty4HttpClient extends AbstractHttpClient {
private final Bootstrap bootstrap; private final Bootstrap bootstrap;
private final HttpParams params;
public Netty4HttpClient(Bootstrap bootstrap) { public Netty4HttpClient(Bootstrap bootstrap, HttpParams params) {
this.bootstrap = bootstrap; this.bootstrap = bootstrap;
this.params = params;
} }
@Override @Override
public HttpResponse execute(HttpRequest request) throws HttpClientException { public HttpResponse execute(final HttpRequest request)
throws HttpClientException {
HttpResponse response = null; HttpResponse response = null;
try { try {
final URI uri = request.getURI(); final URI uri = request.getURI();
final HttpParams params = request.getParams();
if (params != null) {
bootstrap.option(ChannelOption.CONNECT_TIMEOUT_MILLIS,
params.getConnectTimeout());
}
final boolean useProxy = params != null
&& params.getProxy() != null;
final boolean useSSL = "https".equals(uri.getScheme()) && !useProxy;
final DefaultHttpRequest uriRequest = createRequest(request);
final SettableFuture<HttpResponse> future = new SettableFuture<HttpResponse>(); final SettableFuture<HttpResponse> future = new SettableFuture<HttpResponse>();
ChannelFutureListener listener = new ChannelFutureListener() { ChannelFutureListener listener = new ChannelFutureListener() {
@Override @Override
@ -79,9 +71,8 @@ public class Netty4HttpClient extends AbstractHttpClient {
throws Exception { throws Exception {
if (channelFuture.isSuccess()) { if (channelFuture.isSuccess()) {
Channel channel = channelFuture.channel(); Channel channel = channelFuture.channel();
// ssl if ("https".equals(uri.getScheme())) {
SSLContext sslContext = null; SSLContext sslContext;
if (useSSL) {
if (params != null if (params != null
&& params.getSSLContext() != null) { && params.getSSLContext() != null) {
sslContext = params.getSSLContext(); sslContext = params.getSSLContext();
@ -93,25 +84,20 @@ public class Netty4HttpClient extends AbstractHttpClient {
sslEngine.setUseClientMode(true); sslEngine.setUseClientMode(true);
channel.pipeline().addFirst( channel.pipeline().addFirst(
new SslHandler(sslEngine)); new SslHandler(sslEngine));
if (params != null && params.getReadTimeout() > 0) {
channel.pipeline().addFirst(
new ReadTimeoutHandler(params
.getReadTimeout(),
TimeUnit.MILLISECONDS));
}
} }
channel.pipeline().addLast(new RequestHandler(future)); channel.pipeline().addLast(new RequestHandler(future));
DefaultHttpRequest uriRequest = createRequest(request);
channel.writeAndFlush(uriRequest); channel.writeAndFlush(uriRequest);
} else { } else {
future.setException(channelFuture.cause()); future.setException(channelFuture.cause());
} }
} }
}; };
InetSocketAddress address = useProxy ? (InetSocketAddress) params InetSocketAddress address = params != null
&& params.getProxy() != null ? (InetSocketAddress) params
.getProxy().address() : new InetSocketAddress( .getProxy().address() : new InetSocketAddress(
InetAddress.getByName(uri.getHost()), getPort(uri)); InetAddress.getByName(uri.getHost()), getPort(uri));
bootstrap.connect(address).syncUninterruptibly() bootstrap.connect(address).addListener(listener);
.addListener(listener);
response = future.get(); response = future.get();
handleResponse(response); handleResponse(response);
} catch (IOException e) { } catch (IOException e) {

View File

@ -1,4 +1,4 @@
package com.foxinmy.weixin4j.http.factory; package com.foxinmy.weixin4j.http.support.netty;
import io.netty.bootstrap.Bootstrap; import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelInitializer;
@ -13,47 +13,70 @@ import io.netty.handler.codec.http.HttpContentDecompressor;
import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpResponseDecoder; import io.netty.handler.codec.http.HttpResponseDecoder;
import io.netty.handler.stream.ChunkedWriteHandler; import io.netty.handler.stream.ChunkedWriteHandler;
import io.netty.handler.timeout.ReadTimeoutHandler;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import com.foxinmy.weixin4j.http.HttpClient; import com.foxinmy.weixin4j.http.HttpClient;
import com.foxinmy.weixin4j.http.HttpParams;
import com.foxinmy.weixin4j.http.factory.HttpClientFactory;
/** /**
* 使用Netty * 使用Netty4
* *
* @className Netty4HttpClientFactory * @className Netty4HttpClientFactory
* @author jinyu(foxinmy@gmail.com) * @author jinyu(foxinmy@gmail.com)
* @date 2015年8月30日 * @date 2015年8月30日
* @since JDK 1.6 * @since JDK 1.6
* @see
*/ */
public class Netty4HttpClientFactory extends HttpClientFactory { public class Netty4HttpClientFactory extends HttpClientFactory {
/** private volatile Bootstrap bootstrap;
* worker线程数,默认设置为cpu的核数 * 4 private EventLoopGroup eventLoopGroup;
*/ private Map<ChannelOption<?>, ?> options;
private final int workerThreads; private HttpParams params;
public Netty4HttpClientFactory() { public Netty4HttpClientFactory() {
this(Runtime.getRuntime().availableProcessors() * 4); this(new NioEventLoopGroup(
Runtime.getRuntime().availableProcessors() * 4));
} }
public Netty4HttpClientFactory(int workerThreads) { public Netty4HttpClientFactory(EventLoopGroup eventLoopGroup) {
this.workerThreads = workerThreads; this.eventLoopGroup = eventLoopGroup;
} }
private volatile Bootstrap bootstrap;
@Override @Override
public HttpClient newInstance() { protected void resolveHttpParams0(HttpParams params) {
this.params = params;
}
public Netty4HttpClientFactory setOptions(Map<ChannelOption<?>, ?> options) {
if (options == null) {
throw new IllegalArgumentException("'options' must not be empty");
}
this.options = options;
return this;
}
private Bootstrap getBootstrap() {
if (bootstrap == null) { if (bootstrap == null) {
bootstrap = new Bootstrap(); bootstrap = new Bootstrap();
bootstrap.option(ChannelOption.SO_KEEPALIVE, true).option( bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class)
ChannelOption.TCP_NODELAY, true);
EventLoopGroup workerGroup = new NioEventLoopGroup(workerThreads);
bootstrap.group(workerGroup).channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() { .handler(new ChannelInitializer<SocketChannel>() {
@Override @Override
protected void initChannel(SocketChannel channel) protected void initChannel(SocketChannel channel)
throws Exception { throws Exception {
ChannelPipeline pipeline = channel.pipeline(); ChannelPipeline pipeline = channel.pipeline();
if (params != null) {
channel.config().setConnectTimeoutMillis(
params.getConnectTimeout());
if (options != null) {
channel.config().setOptions(options);
}
pipeline.addLast(new ReadTimeoutHandler(params
.getReadTimeout(),
TimeUnit.MILLISECONDS));
}
pipeline.addLast(new HttpClientCodec()); pipeline.addLast(new HttpClientCodec());
pipeline.addLast(new HttpContentDecompressor()); pipeline.addLast(new HttpContentDecompressor());
pipeline.addLast(new ChunkedWriteHandler()); pipeline.addLast(new ChunkedWriteHandler());
@ -63,6 +86,11 @@ public class Netty4HttpClientFactory extends HttpClientFactory {
} }
}); });
} }
return new Netty4HttpClient(bootstrap); return bootstrap;
}
@Override
public HttpClient newInstance() {
return new Netty4HttpClient(getBootstrap(), params);
} }
} }

View File

@ -1,4 +1,4 @@
package com.foxinmy.weixin4j.http.factory; package com.foxinmy.weixin4j.http.support.netty;
import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.FullHttpResponse; import io.netty.handler.codec.http.FullHttpResponse;
@ -27,7 +27,7 @@ public class Netty4HttpResponse extends AbstractHttpResponse {
private HttpVersion protocol; private HttpVersion protocol;
private HttpStatus status; private HttpStatus status;
private volatile HttpHeaders headers; private HttpHeaders headers;
public Netty4HttpResponse(ChannelHandlerContext context, public Netty4HttpResponse(ChannelHandlerContext context,
FullHttpResponse response, byte[] content) { FullHttpResponse response, byte[] content) {
@ -40,11 +40,10 @@ public class Netty4HttpResponse extends AbstractHttpResponse {
@Override @Override
public HttpHeaders getHeaders() { public HttpHeaders getHeaders() {
if (this.headers == null) { if (this.headers == null) {
HttpHeaders headers = new HttpHeaders(); this.headers = new HttpHeaders();
for (Map.Entry<String, String> entry : this.response.headers()) { for (Map.Entry<String, String> entry : this.response.headers()) {
headers.add(entry.getKey(), entry.getValue()); headers.add(entry.getKey(), entry.getValue());
} }
this.headers = headers;
} }
return this.headers; return this.headers;
} }

View File

@ -0,0 +1,144 @@
package com.foxinmy.weixin4j.http.support.okhttp;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.List;
import java.util.Map.Entry;
import okio.BufferedSink;
import com.foxinmy.weixin4j.http.AbstractHttpClient;
import com.foxinmy.weixin4j.http.HttpClientException;
import com.foxinmy.weixin4j.http.HttpHeaders;
import com.foxinmy.weixin4j.http.HttpMethod;
import com.foxinmy.weixin4j.http.HttpRequest;
import com.foxinmy.weixin4j.http.HttpResponse;
import com.foxinmy.weixin4j.http.entity.HttpEntity;
import com.foxinmy.weixin4j.util.StringUtil;
import com.squareup.okhttp.MediaType;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.Request;
import com.squareup.okhttp.RequestBody;
import com.squareup.okhttp.Response;
/**
* OkHttp2
*
* @className OkHttpClient2
* @author jinyu(foxinmy@gmail.com)
* @date 2016年7月25日
* @since JDK 1.6
*/
public class OkHttpClient2 extends AbstractHttpClient {
private final OkHttpClient okClient;
public OkHttpClient2(OkHttpClient okClient) {
this.okClient = okClient;
}
@Override
public HttpResponse execute(HttpRequest request) throws HttpClientException {
HttpResponse response = null;
try {
Request okRequest = createRequest(request);
Response okResponse = okClient.newCall(okRequest).execute();
response = new OkHttpResponse2(okResponse, okResponse.body()
.bytes());
handleResponse(response);
} catch (IOException e) {
throw new HttpClientException("I/O error on "
+ request.getMethod().name() + " request for \""
+ request.getURI().toString() + "\":" + e.getMessage(), e);
} finally {
if (response != null) {
response.close();
}
}
return response;
}
/**
* create OkRequest
*/
protected Request createRequest(HttpRequest request)
throws HttpClientException {
Request.Builder requestBuilder = createBuilder(request);
resolveHeaders(request.getHeaders(), requestBuilder);
resolveContent(request.getEntity(), request.getMethod(), requestBuilder);
return requestBuilder.build();
}
/**
* create Request.Builder
*
* @throws HttpClientException
*/
protected Request.Builder createBuilder(HttpRequest request)
throws HttpClientException {
Request.Builder requestBuilder = new Request.Builder();
try {
requestBuilder.url(request.getURI().toURL());
} catch (MalformedURLException e) {
throw new HttpClientException("format URI error", e);
}
return requestBuilder;
}
/**
* resolve Request.Headers
* */
protected void resolveHeaders(
com.foxinmy.weixin4j.http.HttpHeaders headers,
Request.Builder requestBuilder) {
if (headers == null) {
headers = new HttpHeaders();
}
// Add default accept headers
if (!headers.containsKey(HttpHeaders.ACCEPT)) {
headers.set(HttpHeaders.ACCEPT, "*/*");
}
// Add default user agent
if (!headers.containsKey(HttpHeaders.USER_AGENT)) {
headers.set(HttpHeaders.USER_AGENT, "square/okhttp2");
}
for (Entry<String, List<String>> header : headers.entrySet()) {
if (HttpHeaders.COOKIE.equalsIgnoreCase(header.getKey())) {
requestBuilder.header(header.getKey(),
StringUtil.join(header.getValue(), ';'));
} else {
for (String headerValue : header.getValue()) {
requestBuilder.header(header.getKey(),
headerValue != null ? headerValue : "");
}
}
}
}
/**
* resolve Request.Content
*/
protected void resolveContent(final HttpEntity entity, HttpMethod method,
Request.Builder requestBuilder) throws HttpClientException {
RequestBody body = null;
if (entity != null) {
body = new RequestBody() {
@Override
public long contentLength() throws IOException {
return entity.getContentLength();
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
entity.writeTo(sink.outputStream());
}
@Override
public MediaType contentType() {
return MediaType.parse(entity.getContentType().toString());
}
};
}
requestBuilder.method(method.name(), body);
}
}

View File

@ -0,0 +1,85 @@
package com.foxinmy.weixin4j.http.support.okhttp;
import java.net.CookieHandler;
import java.util.concurrent.TimeUnit;
import com.foxinmy.weixin4j.http.HttpClient;
import com.foxinmy.weixin4j.http.HttpParams;
import com.foxinmy.weixin4j.http.factory.HttpClientFactory;
import com.squareup.okhttp.Cache;
import com.squareup.okhttp.ConnectionPool;
import com.squareup.okhttp.Dispatcher;
import com.squareup.okhttp.Dns;
import com.squareup.okhttp.OkHttpClient;
/**
* 使用OkHttp2
*
* @className OkHttpClient2Factory
* @author jinyu(foxinmy@gmail.com)
* @date 2016年7月25日
* @since JDK 1.6
*/
public class OkHttpClient2Factory extends HttpClientFactory {
private final OkHttpClient okClient;
public OkHttpClient2Factory() {
this(new OkHttpClient());
}
public OkHttpClient2Factory(OkHttpClient okClient) {
this.okClient = okClient;
}
@Override
protected void resolveHttpParams0(HttpParams params) {
okClient.setConnectTimeout(params.getConnectTimeout(),
TimeUnit.MILLISECONDS);
okClient.setReadTimeout(params.getReadTimeout(), TimeUnit.MILLISECONDS);
if (params.getProxy() != null) {
okClient.setProxy(params.getProxy());
}
if (params.getHostnameVerifier() != null) {
okClient.setHostnameVerifier(params.getHostnameVerifier());
}
if (params.getSSLContext() != null) {
okClient.setSslSocketFactory(params.getSSLContext()
.getSocketFactory());
}
}
public OkHttpClient2Factory setWriteTimeout(int writeTimeout) {
okClient.setWriteTimeout(writeTimeout, TimeUnit.MILLISECONDS);
return this;
}
public OkHttpClient2Factory setCache(Cache cache) {
okClient.setCache(cache);
return this;
}
public OkHttpClient2Factory setConnectionPool(ConnectionPool connectionPool) {
okClient.setConnectionPool(connectionPool);
return this;
}
public OkHttpClient2Factory setCookieHandler(CookieHandler cookieHandler) {
okClient.setCookieHandler(cookieHandler);
return this;
}
public OkHttpClient2Factory setDispatcher(Dispatcher dispatcher) {
okClient.setDispatcher(dispatcher);
return this;
}
public OkHttpClient2Factory setDns(Dns dns) {
okClient.setDns(dns);
return this;
}
@Override
public HttpClient newInstance() {
return new OkHttpClient2(okClient);
}
}

View File

@ -0,0 +1,144 @@
package com.foxinmy.weixin4j.http.support.okhttp;
import java.io.IOException;
import java.net.MalformedURLException;
import java.util.List;
import java.util.Map.Entry;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import okio.BufferedSink;
import com.foxinmy.weixin4j.http.AbstractHttpClient;
import com.foxinmy.weixin4j.http.HttpClientException;
import com.foxinmy.weixin4j.http.HttpHeaders;
import com.foxinmy.weixin4j.http.HttpRequest;
import com.foxinmy.weixin4j.http.HttpResponse;
import com.foxinmy.weixin4j.http.entity.HttpEntity;
import com.foxinmy.weixin4j.util.StringUtil;
/**
* OkHttp3
*
* @className OkHttpClient3
* @author jinyu(foxinmy@gmail.com)
* @date 2016年7月25日
* @since JDK 1.6
*/
public class OkHttpClient3 extends AbstractHttpClient {
private final OkHttpClient okClient;
public OkHttpClient3(OkHttpClient okClient) {
this.okClient = okClient;
}
@Override
public HttpResponse execute(HttpRequest request) throws HttpClientException {
HttpResponse response = null;
try {
okhttp3.Request okRequest = createRequest(request);
okhttp3.Response okResponse = okClient.newCall(okRequest)
.execute();
response = new OkHttpResponse3(okResponse, okResponse.body()
.bytes());
handleResponse(response);
} catch (IOException e) {
throw new HttpClientException("I/O error on "
+ request.getMethod().name() + " request for \""
+ request.getURI().toString() + "\":" + e.getMessage(), e);
} finally {
if (response != null) {
response.close();
}
}
return response;
}
/**
* create OkRequest
*/
protected okhttp3.Request createRequest(HttpRequest request)
throws HttpClientException {
okhttp3.Request.Builder requestBuilder = createBuilder(request);
resolveHeaders(requestBuilder, request);
resolveContent(requestBuilder, request);
return requestBuilder.build();
}
/**
* create Request.Builder
*
* @throws HttpClientException
*/
protected okhttp3.Request.Builder createBuilder(HttpRequest request)
throws HttpClientException {
okhttp3.Request.Builder requestBuilder = new okhttp3.Request.Builder();
try {
requestBuilder.url(request.getURI().toURL());
} catch (MalformedURLException e) {
throw new HttpClientException("format URI error", e);
}
return requestBuilder;
}
/**
* resolve Request.Headers
* */
protected void resolveHeaders(okhttp3.Request.Builder builder,
HttpRequest request) {
com.foxinmy.weixin4j.http.HttpHeaders headers = request.getHeaders();
if (headers == null) {
headers = new HttpHeaders();
}
// Add default accept headers
if (!headers.containsKey(HttpHeaders.ACCEPT)) {
headers.set(HttpHeaders.ACCEPT, "*/*");
}
// Add default user agent
if (!headers.containsKey(HttpHeaders.USER_AGENT)) {
headers.set(HttpHeaders.USER_AGENT, "square/okhttp3");
}
for (Entry<String, List<String>> header : headers.entrySet()) {
if (HttpHeaders.COOKIE.equalsIgnoreCase(header.getKey())) {
builder.header(header.getKey(),
StringUtil.join(header.getValue(), ';'));
} else {
for (String headerValue : header.getValue()) {
builder.header(header.getKey(),
headerValue != null ? headerValue : "");
}
}
}
}
/**
* resolve Request.Content
*/
protected void resolveContent(okhttp3.Request.Builder builder,
HttpRequest request) throws HttpClientException {
final HttpEntity entity = request.getEntity();
okhttp3.RequestBody body = null;
if (entity != null) {
body = new RequestBody() {
@Override
public long contentLength() throws IOException {
return entity.getContentLength();
}
@Override
public void writeTo(BufferedSink sink) throws IOException {
entity.writeTo(sink.outputStream());
}
@Override
public MediaType contentType() {
return MediaType.parse(entity.getContentType().toString());
}
};
}
builder.method(request.getMethod().name(), body);
}
}

View File

@ -0,0 +1,108 @@
package com.foxinmy.weixin4j.http.support.okhttp;
import java.util.concurrent.TimeUnit;
import okhttp3.Cache;
import okhttp3.ConnectionPool;
import okhttp3.CookieJar;
import okhttp3.Dispatcher;
import okhttp3.Dns;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import com.foxinmy.weixin4j.http.HttpClient;
import com.foxinmy.weixin4j.http.HttpParams;
import com.foxinmy.weixin4j.http.factory.HttpClientFactory;
/**
* 使用OkHttp3
*
* @className OkHttpClient3Factory
* @author jinyu(foxinmy@gmail.com)
* @date 2016年7月25日
* @since JDK 1.6
*/
public class OkHttpClient3Factory extends HttpClientFactory {
private volatile OkHttpClient okClient;
private final OkHttpClient.Builder clientBuilder;
public OkHttpClient3Factory() {
this(new OkHttpClient.Builder());
}
public OkHttpClient3Factory(OkHttpClient.Builder clientBuilder) {
this.clientBuilder = clientBuilder;
}
/**
* resolve Request.Parameter
*
* */
@Override
protected void resolveHttpParams0(HttpParams params) {
clientBuilder.connectTimeout(params.getConnectTimeout(),
TimeUnit.MILLISECONDS);
clientBuilder.readTimeout(params.getReadTimeout(),
TimeUnit.MILLISECONDS);
if (params.getProxy() != null) {
clientBuilder.proxy(params.getProxy());
}
if (params.getHostnameVerifier() != null) {
clientBuilder.hostnameVerifier(params.getHostnameVerifier());
}
if (params.getSSLContext() != null) {
clientBuilder.sslSocketFactory(params.getSSLContext()
.getSocketFactory(),
HttpClientFactory.AllowX509TrustManager.GLOBAL);
}
}
public OkHttpClient3Factory setWriteTimeout(int writeTimeout) {
clientBuilder.writeTimeout(writeTimeout, TimeUnit.MILLISECONDS);
return this;
}
public OkHttpClient3Factory addInterceptor(Interceptor interceptor) {
clientBuilder.addInterceptor(interceptor);
return this;
}
public OkHttpClient3Factory retryOnConnectionFailure(
boolean retryOnConnectionFailure) {
clientBuilder.retryOnConnectionFailure(retryOnConnectionFailure);
return this;
}
public OkHttpClient3Factory setCookieJar(CookieJar cookieJar) {
clientBuilder.cookieJar(cookieJar);
return this;
}
public OkHttpClient3Factory setCache(Cache cache) {
clientBuilder.cache(cache);
return this;
}
public OkHttpClient3Factory setConnectionPool(ConnectionPool connectionPool) {
clientBuilder.connectionPool(connectionPool);
return this;
}
public OkHttpClient3Factory setDispatcher(Dispatcher dispatcher) {
clientBuilder.dispatcher(dispatcher);
return this;
}
public OkHttpClient3Factory setDns(Dns dns) {
clientBuilder.dns(dns);
return this;
}
@Override
public HttpClient newInstance() {
if (okClient == null) {
this.okClient = clientBuilder.build();
}
return new OkHttpClient3(okClient);
}
}

View File

@ -0,0 +1,38 @@
package com.foxinmy.weixin4j.http.support.okhttp;
import com.foxinmy.weixin4j.http.HttpClient;
import com.foxinmy.weixin4j.http.HttpParams;
import com.foxinmy.weixin4j.http.factory.HttpClientFactory;
/**
* 使用OkHttp
*
* @className OkHttpClientFactory
* @author jinyu(foxinmy@gmail.com)
* @date 2016年7月25日
* @since JDK 1.6
*/
public class OkHttpClientFactory extends HttpClientFactory {
private static HttpClientFactory okHttpClientFactory;
static {
try {
okHttpClientFactory = new OkHttpClient2Factory();
} catch (Throwable e1) {
try {
okHttpClientFactory = new OkHttpClient3Factory();
} catch (Throwable e2) {
throw e2;
}
}
}
@Override
protected void resolveHttpParams0(HttpParams params) {
okHttpClientFactory.resolveHttpParams(params);
}
@Override
public HttpClient newInstance() {
return okHttpClientFactory.newInstance();
}
}

View File

@ -0,0 +1,77 @@
package com.foxinmy.weixin4j.http.support.okhttp;
import com.foxinmy.weixin4j.http.AbstractHttpResponse;
import com.foxinmy.weixin4j.http.HttpHeaders;
import com.foxinmy.weixin4j.http.HttpStatus;
import com.foxinmy.weixin4j.http.HttpVersion;
import com.squareup.okhttp.Headers;
import com.squareup.okhttp.Protocol;
import com.squareup.okhttp.Response;
/**
* OkHttp Response:Requires OkHttp 2.x
*
* @className OkHttpResponse2
* @author jinyu(foxinmy@gmail.com)
* @date 2016年7月25日
* @since JDK 1.6
*/
public class OkHttpResponse2 extends AbstractHttpResponse {
private final Response response;
private HttpHeaders headers;
private HttpVersion protocol;
private HttpStatus status;
public OkHttpResponse2(Response response, byte[] content) {
super(content);
this.response = response;
}
@Override
public HttpHeaders getHeaders() {
if (this.headers == null) {
this.headers = new HttpHeaders();
Headers headers = this.response.headers();
for (int i = 0; i < headers.size(); i++) {
this.headers.add(headers.name(i), headers.value(i));
}
}
return this.headers;
}
@Override
public HttpVersion getProtocol() {
if (protocol == null) {
String protocol = this.response.protocol().toString().split("/")[0];
boolean keepAlive = KEEP_ALIVE.equalsIgnoreCase(this.response
.header("Connection"));
if (this.response.protocol() == Protocol.HTTP_1_0) {
return new HttpVersion(protocol, 1, 0, keepAlive);
} else if (this.response.protocol() == Protocol.HTTP_1_1) {
return new HttpVersion(protocol, 1, 1, keepAlive);
} else if (this.response.protocol() == Protocol.HTTP_2) {
return new HttpVersion(protocol, 2, 0, keepAlive);
} else if (this.response.protocol() == Protocol.SPDY_3) {
return new HttpVersion(protocol, 3, 0, keepAlive);
} else {
this.protocol = new HttpVersion(protocol, keepAlive);
}
}
return protocol;
}
@Override
public HttpStatus getStatus() {
if (status == null) {
status = new HttpStatus(this.response.code(),
this.response.message());
}
return status;
}
@Override
public void close() {
// nothing
}
}

View File

@ -0,0 +1,75 @@
package com.foxinmy.weixin4j.http.support.okhttp;
import okhttp3.Protocol;
import com.foxinmy.weixin4j.http.AbstractHttpResponse;
import com.foxinmy.weixin4j.http.HttpHeaders;
import com.foxinmy.weixin4j.http.HttpStatus;
import com.foxinmy.weixin4j.http.HttpVersion;
/**
* OkHttp Response:Requires OkHttp 3.x or higher
*
* @className OkHttpResponse3
* @author jinyu(foxinmy@gmail.com)
* @date 2016年7月25日
* @since JDK 1.6
*/
public class OkHttpResponse3 extends AbstractHttpResponse {
private final okhttp3.Response response;
private HttpHeaders headers;
private HttpVersion protocol;
private HttpStatus status;
public OkHttpResponse3(okhttp3.Response response, byte[] content) {
super(content);
this.response = response;
}
@Override
public HttpHeaders getHeaders() {
if (this.headers == null) {
this.headers = new HttpHeaders();
okhttp3.Headers headers = this.response.headers();
for (int i = 0; i < headers.size(); i++) {
this.headers.add(headers.name(i), headers.value(i));
}
}
return this.headers;
}
@Override
public HttpVersion getProtocol() {
if (protocol == null) {
String protocol = this.response.protocol().toString().split("/")[0];
boolean keepAlive = KEEP_ALIVE.equalsIgnoreCase(this.response
.header("Connection"));
if (this.response.protocol() == Protocol.HTTP_1_0) {
return new HttpVersion(protocol, 1, 0, keepAlive);
} else if (this.response.protocol() == Protocol.HTTP_1_1) {
return new HttpVersion(protocol, 1, 1, keepAlive);
} else if (this.response.protocol() == Protocol.HTTP_2) {
return new HttpVersion(protocol, 2, 0, keepAlive);
} else if (this.response.protocol() == Protocol.SPDY_3) {
return new HttpVersion(protocol, 3, 0, keepAlive);
} else {
this.protocol = new HttpVersion(protocol, keepAlive);
}
}
return protocol;
}
@Override
public HttpStatus getStatus() {
if (status == null) {
status = new HttpStatus(this.response.code(),
this.response.message());
}
return status;
}
@Override
public void close() {
response.close();
}
}

View File

@ -1,7 +1,12 @@
package com.foxinmy.weixin4j.http.weixin; package com.foxinmy.weixin4j.http.weixin;
import java.io.IOException; import java.io.IOException;
import java.util.Map; import java.io.InputStream;
import java.security.KeyStore;
import java.util.Arrays;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.HttpClient; import com.foxinmy.weixin4j.http.HttpClient;
@ -10,6 +15,7 @@ import com.foxinmy.weixin4j.http.HttpMethod;
import com.foxinmy.weixin4j.http.HttpParams; import com.foxinmy.weixin4j.http.HttpParams;
import com.foxinmy.weixin4j.http.HttpRequest; import com.foxinmy.weixin4j.http.HttpRequest;
import com.foxinmy.weixin4j.http.HttpResponse; import com.foxinmy.weixin4j.http.HttpResponse;
import com.foxinmy.weixin4j.http.URLParameter;
import com.foxinmy.weixin4j.http.apache.FormBodyPart; import com.foxinmy.weixin4j.http.apache.FormBodyPart;
import com.foxinmy.weixin4j.http.apache.HttpMultipartMode; import com.foxinmy.weixin4j.http.apache.HttpMultipartMode;
import com.foxinmy.weixin4j.http.apache.MultipartEntity; import com.foxinmy.weixin4j.http.apache.MultipartEntity;
@ -35,45 +41,31 @@ import com.foxinmy.weixin4j.model.Consts;
*/ */
public class WeixinRequestExecutor { public class WeixinRequestExecutor {
protected final InternalLogger logger = InternalLoggerFactory.getInstance(getClass()); protected final InternalLogger logger = InternalLoggerFactory
.getInstance(getClass());
private static final String SUCCESS_CODE = ",0,success,"; private static final String SUCCESS_CODE = ",0,success,";
protected final HttpClient httpClient; private final HttpClient httpClient;
protected final HttpParams httpParams;
public WeixinRequestExecutor() { public WeixinRequestExecutor() {
this(new HttpParams());
}
public WeixinRequestExecutor(HttpParams httpParams) {
this.httpClient = HttpClientFactory.getInstance(); this.httpClient = HttpClientFactory.getInstance();
this.httpParams = httpParams;
} }
public WeixinResponse get(String url) throws WeixinException { public WeixinRequestExecutor(HttpParams params) {
HttpRequest request = new HttpRequest(HttpMethod.GET, url); this.httpClient = HttpClientFactory.getInstance(params);
return doRequest(request);
}
public WeixinResponse get(String url, Map<String, String> parameters) throws WeixinException {
StringBuilder buf = new StringBuilder(url);
if (parameters != null && !parameters.isEmpty()) {
if (url.indexOf("?") < 0) {
buf.append("?");
} else {
buf.append("&");
}
buf.append(FormUrlEntity.formatParameters(parameters));
}
return doRequest(new HttpRequest(HttpMethod.GET, buf.toString()));
}
public WeixinResponse post(String url) throws WeixinException {
HttpRequest request = new HttpRequest(HttpMethod.POST, url);
return doRequest(request);
} }
/**
* Post方法执行微信请求
*
* @param url
* 请求URL
* @param body
* 参数内容
* @return 微信响应
* @throws WeixinException
*/
public WeixinResponse post(String url, String body) throws WeixinException { public WeixinResponse post(String url, String body) throws WeixinException {
HttpEntity entity = new StringEntity(body); HttpEntity entity = new StringEntity(body);
HttpRequest request = new HttpRequest(HttpMethod.POST, url); HttpRequest request = new HttpRequest(HttpMethod.POST, url);
@ -81,8 +73,20 @@ public class WeixinRequestExecutor {
return doRequest(request); return doRequest(request);
} }
public WeixinResponse post(String url, FormBodyPart... bodyParts) throws WeixinException { /**
MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE, null, Consts.UTF_8); * Post方法执行微信请求用于文件上传
*
* @param url
* 请求URL
* @param bodyParts
* 文件内容
* @return 微信响应
* @throws WeixinException
*/
public WeixinResponse post(String url, FormBodyPart... bodyParts)
throws WeixinException {
MultipartEntity entity = new MultipartEntity(
HttpMultipartMode.BROWSER_COMPATIBLE, null, Consts.UTF_8);
for (FormBodyPart bodyPart : bodyParts) { for (FormBodyPart bodyPart : bodyParts) {
entity.addPart(bodyPart); entity.addPart(bodyPart);
} }
@ -91,31 +95,74 @@ public class WeixinRequestExecutor {
return doRequest(request); return doRequest(request);
} }
protected WeixinResponse doRequest(HttpRequest request) throws WeixinException { /**
request.setParams(httpParams); * Get方法执行微信请求
*
* @param url
* 请求URLhttps://api.weixin.qq.com/cgi-bin/token
* @param parameters
* url上的参数:new URLParameter("appid",xxxxx)
* @return 微信响应
* @throws WeixinException
*/
public WeixinResponse get(String url, URLParameter... parameters)
throws WeixinException {
// always contain the question mark
StringBuilder buf = new StringBuilder(url).append("&");
if (parameters != null && parameters.length > 0) {
buf.append(FormUrlEntity.formatParameters(Arrays.asList(parameters)));
}
HttpRequest request = new HttpRequest(HttpMethod.GET, buf.toString());
return doRequest(request);
}
/**
* 执行微信请求
*
* @param request
* 微信请求
* @return 微信响应
* @throws WeixinException
*/
protected WeixinResponse doRequest(HttpRequest request)
throws WeixinException {
try { try {
logger.info("weixin request >> " + request.getMethod() + " " + request.getURI().toString()); logger.info("weixin request >> " + request.getMethod() + " "
+ request.getURI().toString());
HttpResponse httpResponse = httpClient.execute(request); HttpResponse httpResponse = httpClient.execute(request);
WeixinResponse response = new WeixinResponse(httpResponse); WeixinResponse response = new WeixinResponse(httpResponse);
logger.info("weixin response << " + httpResponse.getProtocol() + httpResponse.getStatus() + ":" logger.info("weixin response << " + httpResponse.getProtocol()
+ response.getAsString()); + httpResponse.getStatus() + ":" + response.getAsString());
handlResponse(response); handleResponse(response);
return response; return response;
} catch (HttpClientException e) { } catch (HttpClientException e) {
throw new WeixinException(e); throw new WeixinException(e);
} }
} }
protected void handlResponse(WeixinResponse response) throws WeixinException { /**
* handle the weixin response
*
* @param response
* 微信请求响应
* @throws WeixinException
*/
protected void handleResponse(WeixinResponse response)
throws WeixinException {
ApiResult result = response.getAsResult(); ApiResult result = response.getAsResult();
if (!SUCCESS_CODE.contains(String.format(",%s,", result.getReturnCode().toLowerCase()))) { if (!SUCCESS_CODE.contains(String.format(",%s,", result.getReturnCode()
throw new WeixinException(result.getReturnCode(), result.getReturnMsg()); .toLowerCase()))) {
throw new WeixinException(result.getReturnCode(),
result.getReturnMsg());
} }
if (XmlMessageConverter.GLOBAL.canConvert(XmlResult.class, response)) { if (XmlMessageConverter.GLOBAL.canConvert(XmlResult.class, response)) {
try { try {
XmlResult xmlResult = XmlMessageConverter.GLOBAL.convert(XmlResult.class, response); XmlResult xmlResult = XmlMessageConverter.GLOBAL.convert(
if (!SUCCESS_CODE.contains(String.format(",%s,", xmlResult.getResultCode().toLowerCase()))) { XmlResult.class, response);
throw new WeixinException(xmlResult.getErrCode(), xmlResult.getErrCodeDes()); if (!SUCCESS_CODE.contains(String.format(",%s,", xmlResult
.getResultCode().toLowerCase()))) {
throw new WeixinException(xmlResult.getErrCode(),
xmlResult.getErrCodeDes());
} }
} catch (IOException e) { } catch (IOException e) {
; ;
@ -127,7 +174,39 @@ public class WeixinRequestExecutor {
return httpClient; return httpClient;
} }
public HttpParams getExecuteParams() { /**
return httpParams; * 创建 SSL微信请求对象
*
* @param password
* 加载密钥
* @param inputStream
* 密钥内容
* @return 微信请求
* @throws WeixinException
*/
public WeixinRequestExecutor createSSLRequestExecutor(String password,
InputStream inputStream) throws WeixinException {
try {
KeyStore keyStore = KeyStore.getInstance(Consts.PKCS12);
keyStore.load(inputStream, password.toCharArray());
KeyManagerFactory kmf = KeyManagerFactory
.getInstance(Consts.SunX509);
kmf.init(keyStore, password.toCharArray());
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), null,
new java.security.SecureRandom());
return createSSLRequestExecutor(sslContext);
} catch (Exception e) {
throw new WeixinException("Key load error", e);
}
}
public WeixinRequestExecutor createSSLRequestExecutor(SSLContext sslContext) {
if (sslContext == null) {
throw new IllegalArgumentException("sslContext must not be empty");
}
HttpParams params = new HttpParams();
params.setSSLContext(sslContext);
return new WeixinRequestExecutor(params);
} }
} }

View File

@ -1,56 +0,0 @@
package com.foxinmy.weixin4j.http.weixin;
import java.io.InputStream;
import java.security.KeyStore;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.HttpRequest;
import com.foxinmy.weixin4j.model.Consts;
/**
* 微信ssl请求
*
* @className WeixinSSLRequestExecutor
* @author jinyu(foxinmy@gmail.com)
* @date 2015年8月17日
* @since JDK 1.6
* @see
*/
public class WeixinSSLRequestExecutor extends WeixinRequestExecutor {
private final SSLContext sslContext;
public WeixinSSLRequestExecutor(String password, InputStream inputStream)
throws WeixinException {
try {
KeyStore keyStore = KeyStore.getInstance(Consts.PKCS12);
keyStore.load(inputStream, password.toCharArray());
KeyManagerFactory kmf = KeyManagerFactory
.getInstance(Consts.SunX509);
kmf.init(keyStore, password.toCharArray());
sslContext = SSLContext.getInstance("TLS");
sslContext.init(kmf.getKeyManagers(), null,
new java.security.SecureRandom());
} catch (Exception e) {
throw new WeixinException("Key load error", e);
}
}
public WeixinSSLRequestExecutor(SSLContext sslContext) {
this.sslContext = sslContext;
}
public SSLContext getSSLContext() {
return sslContext;
}
@Override
protected WeixinResponse doRequest(HttpRequest request)
throws WeixinException {
httpParams.setSSLContext(sslContext);
return super.doRequest(request);
}
}

View File

@ -2,7 +2,6 @@ package com.foxinmy.weixin4j.setting;
import com.foxinmy.weixin4j.cache.CacheStorager; import com.foxinmy.weixin4j.cache.CacheStorager;
import com.foxinmy.weixin4j.cache.FileCacheStorager; import com.foxinmy.weixin4j.cache.FileCacheStorager;
import com.foxinmy.weixin4j.http.HttpParams;
import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.util.StringUtil; import com.foxinmy.weixin4j.util.StringUtil;
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil; import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
@ -21,10 +20,6 @@ public class Weixin4jSettings<T> {
* 账号信息 * 账号信息
*/ */
private final T account; private final T account;
/**
* Http参数
*/
private HttpParams httpParams;
/** /**
* 系统临时目录 * 系统临时目录
*/ */
@ -46,18 +41,10 @@ public class Weixin4jSettings<T> {
return account; return account;
} }
public HttpParams getHttpParams() {
return httpParams;
}
public String getTmpdir() { public String getTmpdir() {
return tmpdir; return tmpdir;
} }
public void setHttpParams(HttpParams httpParams) {
this.httpParams = httpParams;
}
public void setTmpdir(String tmpdir) { public void setTmpdir(String tmpdir) {
this.tmpdir = tmpdir; this.tmpdir = tmpdir;
} }
@ -103,8 +90,8 @@ public class Weixin4jSettings<T> {
@Override @Override
public String toString() { public String toString() {
return "Weixin4jSettings [account=" + account + ", httpParams=" return "Weixin4jSettings [account=" + account + ", tmpdir=" + tmpdir
+ httpParams + ", tmpdir=" + tmpdir + ", cacheStorager=" + ", cacheStorager=" + cacheStorager + ", certificateFile="
+ cacheStorager + ", certificateFile=" + certificateFile + "]"; + certificateFile + "]";
} }
} }

View File

@ -41,6 +41,27 @@ public class IOUtil {
out.flush(); out.flush();
} }
public static int copy(InputStream input, OutputStream output)
throws IOException {
long count = copyLarge(input, output);
if (count > Integer.MAX_VALUE) {
return -1;
}
return (int) count;
}
private static long copyLarge(InputStream input, OutputStream output)
throws IOException {
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
long count = 0;
int n = 0;
while (-1 != (n = input.read(buffer))) {
output.write(buffer, 0, n);
count += n;
}
return count;
}
public static byte[] toByteArray(InputStream input) throws IOException { public static byte[] toByteArray(InputStream input) throws IOException {
ByteArrayOutputStream output = new ByteArrayOutputStream(); ByteArrayOutputStream output = new ByteArrayOutputStream();
copyLarge(input, output, new byte[DEFAULT_BUFFER_SIZE]); copyLarge(input, output, new byte[DEFAULT_BUFFER_SIZE]);

View File

@ -1,72 +0,0 @@
package com.foxinmy.weixin4j.base.test;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Proxy.Type;
import com.foxinmy.weixin4j.http.HttpClient;
import com.foxinmy.weixin4j.http.HttpClientException;
import com.foxinmy.weixin4j.http.HttpMethod;
import com.foxinmy.weixin4j.http.HttpParams;
import com.foxinmy.weixin4j.http.HttpRequest;
import com.foxinmy.weixin4j.http.HttpResponse;
import com.foxinmy.weixin4j.http.factory.HttpClientFactory;
import com.foxinmy.weixin4j.http.factory.HttpComponent3Factory;
import com.foxinmy.weixin4j.http.factory.HttpComponent4Factory;
import com.foxinmy.weixin4j.http.factory.Netty4HttpClientFactory;
import com.foxinmy.weixin4j.http.factory.SimpleHttpClientFactory;
import com.foxinmy.weixin4j.util.IOUtil;
public class HttpClientTest {
static HttpRequest request = new HttpRequest(HttpMethod.GET,
"http://www.iteye.com/");
static {
HttpParams params = new HttpParams().setProxy(new Proxy(Type.HTTP,
new InetSocketAddress("117.136.234.9", 80)));
// request.setParams(params);
}
public static void test1() throws HttpClientException {
HttpClientFactory.setDefaultFactory(new SimpleHttpClientFactory());
HttpClient httpClient = HttpClientFactory.getInstance();
HttpResponse response = httpClient.execute(request);
print(response);
}
public static void test2() throws HttpClientException {
HttpClientFactory.setDefaultFactory(new HttpComponent3Factory());
HttpClient httpClient = HttpClientFactory.getInstance();
HttpResponse response = httpClient.execute(request);
print(response);
}
public static void test3() throws HttpClientException {
HttpClientFactory.setDefaultFactory(new HttpComponent4Factory());
HttpClient httpClient = HttpClientFactory.getInstance();
HttpResponse response = httpClient.execute(request);
print(response);
}
public static void test4() throws HttpClientException {
HttpClientFactory.setDefaultFactory(new Netty4HttpClientFactory());
HttpClient httpClient = HttpClientFactory.getInstance();
HttpResponse response = httpClient.execute(request);
print(response);
}
public static void print(HttpResponse response) throws HttpClientException {
try {
System.err.println(new String(
IOUtil.toByteArray(response.getBody())));
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws Exception {
test1();
}
}

View File

@ -34,7 +34,7 @@ import com.foxinmy.weixin4j.type.TradeType;
* @className PayTest * @className PayTest
* @author jinyu(foxinmy@gmail.com) * @author jinyu(foxinmy@gmail.com)
* @date 2016年1月30日 * @date 2016年1月30日
* @since JDK 1.6 * @since JDK 1.7
* @see * @see
*/ */
public class PayTest { public class PayTest {
@ -43,18 +43,18 @@ public class PayTest {
protected final static WeixinPayProxy PAY; protected final static WeixinPayProxy PAY;
static { static {
ACCOUNT = new WeixinPayAccount("appid", "paysignkey", "mchid"); ACCOUNT = new WeixinPayAccount("wx0d1d598c0c03c999", "GATFzDwbQdbbci3QEQxX2rUBvwTrsMiZ", "10020674");
SIGNATURE = new WeixinPaymentSignature(ACCOUNT.getPaySignKey()); SIGNATURE = new WeixinPaymentSignature(ACCOUNT.getPaySignKey());
PAY = new WeixinPayProxy(new Weixin4jSettings<WeixinPayAccount>(ACCOUNT)); PAY = new WeixinPayProxy(new Weixin4jSettings<WeixinPayAccount>(ACCOUNT));
} }
/** /**
* 商户证书文件 * 商户证书文件
*/ */
protected File caFile = new File("*.p12"); protected File caFile = new File("/Users/jy/workspace/feican/canyi-weixin-parent/canyi-weixin-service/src/main/resources/10020674.p12");
@Test @Test
public void queryOrder() throws WeixinException { public void queryOrder() throws WeixinException {
Order order = PAY.queryOrder(new IdQuery("201601131632321", Order order = PAY.queryOrder(new IdQuery("BY2016010800025",
IdType.TRADENO)); IdType.TRADENO));
System.err.println(order); System.err.println(order);
String sign = order.getSign(); String sign = order.getSign();
@ -70,6 +70,7 @@ public class PayTest {
RefundRecord record = PAY.queryRefund(new IdQuery("TT_1427183696238", RefundRecord record = PAY.queryRefund(new IdQuery("TT_1427183696238",
IdType.TRADENO)); IdType.TRADENO));
System.err.println(record); System.err.println(record);
// 这里的验证签名需要把details循环拼接
String sign = record.getSign(); String sign = record.getSign();
record.setSign(null); record.setSign(null);
String valiSign = SIGNATURE.sign(record); String valiSign = SIGNATURE.sign(record);
@ -138,7 +139,7 @@ public class PayTest {
} }
@Test @Test
public void reportInterface() throws WeixinException { public void interfaceReport() throws WeixinException {
String interfaceUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder"; String interfaceUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
int executeTime = 2500; int executeTime = 2500;
String outTradeNo = null; String outTradeNo = null;

View File

@ -0,0 +1,20 @@
package com.foxinmy.weixin4j.base.test.http;
import com.foxinmy.weixin4j.http.factory.HttpClientFactory;
import com.foxinmy.weixin4j.http.support.apache3.HttpComponent3Factory;
/**
* Apache3 for http test
*
* @className Apache3HttpClientTest
* @author jinyu(foxinmy@gmail.com)
* @date 2016年7月28日
* @since JDK 1.6
*/
public class Apache3HttpClientTest extends HttpClientTest {
@Override
protected HttpClientFactory createHttpFactory() {
return new HttpComponent3Factory();
}
}

View File

@ -0,0 +1,19 @@
package com.foxinmy.weixin4j.base.test.http;
import com.foxinmy.weixin4j.http.factory.HttpClientFactory;
import com.foxinmy.weixin4j.http.support.apache4.HttpComponent4_1Factory;
/**
* Apache4 for http test
* @className Apache4HttpClientTest
* @author jinyu(foxinmy@gmail.com)
* @date 2016年7月28日
* @since JDK 1.6
*/
public class Apache4_1HttpClientTest extends HttpClientTest {
@Override
protected HttpClientFactory createHttpFactory() {
return new HttpComponent4_1Factory();
}
}

View File

@ -0,0 +1,19 @@
package com.foxinmy.weixin4j.base.test.http;
import com.foxinmy.weixin4j.http.factory.HttpClientFactory;
import com.foxinmy.weixin4j.http.support.apache4.HttpComponent4_2Factory;
/**
* Apache4 for http test
* @className Apache4HttpClientTest
* @author jinyu(foxinmy@gmail.com)
* @date 2016年7月28日
* @since JDK 1.6
*/
public class Apache4_2HttpClientTest extends HttpClientTest {
@Override
protected HttpClientFactory createHttpFactory() {
return new HttpComponent4_2Factory();
}
}

View File

@ -0,0 +1,124 @@
package com.foxinmy.weixin4j.base.test.http;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Proxy.Type;
import org.junit.Assert;
import org.junit.Test;
import com.foxinmy.weixin4j.http.HttpClient;
import com.foxinmy.weixin4j.http.HttpClientException;
import com.foxinmy.weixin4j.http.HttpParams;
import com.foxinmy.weixin4j.http.HttpResponse;
import com.foxinmy.weixin4j.http.URLParameter;
import com.foxinmy.weixin4j.http.factory.HttpClientFactory;
import com.foxinmy.weixin4j.http.support.netty.Netty4HttpClientFactory;
/**
* HttpClient Test
*
* @className HttpClientTest
* @author jinyu(foxinmy@gmail.com)
* @date 2016年7月28日
* @since JDK 1.6
*/
public abstract class HttpClientTest {
private static final String GET_URL = "http://www.iteye.com/";
private static final String POST_URL = "http://223.72.192.176:8080/YuJia/LoginServlet";
private static final String HTTPS_URL = "https://www.baidu.com/";
protected static final Proxy PROXY = new Proxy(Type.HTTP,
new InetSocketAddress("219.141.225.108", 80));
protected abstract HttpClientFactory createHttpFactory();
protected HttpClient createHttpClient() {
return createHttpFactory().newInstance();
}
protected HttpClient createProxyHttpClient() {
HttpParams params = new HttpParams();
params.setProxy(PROXY);
return createHttpClient(params);
}
protected HttpClient createSSLHttpClient() throws HttpClientException {
HttpParams params = new HttpParams();
params.setHostnameVerifier(HttpClientFactory.AllowHostnameVerifier.GLOBAL);
params.setSSLContext(HttpClientFactory.allowSSLContext());
return createHttpClient(params);
}
protected HttpClient createProxyAndSSLHttpClient()
throws HttpClientException {
HttpParams params = new HttpParams();
params.setHostnameVerifier(HttpClientFactory.AllowHostnameVerifier.GLOBAL);
params.setSSLContext(HttpClientFactory.allowSSLContext());
params.setProxy(PROXY);
return createHttpClient(params);
}
protected HttpClient createHttpClient(HttpParams params) {
HttpClientFactory httpClientFactory = createHttpFactory();
httpClientFactory.resolveHttpParams(params);
return httpClientFactory.newInstance();
}
@Test
public void getDefaultHttpClientFactoryTest() {
HttpClientFactory httpClientFactory = HttpClientFactory
.getDefaultFactory();
Assert.assertTrue(httpClientFactory.getClass().isAssignableFrom(
Netty4HttpClientFactory.class));
}
@Test
public void getRequestTest() throws HttpClientException {
HttpClient httpClient = createHttpClient();
HttpResponse response = httpClient.get(GET_URL);
Assert.assertEquals(200, response.getStatus().getStatusCode());
}
@Test
public void postRequestTest() throws HttpClientException {
HttpClient httpClient = createHttpClient();
URLParameter parameter = new URLParameter("query", "java");
HttpResponse response = httpClient.post(POST_URL, parameter);
Assert.assertEquals(200, response.getStatus().getStatusCode());
}
@Test
public void httpsRequestTest() throws HttpClientException {
HttpClient httpClient = createHttpClient();
HttpResponse response = httpClient.get(HTTPS_URL);
Assert.assertEquals(200, response.getStatus().getStatusCode());
}
@Test
public void proxyRequestTest() throws HttpClientException {
HttpClient httpClient = createProxyHttpClient();
HttpResponse response = httpClient.get(GET_URL);
Assert.assertEquals(200, response.getStatus().getStatusCode());
response = httpClient.get(HTTPS_URL);
Assert.assertEquals(200, response.getStatus().getStatusCode());
}
@Test
public void sslRequestTest() throws HttpClientException {
HttpClient httpClient = createSSLHttpClient();
HttpResponse response = httpClient.get(GET_URL);
Assert.assertEquals(200, response.getStatus().getStatusCode());
response = httpClient.get(HTTPS_URL);
Assert.assertEquals(200, response.getStatus().getStatusCode());
}
@Test
public void proxyAndSSLRequestTest() throws HttpClientException {
HttpClient httpClient = createProxyAndSSLHttpClient();
HttpResponse response = httpClient.get(GET_URL);
Assert.assertEquals(200, response.getStatus().getStatusCode());
response = httpClient.get(HTTPS_URL);
Assert.assertEquals(200, response.getStatus().getStatusCode());
}
}

View File

@ -0,0 +1,19 @@
package com.foxinmy.weixin4j.base.test.http;
import com.foxinmy.weixin4j.http.factory.HttpClientFactory;
import com.foxinmy.weixin4j.http.support.netty.Netty4HttpClientFactory;
/**
* Netty for http test
* @className NettyHttpClientTest
* @author jinyu(foxinmy@gmail.com)
* @date 2016年7月28日
* @since JDK 1.6
*/
public class NettyHttpClientTest extends HttpClientTest {
@Override
protected HttpClientFactory createHttpFactory() {
return new Netty4HttpClientFactory();
}
}

View File

@ -0,0 +1,19 @@
package com.foxinmy.weixin4j.base.test.http;
import com.foxinmy.weixin4j.http.factory.HttpClientFactory;
import com.foxinmy.weixin4j.http.support.okhttp.OkHttpClient2Factory;
/**
* OkHttp for test
*
* @className OkHttpClinetTest
* @author jinyu(foxinmy@gmail.com)
* @date 2016年7月28日
* @since JDK 1.6
*/
public class OkHttp2ClinetTest extends HttpClientTest {
@Override
protected HttpClientFactory createHttpFactory() {
return new OkHttpClient2Factory();
}
}

View File

@ -0,0 +1,19 @@
package com.foxinmy.weixin4j.base.test.http;
import com.foxinmy.weixin4j.http.factory.HttpClientFactory;
import com.foxinmy.weixin4j.http.support.okhttp.OkHttpClient3Factory;
/**
* OkHttp for test
*
* @className OkHttpClinetTest
* @author jinyu(foxinmy@gmail.com)
* @date 2016年7月28日
* @since JDK 1.6
*/
public class OkHttp3ClinetTest extends HttpClientTest {
@Override
protected HttpClientFactory createHttpFactory() {
return new OkHttpClient3Factory();
}
}

View File

@ -0,0 +1,19 @@
package com.foxinmy.weixin4j.base.test.http;
import com.foxinmy.weixin4j.http.factory.HttpClientFactory;
import com.foxinmy.weixin4j.http.factory.SimpleHttpClientFactory;
/**
* SimpleClient for test
* @className SimpleHttpTest
* @author jinyu(foxinmy@gmail.com)
* @date 2016年7月28日
* @since JDK 1.6
*/
public class SimpleHttpTest extends HttpClientTest {
@Override
protected HttpClientFactory createHttpFactory() {
return new SimpleHttpClientFactory();
}
}

View File

@ -37,10 +37,6 @@
</constructor-arg> </constructor-arg>
</bean> </bean>
</property --> </property -->
<!-- http参数:http请求时的参数,比如代理、超时等配置信息,暂时还未实现 -->
<property name="httpParams">
<bean class="com.foxinmy.weixin4j.http.HttpParams"/>
</property>
<!-- 临时目录:weixin4j调用某些接口时需要用到的临时目录,不声明则获取顺序为:weixin4j.properties#weixin4j.tmpdir->`java.io.tmp` --> <!-- 临时目录:weixin4j调用某些接口时需要用到的临时目录,不声明则获取顺序为:weixin4j.properties#weixin4j.tmpdir->`java.io.tmp` -->
<property name="tmpdir" value="/tmp/weixin4j" /> <property name="tmpdir" value="/tmp/weixin4j" />
</bean> </bean>
@ -62,10 +58,6 @@
</constructor-arg> </constructor-arg>
<!-- ca证书:调用某些支付接口(如退款、红包)需要用到的证书文件,不声明则获取顺序为:weixin4j.properties#weixin4j.certificate.file->`classpath:ca.p12` --> <!-- ca证书:调用某些支付接口(如退款、红包)需要用到的证书文件,不声明则获取顺序为:weixin4j.properties#weixin4j.certificate.file->`classpath:ca.p12` -->
<property name="certificateFile" value="/path/to/certificate/file" /> <property name="certificateFile" value="/path/to/certificate/file" />
<!-- http参数:http请求时的参数,比如代理、超时等配置信息,暂时还未实现 -->
<property name="httpParams">
<bean class="com.foxinmy.weixin4j.http.HttpParams"/>
</property>
<!-- 临时目录:weixin4j调用某些接口时需要用到的临时目录,不声明则获取顺序为:weixin4j.properties#weixin4j.tmpdir->`java.io.tmp` --> <!-- 临时目录:weixin4j调用某些接口时需要用到的临时目录,不声明则获取顺序为:weixin4j.properties#weixin4j.tmpdir->`java.io.tmp` -->
<property name="tmpdir" value="/tmp/weixin4j" /> <property name="tmpdir" value="/tmp/weixin4j" />
</bean> </bean>

View File

@ -234,7 +234,6 @@ public class MediaApi extends MpApi {
request = new HttpRequest(HttpMethod.GET, request = new HttpRequest(HttpMethod.GET,
String.format(meida_download_uri, token.getAccessToken(), mediaId)); String.format(meida_download_uri, token.getAccessToken(), mediaId));
} }
request.setParams(weixinExecutor.getExecuteParams());
logger.info("weixin request >> " + request.getMethod() + " " + request.getURI().toString()); logger.info("weixin request >> " + request.getMethod() + " " + request.getURI().toString());
HttpResponse response = weixinExecutor.getExecuteClient().execute(request); HttpResponse response = weixinExecutor.getExecuteClient().execute(request);
byte[] content = IOUtil.toByteArray(response.getBody()); byte[] content = IOUtil.toByteArray(response.getBody());

View File

@ -26,10 +26,9 @@ import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference; import com.alibaba.fastjson.TypeReference;
import com.alibaba.fastjson.parser.Feature; import com.alibaba.fastjson.parser.Feature;
import com.foxinmy.weixin4j.exception.WeixinException; import com.foxinmy.weixin4j.exception.WeixinException;
import com.foxinmy.weixin4j.http.entity.FormUrlEntity;
import com.foxinmy.weixin4j.http.message.ApiResult; import com.foxinmy.weixin4j.http.message.ApiResult;
import com.foxinmy.weixin4j.http.weixin.WeixinRequestExecutor;
import com.foxinmy.weixin4j.http.weixin.WeixinResponse; import com.foxinmy.weixin4j.http.weixin.WeixinResponse;
import com.foxinmy.weixin4j.http.weixin.WeixinSSLRequestExecutor;
import com.foxinmy.weixin4j.model.Consts; import com.foxinmy.weixin4j.model.Consts;
import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.mp.oldpayment.OrderV2; import com.foxinmy.weixin4j.mp.oldpayment.OrderV2;
@ -312,10 +311,9 @@ public class PayOldApi extends MpApi {
ctx = SSLContext.getInstance(Consts.TLS); ctx = SSLContext.getInstance(Consts.TLS);
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(),
new SecureRandom()); new SecureRandom());
response = weixinExecutor.createSSLRequestExecutor(ctx).get(
WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor( String.format("%s?%s", refund_uri,
ctx); FormUrlEntity.formatParameters(map)));
response = weixinExecutor.get(refund_uri, map);
} catch (WeixinException e) { } catch (WeixinException e) {
throw e; throw e;
} catch (Exception e) { } catch (Exception e) {
@ -459,7 +457,8 @@ public class PayOldApi extends MpApi {
map.put("key", weixinAccount.getPartnerKey()); map.put("key", weixinAccount.getPartnerKey());
String sign = DigestUtil.MD5(MapUtil.toJoinString(map, false, false)); String sign = DigestUtil.MD5(MapUtil.toJoinString(map, false, false));
map.put("sign", sign.toLowerCase()); map.put("sign", sign.toLowerCase());
WeixinResponse response = weixinExecutor.get(downloadbill_uri, map); WeixinResponse response = weixinExecutor.get(String.format("%s?%s",
downloadbill_uri, FormUrlEntity.formatParameters(map)));
BufferedReader reader = null; BufferedReader reader = null;
BufferedWriter writer = null; BufferedWriter writer = null;
try { try {
@ -510,7 +509,8 @@ public class PayOldApi extends MpApi {
map.put(idQuery.getType().getName(), idQuery.getId()); map.put(idQuery.getType().getName(), idQuery.getId());
String sign = weixinMD5Signature.sign(map); String sign = weixinMD5Signature.sign(map);
map.put("sign", sign.toLowerCase()); map.put("sign", sign.toLowerCase());
WeixinResponse response = weixinExecutor.get(refundquery_uri, map); WeixinResponse response = weixinExecutor.get(String.format(
refundquery_uri, FormUrlEntity.formatParameters(map)));
return ListsuffixResultDeserializer.deserialize(response.getAsString(), return ListsuffixResultDeserializer.deserialize(response.getAsString(),
RefundRecordV2.class); RefundRecordV2.class);
} }

View File

@ -1,6 +1,5 @@
package com.foxinmy.weixin4j.mp.model; package com.foxinmy.weixin4j.mp.model;
import com.alibaba.fastjson.annotation.JSONCreator;
import com.alibaba.fastjson.annotation.JSONField; import com.alibaba.fastjson.annotation.JSONField;
import com.foxinmy.weixin4j.model.Token; import com.foxinmy.weixin4j.model.Token;

View File

@ -93,13 +93,13 @@ public class NotifyTest extends TokenTest {
@Test @Test
public void send2() throws WeixinException, IOException { public void send2() throws WeixinException, IOException {
File file = new File("/tmp/test.jpg"); File file = new File("/Users/jy/Downloads/weixin4j.png");
MediaUploadResult mediaResult = mediaApi.uploadMedia(false, MediaUploadResult mediaResult = mediaApi.uploadMedia(false,
new FileInputStream(file), file.getName()); new FileInputStream(file), file.getName());
NotifyMessage imageNotify = new NotifyMessage( NotifyMessage imageNotify = new NotifyMessage(
"owGBft_vbBbOaQOmpEUE4xDLeRSU", new Image( "owGBft_vbBbOaQOmpEUE4xDLeRSU", new Image(
mediaResult.getMediaId())); mediaResult.getMediaId()));
ApiResult result = notifyApi.sendNotify(imageNotify); ApiResult result = notifyApi.sendNotify(imageNotify);
Assert.assertEquals(0, result.getReturnCode()); Assert.assertEquals("0", result.getReturnCode());
} }
} }

View File

@ -199,7 +199,6 @@ public class MediaApi extends QyApi {
request = new HttpRequest(HttpMethod.GET, request = new HttpRequest(HttpMethod.GET,
String.format(media_download_uri, token.getAccessToken(), mediaId)); String.format(media_download_uri, token.getAccessToken(), mediaId));
} }
request.setParams(weixinExecutor.getExecuteParams());
logger.info("weixin request >> " + request.getMethod() + " " + request.getURI().toString()); logger.info("weixin request >> " + request.getMethod() + " " + request.getURI().toString());
HttpResponse response = weixinExecutor.getExecuteClient().execute(request); HttpResponse response = weixinExecutor.getExecuteClient().execute(request);
byte[] content = IOUtil.toByteArray(response.getBody()); byte[] content = IOUtil.toByteArray(response.getBody());

View File

@ -122,7 +122,7 @@ public class PartyApi extends QyApi {
public ApiResult deleteParty(int partId) throws WeixinException { public ApiResult deleteParty(int partId) throws WeixinException {
String department_delete_uri = getRequestUri("department_delete_uri"); String department_delete_uri = getRequestUri("department_delete_uri");
Token token = tokenManager.getCache(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post(String.format( WeixinResponse response = weixinExecutor.get(String.format(
department_delete_uri, token.getAccessToken(), partId)); department_delete_uri, token.getAccessToken(), partId));
return response.getAsResult(); return response.getAsResult();
} }

View File

@ -339,8 +339,9 @@ public class UserApi extends QyApi {
obj.put("useridlist", userIds); obj.put("useridlist", userIds);
String user_delete_uri = getRequestUri("user_batchdelete_uri"); String user_delete_uri = getRequestUri("user_batchdelete_uri");
Token token = tokenManager.getCache(); Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post(String.format( WeixinResponse response = weixinExecutor.post(
user_delete_uri, token.getAccessToken(), obj.toJSONString())); String.format(user_delete_uri, token.getAccessToken()),
obj.toJSONString());
return response.getAsResult(); return response.getAsResult();
} }
@ -418,9 +419,9 @@ public class UserApi extends QyApi {
obj.put("agentid", agentid); obj.put("agentid", agentid);
} }
String userid2openid_uri = getRequestUri("userid2openid_uri"); String userid2openid_uri = getRequestUri("userid2openid_uri");
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor
String.format(userid2openid_uri, tokenManager.getAccessToken()), .post(String.format(userid2openid_uri,
obj.toJSONString()); tokenManager.getAccessToken()), obj.toJSONString());
obj = response.getAsJson(); obj = response.getAsJson();
return new String[] { obj.getString("openid"), obj.getString("appid") }; return new String[] { obj.getString("openid"), obj.getString("appid") };
} }
@ -439,9 +440,10 @@ public class UserApi extends QyApi {
*/ */
public String openid2userid(String openid) throws WeixinException { public String openid2userid(String openid) throws WeixinException {
String openid2userid_uri = getRequestUri("openid2userid_uri"); String openid2userid_uri = getRequestUri("openid2userid_uri");
WeixinResponse response = weixinExecutor.post( WeixinResponse response = weixinExecutor
String.format(openid2userid_uri, tokenManager.getAccessToken()), .post(String.format(openid2userid_uri,
String.format("{\"openid\": \"%s\"}", openid)); tokenManager.getAccessToken()),
String.format("{\"openid\": \"%s\"}", openid));
return response.getAsJson().getString("userid"); return response.getAsJson().getString("userid");
} }
} }