重新整理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

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

View File

@ -39,6 +39,18 @@
<version>4.0.30.Final</version>
<optional>true</optional>
</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>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>

View File

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

View File

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

View File

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

View File

@ -24,12 +24,14 @@ public final class ContentType implements Serializable {
private final Charset charset;
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 MULTIPART_FORM_DATA;
public static final ContentType DEFAULT_BINARY;
public static final ContentType DEFAULT_TEXT;
static {
APPLICATION_JSON = new ContentType(MimeType.APPLICATION_JSON);
APPLICATION_FORM_URLENCODED = new ContentType(MimeType.APPLICATION_FORM_URLENCODED);
MULTIPART_FORM_DATA = new ContentType(MimeType.MULTIPART_FORM_DATA);
DEFAULT_BINARY = new ContentType(MimeType.APPLICATION_OCTET_STREAM);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,11 +5,18 @@ import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.X509TrustManager;
import com.foxinmy.weixin4j.http.HttpClient;
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
@ -29,7 +36,7 @@ public abstract class HttpClientFactory {
/**
* NettyHttpClient -> ApacheHttpClient(HttpComponent3&4) ->
* SimpleHttpClient(HttpURLConnection)
* OkHttpClient(2&3) -> SimpleHttpClient(HttpURLConnection)
*
* @return
*/
@ -44,7 +51,11 @@ public abstract class HttpClientFactory {
try {
f = new HttpComponent3Factory();
} 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) {
if (defaultFactory == null) {
throw new NullPointerException("defaultFactory");
throw new IllegalArgumentException(
"'defaultFactory' must not be empty");
}
HttpClientFactory.defaultFactory = defaultFactory;
}
@ -81,6 +93,40 @@ public abstract class HttpClientFactory {
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实例
*
@ -92,7 +138,7 @@ public abstract class HttpClientFactory {
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null,
new X509TrustManager[] { createX509TrustManager() },
new X509TrustManager[] { AllowX509TrustManager.GLOBAL },
new java.security.SecureRandom());
return sslContext;
} catch (NoSuchAlgorithmException e) {
@ -104,24 +150,39 @@ public abstract class HttpClientFactory {
}
}
protected static X509TrustManager createX509TrustManager() {
return new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return null;
}
public static class AllowX509TrustManager implements X509TrustManager {
public static final X509TrustManager GLOBAL = new AllowX509TrustManager();
@Override
public void checkServerTrusted(
X509Certificate[] paramArrayOfX509Certificate,
String paramString) throws CertificateException {
}
private AllowX509TrustManager() {
}
@Override
public void checkClientTrusted(
X509Certificate[] paramArrayOfX509Certificate,
String paramString) throws CertificateException {
}
};
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
@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;
import com.foxinmy.weixin4j.http.HttpClient;
import com.foxinmy.weixin4j.http.HttpParams;
import com.foxinmy.weixin4j.http.SimpleHttpClient;
/**
@ -14,8 +15,19 @@ import com.foxinmy.weixin4j.http.SimpleHttpClient;
*/
public class SimpleHttpClientFactory extends HttpClientFactory {
private volatile SimpleHttpClient httpClient;
private HttpParams params;
@Override
protected void resolveHttpParams0(HttpParams params) {
this.params = params;
}
@Override
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;
public JsonMessageConverter() {
super(MimeType.APPLICATION_JSON, new MimeType("application", "*+json"));
super(MimeType.APPLICATION_JSON, MimeType.TEXT_JSON, new MimeType(
"application", "*+json"));
}
@Override
public boolean canConvert(Class<?> clazz, HttpResponse response) {
if (!super.canConvert(clazz, response)) {
String disposition = response.getHeaders().getFirst(HttpHeaders.CONTENT_DISPOSITION);
String fileName = RegexUtil.regexFileNameFromContentDispositionHeader(disposition);
return (fileName != null && FileUtil.getFileExtension(fileName).equalsIgnoreCase(JSO));
String disposition = response.getHeaders().getFirst(
HttpHeaders.CONTENT_DISPOSITION);
String fileName = RegexUtil
.regexFileNameFromContentDispositionHeader(disposition);
return (fileName != null && FileUtil.getFileExtension(fileName)
.equalsIgnoreCase(JSO));
}
return true;
}
@ -48,8 +52,10 @@ public class JsonMessageConverter extends AbstractMessageConverter {
}
@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);
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.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.Socket;
import java.net.UnknownHostException;
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.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.ControllerThreadSocketFactory;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
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.HttpParams;
import com.foxinmy.weixin4j.http.HttpRequest;
import com.foxinmy.weixin4j.http.HttpResponse;
import com.foxinmy.weixin4j.http.apache.MultipartEntity;
@ -59,11 +55,47 @@ public class HttpComponent3 extends AbstractHttpClient {
this.httpClient = httpClient;
}
private org.apache.commons.httpclient.HttpMethod createHttpMethod(
HttpMethod method, java.net.URI url) throws HttpClientException {
@Override
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;
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) {
httpMethod = new GetMethod();
} else if (method == HttpMethod.HEAD) {
@ -85,121 +117,79 @@ public class HttpComponent3 extends AbstractHttpClient {
httpMethod.setURI(uri);
} catch (IOException e) {
throw new HttpClientException("I/O error on " + method.name()
+ " setURI for \"" + url.toString() + "\":"
+ " setURI for \"" + request.toString() + "\":"
+ e.getMessage(), e);
}
return httpMethod;
}
@Override
public HttpResponse execute(HttpRequest request) throws HttpClientException {
HttpResponse response = null;
try {
org.apache.commons.httpclient.HttpMethod httpMethod = createHttpMethod(
request.getMethod(), request.getURI());
boolean useSSL = "https".equals(request.getURI().getScheme());
SSLContext sslContext = null;
HttpParams params = request.getParams();
if (params != null) {
Proxy proxy = params.getProxy();
if (proxy != null) {
InetSocketAddress socketAddress = (InetSocketAddress) proxy
.address();
httpClient.getHostConfiguration().setProxy(
socketAddress.getHostName(),
socketAddress.getPort());
useSSL = false;
}
sslContext = params.getSSLContext();
httpClient.getHttpConnectionManager().getParams()
.setConnectionTimeout(params.getConnectTimeout());
httpClient.getHttpConnectionManager().getParams()
.setSendBufferSize(params.getChunkSize());
httpMethod.getParams().setSoTimeout(params.getSocketTimeout());
httpMethod.getParams().setHttpElementCharset(
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())) {
/**
* Resolve Headers
*/
protected void resolveHeaders(HttpRequest request,
org.apache.commons.httpclient.HttpMethod httpMethod) {
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(),
StringUtil.join(header.getValue(), ';'));
} else {
for (String headerValue : header.getValue()) {
httpMethod.setRequestHeader(header.getKey(),
StringUtil.join(header.getValue(), ';'));
} else {
for (String headerValue : header.getValue()) {
httpMethod.setRequestHeader(header.getKey(),
headerValue != null ? headerValue : "");
}
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 {
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;
@ -54,9 +54,9 @@ public class HttpComponent3Response extends AbstractHttpResponse {
}
Header connection = httpMethod.getResponseHeader("Connection");
if (protocol == null) {
protocol = new HttpVersion("HTTP", version.getMinor(),
version.getMajor(), connection != null
&& "keep-alive".equalsIgnoreCase(connection
protocol = new HttpVersion("HTTP", version.getMajor(),
version.getMinor(), connection != null
&& KEEP_ALIVE.equalsIgnoreCase(connection
.getValue()));
}
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.IOException;
import java.net.URI;
import java.security.cert.X509Certificate;
import java.util.List;
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.HttpHeaders;
import com.foxinmy.weixin4j.http.HttpMethod;
import com.foxinmy.weixin4j.http.HttpRequest;
import com.foxinmy.weixin4j.http.apache.MultipartEntity;
import com.foxinmy.weixin4j.http.entity.HttpEntity;
import com.foxinmy.weixin4j.util.StringUtil;
@ -43,8 +45,25 @@ import com.foxinmy.weixin4j.util.StringUtil;
* @see
*/
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) {
return new HttpGet(uri);
} 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) {
headers = new HttpHeaders();
}
@ -77,21 +100,23 @@ public abstract class HttpComponent4 extends AbstractHttpClient {
if (!headers.containsKey(HttpHeaders.USER_AGENT)) {
headers.set(HttpHeaders.USER_AGENT, "apache/httpclient4");
}
for (Entry<String, List<String>> header : headers
.entrySet()) {
for (Entry<String, List<String>> header : headers.entrySet()) {
if (HttpHeaders.COOKIE.equalsIgnoreCase(header.getKey())) {
uriRequest.setHeader(header.getKey(),
httpRequest.setHeader(header.getKey(),
StringUtil.join(header.getValue(), ';'));
} else {
for (String headerValue : header.getValue()) {
uriRequest.setHeader(header.getKey(),
httpRequest.setHeader(header.getKey(),
headerValue != null ? headerValue : "");
}
}
}
}
protected void addEntity(HttpEntity entity, HttpRequestBase uriRequest)
/**
* Resolve Content
*/
protected void resolveContent(HttpEntity entity, HttpRequestBase httpRequest)
throws IOException {
if (entity != null) {
AbstractHttpEntity httpEntity = null;
@ -107,7 +132,8 @@ public abstract class HttpComponent4 extends AbstractHttpClient {
entity.getContentLength());
}
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;
@ -52,8 +52,8 @@ public class HttpComponent4_1Response extends AbstractHttpResponse {
Header connection = httpResponse.getFirstHeader("Connection");
protocol = new HttpVersion(version.getProtocol(),
version.getMajor(), version.getMinor(), connection != null
&& connection.getValue().equalsIgnoreCase(
"keep-alive"));
&& KEEP_ALIVE.equalsIgnoreCase(connection
.getValue()));
}
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;
@ -55,8 +55,8 @@ public class HttpComponent4_2Response extends AbstractHttpResponse {
Header connection = httpResponse.getFirstHeader("Connection");
protocol = new HttpVersion(version.getProtocol(),
version.getMajor(), version.getMinor(), connection != null
&& connection.getValue().equalsIgnoreCase(
"keep-alive"));
&& KEEP_ALIVE.equalsIgnoreCase(connection
.getValue()));
}
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.buffer.ByteBuf;
@ -8,7 +8,6 @@ import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelOption;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.DefaultFullHttpRequest;
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.HttpVersion;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.timeout.ReadTimeoutHandler;
import java.io.IOException;
import java.net.InetAddress;
@ -25,7 +23,6 @@ import java.net.URI;
import java.util.List;
import java.util.Map.Entry;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import javax.net.ssl.SSLContext;
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.HttpResponse;
import com.foxinmy.weixin4j.http.entity.HttpEntity;
import com.foxinmy.weixin4j.http.factory.HttpClientFactory;
import com.foxinmy.weixin4j.model.Consts;
import com.foxinmy.weixin4j.util.SettableFuture;
import com.foxinmy.weixin4j.util.StringUtil;
@ -53,25 +51,19 @@ import com.foxinmy.weixin4j.util.StringUtil;
public class Netty4HttpClient extends AbstractHttpClient {
private final Bootstrap bootstrap;
private final HttpParams params;
public Netty4HttpClient(Bootstrap bootstrap) {
public Netty4HttpClient(Bootstrap bootstrap, HttpParams params) {
this.bootstrap = bootstrap;
this.params = params;
}
@Override
public HttpResponse execute(HttpRequest request) throws HttpClientException {
public HttpResponse execute(final HttpRequest request)
throws HttpClientException {
HttpResponse response = null;
try {
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>();
ChannelFutureListener listener = new ChannelFutureListener() {
@Override
@ -79,9 +71,8 @@ public class Netty4HttpClient extends AbstractHttpClient {
throws Exception {
if (channelFuture.isSuccess()) {
Channel channel = channelFuture.channel();
// ssl
SSLContext sslContext = null;
if (useSSL) {
if ("https".equals(uri.getScheme())) {
SSLContext sslContext;
if (params != null
&& params.getSSLContext() != null) {
sslContext = params.getSSLContext();
@ -93,25 +84,20 @@ public class Netty4HttpClient extends AbstractHttpClient {
sslEngine.setUseClientMode(true);
channel.pipeline().addFirst(
new SslHandler(sslEngine));
if (params != null && params.getReadTimeout() > 0) {
channel.pipeline().addFirst(
new ReadTimeoutHandler(params
.getReadTimeout(),
TimeUnit.MILLISECONDS));
}
}
channel.pipeline().addLast(new RequestHandler(future));
DefaultHttpRequest uriRequest = createRequest(request);
channel.writeAndFlush(uriRequest);
} else {
future.setException(channelFuture.cause());
}
}
};
InetSocketAddress address = useProxy ? (InetSocketAddress) params
InetSocketAddress address = params != null
&& params.getProxy() != null ? (InetSocketAddress) params
.getProxy().address() : new InetSocketAddress(
InetAddress.getByName(uri.getHost()), getPort(uri));
bootstrap.connect(address).syncUninterruptibly()
.addListener(listener);
bootstrap.connect(address).addListener(listener);
response = future.get();
handleResponse(response);
} 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.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.HttpResponseDecoder;
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.HttpParams;
import com.foxinmy.weixin4j.http.factory.HttpClientFactory;
/**
* 使用Netty
* 使用Netty4
*
* @className Netty4HttpClientFactory
* @author jinyu(foxinmy@gmail.com)
* @date 2015年8月30日
* @since JDK 1.6
* @see
*/
public class Netty4HttpClientFactory extends HttpClientFactory {
/**
* worker线程数,默认设置为cpu的核数 * 4
*/
private final int workerThreads;
private volatile Bootstrap bootstrap;
private EventLoopGroup eventLoopGroup;
private Map<ChannelOption<?>, ?> options;
private HttpParams params;
public Netty4HttpClientFactory() {
this(Runtime.getRuntime().availableProcessors() * 4);
this(new NioEventLoopGroup(
Runtime.getRuntime().availableProcessors() * 4));
}
public Netty4HttpClientFactory(int workerThreads) {
this.workerThreads = workerThreads;
public Netty4HttpClientFactory(EventLoopGroup eventLoopGroup) {
this.eventLoopGroup = eventLoopGroup;
}
private volatile Bootstrap bootstrap;
@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) {
bootstrap = new Bootstrap();
bootstrap.option(ChannelOption.SO_KEEPALIVE, true).option(
ChannelOption.TCP_NODELAY, true);
EventLoopGroup workerGroup = new NioEventLoopGroup(workerThreads);
bootstrap.group(workerGroup).channel(NioSocketChannel.class)
bootstrap.group(eventLoopGroup).channel(NioSocketChannel.class)
.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel channel)
throws Exception {
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 HttpContentDecompressor());
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.handler.codec.http.FullHttpResponse;
@ -27,7 +27,7 @@ public class Netty4HttpResponse extends AbstractHttpResponse {
private HttpVersion protocol;
private HttpStatus status;
private volatile HttpHeaders headers;
private HttpHeaders headers;
public Netty4HttpResponse(ChannelHandlerContext context,
FullHttpResponse response, byte[] content) {
@ -40,11 +40,10 @@ public class Netty4HttpResponse extends AbstractHttpResponse {
@Override
public HttpHeaders getHeaders() {
if (this.headers == null) {
HttpHeaders headers = new HttpHeaders();
this.headers = new HttpHeaders();
for (Map.Entry<String, String> entry : this.response.headers()) {
headers.add(entry.getKey(), entry.getValue());
}
this.headers = 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;
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.http.HttpClient;
@ -10,6 +15,7 @@ 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.URLParameter;
import com.foxinmy.weixin4j.http.apache.FormBodyPart;
import com.foxinmy.weixin4j.http.apache.HttpMultipartMode;
import com.foxinmy.weixin4j.http.apache.MultipartEntity;
@ -35,45 +41,31 @@ import com.foxinmy.weixin4j.model.Consts;
*/
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,";
protected final HttpClient httpClient;
protected final HttpParams httpParams;
private final HttpClient httpClient;
public WeixinRequestExecutor() {
this(new HttpParams());
}
public WeixinRequestExecutor(HttpParams httpParams) {
this.httpClient = HttpClientFactory.getInstance();
this.httpParams = httpParams;
}
public WeixinResponse get(String url) throws WeixinException {
HttpRequest request = new HttpRequest(HttpMethod.GET, url);
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);
public WeixinRequestExecutor(HttpParams params) {
this.httpClient = HttpClientFactory.getInstance(params);
}
/**
* Post方法执行微信请求
*
* @param url
* 请求URL
* @param body
* 参数内容
* @return 微信响应
* @throws WeixinException
*/
public WeixinResponse post(String url, String body) throws WeixinException {
HttpEntity entity = new StringEntity(body);
HttpRequest request = new HttpRequest(HttpMethod.POST, url);
@ -81,8 +73,20 @@ public class WeixinRequestExecutor {
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) {
entity.addPart(bodyPart);
}
@ -91,31 +95,74 @@ public class WeixinRequestExecutor {
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 {
logger.info("weixin request >> " + request.getMethod() + " " + request.getURI().toString());
logger.info("weixin request >> " + request.getMethod() + " "
+ request.getURI().toString());
HttpResponse httpResponse = httpClient.execute(request);
WeixinResponse response = new WeixinResponse(httpResponse);
logger.info("weixin response << " + httpResponse.getProtocol() + httpResponse.getStatus() + ":"
+ response.getAsString());
handlResponse(response);
logger.info("weixin response << " + httpResponse.getProtocol()
+ httpResponse.getStatus() + ":" + response.getAsString());
handleResponse(response);
return response;
} catch (HttpClientException 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();
if (!SUCCESS_CODE.contains(String.format(",%s,", result.getReturnCode().toLowerCase()))) {
throw new WeixinException(result.getReturnCode(), result.getReturnMsg());
if (!SUCCESS_CODE.contains(String.format(",%s,", result.getReturnCode()
.toLowerCase()))) {
throw new WeixinException(result.getReturnCode(),
result.getReturnMsg());
}
if (XmlMessageConverter.GLOBAL.canConvert(XmlResult.class, response)) {
try {
XmlResult xmlResult = XmlMessageConverter.GLOBAL.convert(XmlResult.class, response);
if (!SUCCESS_CODE.contains(String.format(",%s,", xmlResult.getResultCode().toLowerCase()))) {
throw new WeixinException(xmlResult.getErrCode(), xmlResult.getErrCodeDes());
XmlResult xmlResult = XmlMessageConverter.GLOBAL.convert(
XmlResult.class, response);
if (!SUCCESS_CODE.contains(String.format(",%s,", xmlResult
.getResultCode().toLowerCase()))) {
throw new WeixinException(xmlResult.getErrCode(),
xmlResult.getErrCodeDes());
}
} catch (IOException e) {
;
@ -127,7 +174,39 @@ public class WeixinRequestExecutor {
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.FileCacheStorager;
import com.foxinmy.weixin4j.http.HttpParams;
import com.foxinmy.weixin4j.model.Token;
import com.foxinmy.weixin4j.util.StringUtil;
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
@ -21,10 +20,6 @@ public class Weixin4jSettings<T> {
* 账号信息
*/
private final T account;
/**
* Http参数
*/
private HttpParams httpParams;
/**
* 系统临时目录
*/
@ -46,18 +41,10 @@ public class Weixin4jSettings<T> {
return account;
}
public HttpParams getHttpParams() {
return httpParams;
}
public String getTmpdir() {
return tmpdir;
}
public void setHttpParams(HttpParams httpParams) {
this.httpParams = httpParams;
}
public void setTmpdir(String tmpdir) {
this.tmpdir = tmpdir;
}
@ -103,8 +90,8 @@ public class Weixin4jSettings<T> {
@Override
public String toString() {
return "Weixin4jSettings [account=" + account + ", httpParams="
+ httpParams + ", tmpdir=" + tmpdir + ", cacheStorager="
+ cacheStorager + ", certificateFile=" + certificateFile + "]";
return "Weixin4jSettings [account=" + account + ", tmpdir=" + tmpdir
+ ", cacheStorager=" + cacheStorager + ", certificateFile="
+ certificateFile + "]";
}
}

View File

@ -41,6 +41,27 @@ public class IOUtil {
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 {
ByteArrayOutputStream output = new ByteArrayOutputStream();
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
* @author jinyu(foxinmy@gmail.com)
* @date 2016年1月30日
* @since JDK 1.6
* @since JDK 1.7
* @see
*/
public class PayTest {
@ -43,18 +43,18 @@ public class PayTest {
protected final static WeixinPayProxy PAY;
static {
ACCOUNT = new WeixinPayAccount("appid", "paysignkey", "mchid");
ACCOUNT = new WeixinPayAccount("wx0d1d598c0c03c999", "GATFzDwbQdbbci3QEQxX2rUBvwTrsMiZ", "10020674");
SIGNATURE = new WeixinPaymentSignature(ACCOUNT.getPaySignKey());
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
public void queryOrder() throws WeixinException {
Order order = PAY.queryOrder(new IdQuery("201601131632321",
Order order = PAY.queryOrder(new IdQuery("BY2016010800025",
IdType.TRADENO));
System.err.println(order);
String sign = order.getSign();
@ -70,6 +70,7 @@ public class PayTest {
RefundRecord record = PAY.queryRefund(new IdQuery("TT_1427183696238",
IdType.TRADENO));
System.err.println(record);
// 这里的验证签名需要把details循环拼接
String sign = record.getSign();
record.setSign(null);
String valiSign = SIGNATURE.sign(record);
@ -138,7 +139,7 @@ public class PayTest {
}
@Test
public void reportInterface() throws WeixinException {
public void interfaceReport() throws WeixinException {
String interfaceUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder";
int executeTime = 2500;
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>
</bean>
</property -->
<!-- http参数:http请求时的参数,比如代理、超时等配置信息,暂时还未实现 -->
<property name="httpParams">
<bean class="com.foxinmy.weixin4j.http.HttpParams"/>
</property>
<!-- 临时目录:weixin4j调用某些接口时需要用到的临时目录,不声明则获取顺序为:weixin4j.properties#weixin4j.tmpdir->`java.io.tmp` -->
<property name="tmpdir" value="/tmp/weixin4j" />
</bean>
@ -62,10 +58,6 @@
</constructor-arg>
<!-- ca证书:调用某些支付接口(如退款、红包)需要用到的证书文件,不声明则获取顺序为:weixin4j.properties#weixin4j.certificate.file->`classpath:ca.p12` -->
<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` -->
<property name="tmpdir" value="/tmp/weixin4j" />
</bean>

View File

@ -234,7 +234,6 @@ public class MediaApi extends MpApi {
request = new HttpRequest(HttpMethod.GET,
String.format(meida_download_uri, token.getAccessToken(), mediaId));
}
request.setParams(weixinExecutor.getExecuteParams());
logger.info("weixin request >> " + request.getMethod() + " " + request.getURI().toString());
HttpResponse response = weixinExecutor.getExecuteClient().execute(request);
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.parser.Feature;
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.weixin.WeixinRequestExecutor;
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.Token;
import com.foxinmy.weixin4j.mp.oldpayment.OrderV2;
@ -312,10 +311,9 @@ public class PayOldApi extends MpApi {
ctx = SSLContext.getInstance(Consts.TLS);
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(),
new SecureRandom());
WeixinRequestExecutor weixinExecutor = new WeixinSSLRequestExecutor(
ctx);
response = weixinExecutor.get(refund_uri, map);
response = weixinExecutor.createSSLRequestExecutor(ctx).get(
String.format("%s?%s", refund_uri,
FormUrlEntity.formatParameters(map)));
} catch (WeixinException e) {
throw e;
} catch (Exception e) {
@ -459,7 +457,8 @@ public class PayOldApi extends MpApi {
map.put("key", weixinAccount.getPartnerKey());
String sign = DigestUtil.MD5(MapUtil.toJoinString(map, false, false));
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;
BufferedWriter writer = null;
try {
@ -510,7 +509,8 @@ public class PayOldApi extends MpApi {
map.put(idQuery.getType().getName(), idQuery.getId());
String sign = weixinMD5Signature.sign(map);
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(),
RefundRecordV2.class);
}

View File

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

View File

@ -93,13 +93,13 @@ public class NotifyTest extends TokenTest {
@Test
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,
new FileInputStream(file), file.getName());
NotifyMessage imageNotify = new NotifyMessage(
"owGBft_vbBbOaQOmpEUE4xDLeRSU", new Image(
mediaResult.getMediaId()));
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,
String.format(media_download_uri, token.getAccessToken(), mediaId));
}
request.setParams(weixinExecutor.getExecuteParams());
logger.info("weixin request >> " + request.getMethod() + " " + request.getURI().toString());
HttpResponse response = weixinExecutor.getExecuteClient().execute(request);
byte[] content = IOUtil.toByteArray(response.getBody());

View File

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

View File

@ -339,8 +339,9 @@ public class UserApi extends QyApi {
obj.put("useridlist", userIds);
String user_delete_uri = getRequestUri("user_batchdelete_uri");
Token token = tokenManager.getCache();
WeixinResponse response = weixinExecutor.post(String.format(
user_delete_uri, token.getAccessToken(), obj.toJSONString()));
WeixinResponse response = weixinExecutor.post(
String.format(user_delete_uri, token.getAccessToken()),
obj.toJSONString());
return response.getAsResult();
}
@ -418,9 +419,9 @@ public class UserApi extends QyApi {
obj.put("agentid", agentid);
}
String userid2openid_uri = getRequestUri("userid2openid_uri");
WeixinResponse response = weixinExecutor.post(
String.format(userid2openid_uri, tokenManager.getAccessToken()),
obj.toJSONString());
WeixinResponse response = weixinExecutor
.post(String.format(userid2openid_uri,
tokenManager.getAccessToken()), obj.toJSONString());
obj = response.getAsJson();
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 {
String openid2userid_uri = getRequestUri("openid2userid_uri");
WeixinResponse response = weixinExecutor.post(
String.format(openid2userid_uri, tokenManager.getAccessToken()),
String.format("{\"openid\": \"%s\"}", openid));
WeixinResponse response = weixinExecutor
.post(String.format(openid2userid_uri,
tokenManager.getAccessToken()),
String.format("{\"openid\": \"%s\"}", openid));
return response.getAsJson().getString("userid");
}
}