对Netty-Http-Client的支持
This commit is contained in:
parent
8bef11f99b
commit
bb18b98538
12
CHANGE.md
12
CHANGE.md
@ -445,8 +445,16 @@
|
|||||||
|
|
||||||
+ `release`: weixin4j-[mp|qy] upgrade to 1.5.3,weixin4j-server upgrade to 1.0.5
|
+ `release`: weixin4j-[mp|qy] upgrade to 1.5.3,weixin4j-server upgrade to 1.0.5
|
||||||
|
|
||||||
+ **weixin4j-[mp|qy]**: 媒体接口类(MediaApi)查询素材接口调整:去掉offset,count替换为Pageable类
|
+ **weixin4j-[mp|qy]**: 媒体接口类(MediaApi)查询素材接口调整:去掉offset,count替换为Pageable类
|
||||||
|
|
||||||
* 2015-08-18
|
* 2015-08-18
|
||||||
|
|
||||||
+ 比较大的改动:重构了HttpClient部分
|
+ 比较大的改动:重构了HttpClient部分
|
||||||
|
|
||||||
|
* 2015-09-08
|
||||||
|
|
||||||
|
+ weixin4j-mp:新增批量获取用户信息接口
|
||||||
|
|
||||||
|
* 2015-09-10
|
||||||
|
|
||||||
|
+ 对Netty-Http-Client的支持
|
||||||
@ -29,5 +29,11 @@
|
|||||||
<version>4.3</version>
|
<version>4.3</version>
|
||||||
<optional>true</optional>
|
<optional>true</optional>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.netty</groupId>
|
||||||
|
<artifactId>netty-all</artifactId>
|
||||||
|
<version>4.0.30.Final</version>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
@ -106,4 +106,25 @@ public abstract class AbstractHttpClient implements HttpClient {
|
|||||||
}
|
}
|
||||||
return execute(new HttpRequest(method, buf.toString()));
|
return execute(new HttpRequest(method, buf.toString()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean hasError(HttpStatus status) {
|
||||||
|
return (status.series() == HttpStatus.Series.CLIENT_ERROR || status
|
||||||
|
.series() == HttpStatus.Series.SERVER_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void handleResponse(HttpResponse response)
|
||||||
|
throws HttpClientException {
|
||||||
|
HttpStatus status = response.getStatus();
|
||||||
|
if (hasError(status)) {
|
||||||
|
switch (status.series()) {
|
||||||
|
case CLIENT_ERROR:
|
||||||
|
case SERVER_ERROR:
|
||||||
|
throw new HttpClientException(String.format("%d %s",
|
||||||
|
status.getStatusCode(), status.getStatusText()));
|
||||||
|
default:
|
||||||
|
throw new HttpClientException("Unknown status code [" + status
|
||||||
|
+ "]");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,31 @@
|
|||||||
|
package com.foxinmy.weixin4j.http;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @className AbstractHttpResponse
|
||||||
|
* @author jy
|
||||||
|
* @date 2015年9月7日
|
||||||
|
* @since JDK 1.7
|
||||||
|
* @see
|
||||||
|
*/
|
||||||
|
public abstract class AbstractHttpResponse implements HttpResponse {
|
||||||
|
|
||||||
|
private final byte[] content;
|
||||||
|
|
||||||
|
public AbstractHttpResponse(byte[] content) {
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getContent() {
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputStream getBody() {
|
||||||
|
return content != null ? new ByteArrayInputStream(content) : null;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -24,14 +24,21 @@ public interface HttpResponse extends HttpMessage {
|
|||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
HttpStatus getStatus() throws HttpClientException;
|
HttpStatus getStatus();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 响应内容
|
* 响应内容
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
InputStream getBody() throws HttpClientException;
|
InputStream getBody();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 响应内容
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
byte[] getContent();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 释放资源
|
* 释放资源
|
||||||
|
|||||||
@ -31,7 +31,6 @@ package com.foxinmy.weixin4j.http;
|
|||||||
* Constants enumerating the HTTP status codes. All status codes defined in
|
* Constants enumerating the HTTP status codes. All status codes defined in
|
||||||
* RFC1945 (HTTP/1.0), RFC2616 (HTTP/1.1), and RFC2518 (WebDAV) are listed.
|
* RFC1945 (HTTP/1.0), RFC2616 (HTTP/1.1), and RFC2518 (WebDAV) are listed.
|
||||||
*
|
*
|
||||||
* @see StatusLine
|
|
||||||
*
|
*
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
@ -188,6 +187,54 @@ public final class HttpStatus {
|
|||||||
return statusText;
|
return statusText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the HTTP status series of this status code.
|
||||||
|
*
|
||||||
|
* @see HttpStatus.Series
|
||||||
|
*/
|
||||||
|
public Series series() {
|
||||||
|
return Series.valueOf(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Java 5 enumeration of HTTP status series.
|
||||||
|
* <p>
|
||||||
|
* Retrievable via {@link HttpStatus#series()}.
|
||||||
|
*/
|
||||||
|
public static enum Series {
|
||||||
|
|
||||||
|
INFORMATIONAL(1), SUCCESSFUL(2), REDIRECTION(3), CLIENT_ERROR(4), SERVER_ERROR(
|
||||||
|
5);
|
||||||
|
|
||||||
|
private final int value;
|
||||||
|
|
||||||
|
private Series(int value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the integer value of this status series. Ranges from 1 to 5.
|
||||||
|
*/
|
||||||
|
public int value() {
|
||||||
|
return this.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Series valueOf(int status) {
|
||||||
|
int seriesCode = status / 100;
|
||||||
|
for (Series series : values()) {
|
||||||
|
if (series.value == seriesCode) {
|
||||||
|
return series;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("No matching constant for ["
|
||||||
|
+ status + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Series valueOf(HttpStatus status) {
|
||||||
|
return valueOf(status.statusCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "[" + statusCode + "," + statusText + "]";
|
return "[" + statusCode + "," + statusText + "]";
|
||||||
|
|||||||
@ -1,29 +1,24 @@
|
|||||||
package com.foxinmy.weixin4j.http;
|
package com.foxinmy.weixin4j.http;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.net.Proxy;
|
import java.net.Proxy;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URLConnection;
|
import java.net.URLConnection;
|
||||||
import java.security.KeyManagementException;
|
|
||||||
import java.security.NoSuchAlgorithmException;
|
|
||||||
import java.security.cert.CertificateException;
|
|
||||||
import java.security.cert.X509Certificate;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import javax.net.ssl.HostnameVerifier;
|
import javax.net.ssl.HostnameVerifier;
|
||||||
import javax.net.ssl.HttpsURLConnection;
|
import javax.net.ssl.HttpsURLConnection;
|
||||||
import javax.net.ssl.SSLContext;
|
import javax.net.ssl.SSLContext;
|
||||||
import javax.net.ssl.SSLSession;
|
import javax.net.ssl.SSLSession;
|
||||||
import javax.net.ssl.X509TrustManager;
|
|
||||||
|
|
||||||
import com.foxinmy.weixin4j.http.entity.HttpEntity;
|
import com.foxinmy.weixin4j.http.entity.HttpEntity;
|
||||||
import com.foxinmy.weixin4j.model.Consts;
|
import com.foxinmy.weixin4j.http.factory.HttpClientFactory;
|
||||||
|
import com.foxinmy.weixin4j.util.IOUtil;
|
||||||
import com.foxinmy.weixin4j.util.StringUtil;
|
import com.foxinmy.weixin4j.util.StringUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -46,27 +41,6 @@ public class SimpleHttpClient extends AbstractHttpClient implements HttpClient {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected X509TrustManager createX509TrustManager() {
|
|
||||||
return new X509TrustManager() {
|
|
||||||
@Override
|
|
||||||
public X509Certificate[] getAcceptedIssuers() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void checkServerTrusted(
|
|
||||||
X509Certificate[] paramArrayOfX509Certificate,
|
|
||||||
String paramString) throws CertificateException {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void checkClientTrusted(
|
|
||||||
X509Certificate[] paramArrayOfX509Certificate,
|
|
||||||
String paramString) throws CertificateException {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
protected HttpURLConnection createHttpConnection(HttpRequest request)
|
protected HttpURLConnection createHttpConnection(HttpRequest request)
|
||||||
throws IOException {
|
throws IOException {
|
||||||
URI uri = request.getURI();
|
URI uri = request.getURI();
|
||||||
@ -83,11 +57,7 @@ public class SimpleHttpClient extends AbstractHttpClient implements HttpClient {
|
|||||||
hostnameVerifier = params.getHostnameVerifier();
|
hostnameVerifier = params.getHostnameVerifier();
|
||||||
}
|
}
|
||||||
if (sslContext == null) {
|
if (sslContext == null) {
|
||||||
sslContext = SSLContext.getInstance("TLS");
|
sslContext = HttpClientFactory.allowSSLContext();
|
||||||
sslContext
|
|
||||||
.init(null,
|
|
||||||
new X509TrustManager[] { createX509TrustManager() },
|
|
||||||
new java.security.SecureRandom());
|
|
||||||
}
|
}
|
||||||
if (hostnameVerifier == null) {
|
if (hostnameVerifier == null) {
|
||||||
hostnameVerifier = createHostnameVerifier();
|
hostnameVerifier = createHostnameVerifier();
|
||||||
@ -96,23 +66,14 @@ public class SimpleHttpClient extends AbstractHttpClient implements HttpClient {
|
|||||||
connection.setSSLSocketFactory(sslContext.getSocketFactory());
|
connection.setSSLSocketFactory(sslContext.getSocketFactory());
|
||||||
connection.setHostnameVerifier(hostnameVerifier);
|
connection.setHostnameVerifier(hostnameVerifier);
|
||||||
return connection;
|
return connection;
|
||||||
} catch (NoSuchAlgorithmException | KeyManagementException e) {
|
} catch (HttpClientException e) {
|
||||||
throw new IOException(e.getMessage());
|
throw new IOException(e);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return (HttpURLConnection) urlConnection;
|
return (HttpURLConnection) urlConnection;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Map<String, String> createDefualtHeader() {
|
|
||||||
Map<String, String> header = new HashMap<String, String>();
|
|
||||||
header.put("User-Agent", "simple-httpclient");
|
|
||||||
header.put("Accept", "text/xml,text/javascript");
|
|
||||||
header.put("Accept-Charset", Consts.UTF_8.name());
|
|
||||||
header.put("Accept-Encoding", Consts.UTF_8.name());
|
|
||||||
return header;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpResponse execute(HttpRequest request) throws HttpClientException {
|
public HttpResponse execute(HttpRequest request) throws HttpClientException {
|
||||||
HttpResponse response = null;
|
HttpResponse response = null;
|
||||||
@ -141,25 +102,31 @@ public class SimpleHttpClient extends AbstractHttpClient implements HttpClient {
|
|||||||
connection.setDoOutput(false);
|
connection.setDoOutput(false);
|
||||||
}
|
}
|
||||||
// set headers
|
// set headers
|
||||||
for (Iterator<Entry<String, String>> headerIterator = createDefualtHeader()
|
|
||||||
.entrySet().iterator(); headerIterator.hasNext();) {
|
|
||||||
Entry<String, String> header = headerIterator.next();
|
|
||||||
connection.setRequestProperty(header.getKey(),
|
|
||||||
header.getValue());
|
|
||||||
}
|
|
||||||
HttpHeaders headers = request.getHeaders();
|
HttpHeaders headers = request.getHeaders();
|
||||||
if (headers != null) {
|
if (headers == null) {
|
||||||
for (Iterator<Entry<String, List<String>>> headerIterator = headers
|
headers = new HttpHeaders();
|
||||||
.entrySet().iterator(); headerIterator.hasNext();) {
|
if (!headers.containsKey(HttpHeaders.HOST)) {
|
||||||
Entry<String, List<String>> header = headerIterator.next();
|
headers.set(HttpHeaders.HOST, request.getURI().getHost());
|
||||||
if (HttpHeaders.COOKIE.equalsIgnoreCase(header.getKey())) {
|
}
|
||||||
connection.setRequestProperty(header.getKey(),
|
// Add default accept headers
|
||||||
StringUtil.join(header.getValue(), ';'));
|
if (!headers.containsKey(HttpHeaders.ACCEPT)) {
|
||||||
} else {
|
headers.set(HttpHeaders.ACCEPT, "*/*");
|
||||||
for (String headerValue : header.getValue()) {
|
}
|
||||||
connection.addRequestProperty(header.getKey(),
|
// Add default user agent
|
||||||
headerValue != null ? headerValue : "");
|
if (!headers.containsKey(HttpHeaders.USER_AGENT)) {
|
||||||
}
|
headers.set(HttpHeaders.USER_AGENT, "jdk/httpclient");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (Iterator<Entry<String, List<String>>> headerIterator = headers
|
||||||
|
.entrySet().iterator(); headerIterator.hasNext();) {
|
||||||
|
Entry<String, List<String>> header = headerIterator.next();
|
||||||
|
if (HttpHeaders.COOKIE.equalsIgnoreCase(header.getKey())) {
|
||||||
|
connection.setRequestProperty(header.getKey(),
|
||||||
|
StringUtil.join(header.getValue(), ';'));
|
||||||
|
} else {
|
||||||
|
for (String headerValue : header.getValue()) {
|
||||||
|
connection.addRequestProperty(header.getKey(),
|
||||||
|
headerValue != null ? headerValue : "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -170,16 +137,15 @@ public class SimpleHttpClient extends AbstractHttpClient implements HttpClient {
|
|||||||
if (httpEntity != null) {
|
if (httpEntity != null) {
|
||||||
// Read Out Exception when connection.disconnect();
|
// Read Out Exception when connection.disconnect();
|
||||||
/*
|
/*
|
||||||
|
* if (httpEntity.getContentLength() > 0l) {
|
||||||
|
* connection.setFixedLengthStreamingMode(httpEntity
|
||||||
|
* .getContentLength()); } else { connection
|
||||||
|
* .setChunkedStreamingMode(params != null ? params
|
||||||
|
* .getChunkSize() : 4096); }
|
||||||
|
*/
|
||||||
if (httpEntity.getContentLength() > 0l) {
|
if (httpEntity.getContentLength() > 0l) {
|
||||||
connection.setFixedLengthStreamingMode(httpEntity
|
connection.setRequestProperty(
|
||||||
.getContentLength());
|
HttpHeaders.CONTENT_LENGTH,
|
||||||
} else {
|
|
||||||
connection
|
|
||||||
.setChunkedStreamingMode(params != null ? params
|
|
||||||
.getChunkSize() : 4096);
|
|
||||||
}*/
|
|
||||||
if (httpEntity.getContentLength() > 0l) {
|
|
||||||
connection.setRequestProperty(HttpHeaders.CONTENT_LENGTH,
|
|
||||||
Long.toString(httpEntity.getContentLength()));
|
Long.toString(httpEntity.getContentLength()));
|
||||||
}
|
}
|
||||||
if (httpEntity.getContentType() != null) {
|
if (httpEntity.getContentType() != null) {
|
||||||
@ -198,7 +164,12 @@ public class SimpleHttpClient extends AbstractHttpClient implements HttpClient {
|
|||||||
output.close();
|
output.close();
|
||||||
}
|
}
|
||||||
// building response
|
// building response
|
||||||
response = new SimpleHttpResponse(connection);
|
InputStream input = connection.getErrorStream() != null ? connection
|
||||||
|
.getErrorStream() : connection.getInputStream();
|
||||||
|
byte[] content = IOUtil.toByteArray(input);
|
||||||
|
response = new SimpleHttpResponse(connection, content);
|
||||||
|
input.close();
|
||||||
|
handleResponse(response);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new HttpClientException("I/O error on "
|
throw new HttpClientException("I/O error on "
|
||||||
+ request.getMethod().name() + " request for \""
|
+ request.getMethod().name() + " request for \""
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
package com.foxinmy.weixin4j.http;
|
package com.foxinmy.weixin4j.http;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -17,7 +16,7 @@ import java.util.Map.Entry;
|
|||||||
* @since JDK 1.7
|
* @since JDK 1.7
|
||||||
* @see
|
* @see
|
||||||
*/
|
*/
|
||||||
public class SimpleHttpResponse implements HttpResponse {
|
public class SimpleHttpResponse extends AbstractHttpResponse {
|
||||||
|
|
||||||
private final HttpURLConnection connection;
|
private final HttpURLConnection connection;
|
||||||
|
|
||||||
@ -25,7 +24,8 @@ public class SimpleHttpResponse implements HttpResponse {
|
|||||||
private HttpVersion protocol;
|
private HttpVersion protocol;
|
||||||
private HttpStatus status;
|
private HttpStatus status;
|
||||||
|
|
||||||
public SimpleHttpResponse(HttpURLConnection connection) {
|
public SimpleHttpResponse(HttpURLConnection connection, byte[] content) {
|
||||||
|
super(content);
|
||||||
this.connection = connection;
|
this.connection = connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,28 +65,18 @@ public class SimpleHttpResponse implements HttpResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpStatus getStatus() throws HttpClientException {
|
public HttpStatus getStatus() {
|
||||||
if (status == null) {
|
if (status == null) {
|
||||||
try {
|
try {
|
||||||
status = new HttpStatus(connection.getResponseCode(),
|
status = new HttpStatus(connection.getResponseCode(),
|
||||||
connection.getResponseMessage());
|
connection.getResponseMessage());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new HttpClientException("I/O Error on getStatus", e);
|
throw new RuntimeException("I/O Error on getStatus", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public InputStream getBody() throws HttpClientException {
|
|
||||||
try {
|
|
||||||
return connection.getErrorStream() != null ? connection
|
|
||||||
.getErrorStream() : connection.getInputStream();
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new HttpClientException("I/O Error on getBody", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
connection.disconnect();
|
connection.disconnect();
|
||||||
|
|||||||
@ -1,6 +1,15 @@
|
|||||||
package com.foxinmy.weixin4j.http.factory;
|
package com.foxinmy.weixin4j.http.factory;
|
||||||
|
|
||||||
|
import java.security.KeyManagementException;
|
||||||
|
import java.security.NoSuchAlgorithmException;
|
||||||
|
import java.security.cert.CertificateException;
|
||||||
|
import java.security.cert.X509Certificate;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
|
import javax.net.ssl.X509TrustManager;
|
||||||
|
|
||||||
import com.foxinmy.weixin4j.http.HttpClient;
|
import com.foxinmy.weixin4j.http.HttpClient;
|
||||||
|
import com.foxinmy.weixin4j.http.HttpClientException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HttpClient工厂生产类:参考netty的InternalLoggerFactory
|
* HttpClient工厂生产类:参考netty的InternalLoggerFactory
|
||||||
@ -26,12 +35,16 @@ public abstract class HttpClientFactory {
|
|||||||
private static HttpClientFactory newDefaultFactory() {
|
private static HttpClientFactory newDefaultFactory() {
|
||||||
HttpClientFactory f;
|
HttpClientFactory f;
|
||||||
try {
|
try {
|
||||||
f = new HttpComponent4Factory();
|
f = new Netty4HttpClientFactory();
|
||||||
} catch (Throwable e2) {
|
} catch (Throwable e1) {
|
||||||
try {
|
try {
|
||||||
f = new HttpComponent3Factory();
|
f = new HttpComponent4Factory();
|
||||||
} catch (Throwable e3) {
|
} catch (Throwable e2) {
|
||||||
f = new SimpleHttpClientFactory();
|
try {
|
||||||
|
f = new HttpComponent3Factory();
|
||||||
|
} catch (Throwable e3) {
|
||||||
|
f = new SimpleHttpClientFactory();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return f;
|
return f;
|
||||||
@ -73,4 +86,37 @@ public abstract class HttpClientFactory {
|
|||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public abstract HttpClient newInstance();
|
public abstract HttpClient newInstance();
|
||||||
|
|
||||||
|
public static SSLContext allowSSLContext() throws HttpClientException {
|
||||||
|
try {
|
||||||
|
SSLContext sslContext = SSLContext.getInstance("TLS");
|
||||||
|
sslContext.init(null,
|
||||||
|
new X509TrustManager[] { createX509TrustManager() },
|
||||||
|
new java.security.SecureRandom());
|
||||||
|
return sslContext;
|
||||||
|
} catch (NoSuchAlgorithmException | KeyManagementException e) {
|
||||||
|
throw new HttpClientException("Create SSLContext Error:", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static X509TrustManager createX509TrustManager() {
|
||||||
|
return new X509TrustManager() {
|
||||||
|
@Override
|
||||||
|
public X509Certificate[] getAcceptedIssuers() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkServerTrusted(
|
||||||
|
X509Certificate[] paramArrayOfX509Certificate,
|
||||||
|
String paramString) throws CertificateException {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkClientTrusted(
|
||||||
|
X509Certificate[] paramArrayOfX509Certificate,
|
||||||
|
String paramString) throws CertificateException {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -109,18 +109,30 @@ public class HttpComponent3 extends AbstractHttpClient {
|
|||||||
}
|
}
|
||||||
com.foxinmy.weixin4j.http.HttpHeaders headers = request
|
com.foxinmy.weixin4j.http.HttpHeaders headers = request
|
||||||
.getHeaders();
|
.getHeaders();
|
||||||
if (headers != null) {
|
if (headers == null) {
|
||||||
for (Iterator<Entry<String, List<String>>> headerIterator = headers
|
headers = new HttpHeaders();
|
||||||
.entrySet().iterator(); headerIterator.hasNext();) {
|
}
|
||||||
Entry<String, List<String>> header = headerIterator.next();
|
if (!headers.containsKey(HttpHeaders.HOST)) {
|
||||||
if (HttpHeaders.COOKIE.equalsIgnoreCase(header.getKey())) {
|
headers.set(HttpHeaders.HOST, uri.getHost());
|
||||||
httpMethod.setRequestHeader(header.getKey(),
|
}
|
||||||
StringUtil.join(header.getValue(), ';'));
|
// Add default accept headers
|
||||||
} else {
|
if (!headers.containsKey(HttpHeaders.ACCEPT)) {
|
||||||
for (String headerValue : header.getValue()) {
|
headers.set(HttpHeaders.ACCEPT, "*/*");
|
||||||
httpMethod.addRequestHeader(header.getKey(),
|
}
|
||||||
headerValue != null ? headerValue : "");
|
// Add default user agent
|
||||||
}
|
if (!headers.containsKey(HttpHeaders.USER_AGENT)) {
|
||||||
|
headers.set(HttpHeaders.USER_AGENT, "apache/httpclient3");
|
||||||
|
}
|
||||||
|
for (Iterator<Entry<String, List<String>>> headerIterator = headers
|
||||||
|
.entrySet().iterator(); headerIterator.hasNext();) {
|
||||||
|
Entry<String, List<String>> header = headerIterator.next();
|
||||||
|
if (HttpHeaders.COOKIE.equalsIgnoreCase(header.getKey())) {
|
||||||
|
httpMethod.setRequestHeader(header.getKey(),
|
||||||
|
StringUtil.join(header.getValue(), ';'));
|
||||||
|
} else {
|
||||||
|
for (String headerValue : header.getValue()) {
|
||||||
|
httpMethod.addRequestHeader(header.getKey(),
|
||||||
|
headerValue != null ? headerValue : "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -153,6 +165,7 @@ public class HttpComponent3 extends AbstractHttpClient {
|
|||||||
}
|
}
|
||||||
httpClient.executeMethod(httpMethod);
|
httpClient.executeMethod(httpMethod);
|
||||||
response = new HttpComponent3Response(httpMethod);
|
response = new HttpComponent3Response(httpMethod);
|
||||||
|
handleResponse(response);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new HttpClientException("I/O error on "
|
throw new HttpClientException("I/O error on "
|
||||||
+ request.getMethod().name() + " request for \""
|
+ request.getMethod().name() + " request for \""
|
||||||
|
|||||||
@ -1,16 +1,13 @@
|
|||||||
package com.foxinmy.weixin4j.http.factory;
|
package com.foxinmy.weixin4j.http.factory;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import org.apache.commons.httpclient.Header;
|
import org.apache.commons.httpclient.Header;
|
||||||
import org.apache.commons.httpclient.HttpMethod;
|
import org.apache.commons.httpclient.HttpMethod;
|
||||||
import org.apache.commons.httpclient.protocol.Protocol;
|
import org.apache.commons.httpclient.protocol.Protocol;
|
||||||
|
|
||||||
import com.foxinmy.weixin4j.http.HttpClientException;
|
import com.foxinmy.weixin4j.http.AbstractHttpResponse;
|
||||||
import com.foxinmy.weixin4j.http.HttpHeaders;
|
import com.foxinmy.weixin4j.http.HttpHeaders;
|
||||||
import com.foxinmy.weixin4j.http.HttpResponse;
|
|
||||||
import com.foxinmy.weixin4j.http.HttpStatus;
|
import com.foxinmy.weixin4j.http.HttpStatus;
|
||||||
import com.foxinmy.weixin4j.http.HttpVersion;
|
import com.foxinmy.weixin4j.http.HttpVersion;
|
||||||
|
|
||||||
@ -23,22 +20,17 @@ import com.foxinmy.weixin4j.http.HttpVersion;
|
|||||||
* @since JDK 1.7
|
* @since JDK 1.7
|
||||||
* @see
|
* @see
|
||||||
*/
|
*/
|
||||||
public class HttpComponent3Response implements HttpResponse {
|
public class HttpComponent3Response extends AbstractHttpResponse {
|
||||||
|
|
||||||
private final HttpMethod httpMethod;
|
private final HttpMethod httpMethod;
|
||||||
|
|
||||||
private HttpHeaders headers;
|
private HttpHeaders headers;
|
||||||
private HttpVersion protocol;
|
private HttpVersion protocol;
|
||||||
private HttpStatus status;
|
private HttpStatus status;
|
||||||
private InputStream body;
|
|
||||||
|
|
||||||
public HttpComponent3Response(HttpMethod httpMethod) {
|
public HttpComponent3Response(HttpMethod httpMethod) throws IOException {
|
||||||
|
super(httpMethod.getResponseBody());
|
||||||
this.httpMethod = httpMethod;
|
this.httpMethod = httpMethod;
|
||||||
try {
|
|
||||||
this.body = new ByteArrayInputStream(httpMethod.getResponseBody());
|
|
||||||
} catch (IOException e) {
|
|
||||||
;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -71,7 +63,7 @@ public class HttpComponent3Response implements HttpResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpStatus getStatus() throws HttpClientException {
|
public HttpStatus getStatus() {
|
||||||
if (status == null) {
|
if (status == null) {
|
||||||
status = new HttpStatus(httpMethod.getStatusCode(),
|
status = new HttpStatus(httpMethod.getStatusCode(),
|
||||||
httpMethod.getStatusText());
|
httpMethod.getStatusText());
|
||||||
@ -79,11 +71,6 @@ public class HttpComponent3Response implements HttpResponse {
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public InputStream getBody() throws HttpClientException {
|
|
||||||
return body;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
httpMethod.releaseConnection();
|
httpMethod.releaseConnection();
|
||||||
|
|||||||
@ -26,6 +26,7 @@ import org.apache.http.client.methods.HttpTrace;
|
|||||||
import org.apache.http.conn.ssl.X509HostnameVerifier;
|
import org.apache.http.conn.ssl.X509HostnameVerifier;
|
||||||
import org.apache.http.entity.AbstractHttpEntity;
|
import org.apache.http.entity.AbstractHttpEntity;
|
||||||
import org.apache.http.entity.InputStreamEntity;
|
import org.apache.http.entity.InputStreamEntity;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
|
|
||||||
import com.foxinmy.weixin4j.http.AbstractHttpClient;
|
import com.foxinmy.weixin4j.http.AbstractHttpClient;
|
||||||
import com.foxinmy.weixin4j.http.HttpHeaders;
|
import com.foxinmy.weixin4j.http.HttpHeaders;
|
||||||
@ -57,18 +58,27 @@ public abstract class HttpComponent4 extends AbstractHttpClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void addHeaders(HttpHeaders headers, HttpRequestBase uriRequest) {
|
protected void addHeaders(HttpHeaders headers, HttpRequestBase uriRequest) {
|
||||||
if (headers != null) {
|
if (headers == null) {
|
||||||
for (Iterator<Entry<String, List<String>>> headerIterator = headers
|
headers = new HttpHeaders();
|
||||||
.entrySet().iterator(); headerIterator.hasNext();) {
|
}
|
||||||
Entry<String, List<String>> header = headerIterator.next();
|
// Add default accept headers
|
||||||
if (HttpHeaders.COOKIE.equalsIgnoreCase(header.getKey())) {
|
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/httpclient4");
|
||||||
|
}
|
||||||
|
for (Iterator<Entry<String, List<String>>> headerIterator = headers
|
||||||
|
.entrySet().iterator(); headerIterator.hasNext();) {
|
||||||
|
Entry<String, List<String>> header = headerIterator.next();
|
||||||
|
if (HttpHeaders.COOKIE.equalsIgnoreCase(header.getKey())) {
|
||||||
|
uriRequest.addHeader(header.getKey(),
|
||||||
|
StringUtil.join(header.getValue(), ';'));
|
||||||
|
} else {
|
||||||
|
for (String headerValue : header.getValue()) {
|
||||||
uriRequest.addHeader(header.getKey(),
|
uriRequest.addHeader(header.getKey(),
|
||||||
StringUtil.join(header.getValue(), ';'));
|
headerValue != null ? headerValue : "");
|
||||||
} else {
|
|
||||||
for (String headerValue : header.getValue()) {
|
|
||||||
uriRequest.addHeader(header.getKey(),
|
|
||||||
headerValue != null ? headerValue : "");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,6 +104,11 @@ public abstract class HttpComponent4 extends AbstractHttpClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected byte[] getContent(org.apache.http.HttpResponse httpResponse)
|
||||||
|
throws IOException {
|
||||||
|
return EntityUtils.toByteArray(httpResponse.getEntity());
|
||||||
|
}
|
||||||
|
|
||||||
protected static class CustomHostnameVerifier implements
|
protected static class CustomHostnameVerifier implements
|
||||||
X509HostnameVerifier {
|
X509HostnameVerifier {
|
||||||
|
|
||||||
|
|||||||
@ -13,7 +13,6 @@ import org.apache.http.impl.client.DefaultHttpClient;
|
|||||||
import org.apache.http.params.CoreConnectionPNames;
|
import org.apache.http.params.CoreConnectionPNames;
|
||||||
import org.apache.http.params.CoreProtocolPNames;
|
import org.apache.http.params.CoreProtocolPNames;
|
||||||
|
|
||||||
import com.foxinmy.weixin4j.http.HttpClient;
|
|
||||||
import com.foxinmy.weixin4j.http.HttpClientException;
|
import com.foxinmy.weixin4j.http.HttpClientException;
|
||||||
import com.foxinmy.weixin4j.http.HttpHeaders;
|
import com.foxinmy.weixin4j.http.HttpHeaders;
|
||||||
import com.foxinmy.weixin4j.http.HttpParams;
|
import com.foxinmy.weixin4j.http.HttpParams;
|
||||||
@ -87,7 +86,9 @@ public class HttpComponent4_1 extends HttpComponent4 {
|
|||||||
addEntity(request.getEntity(), uriRequest);
|
addEntity(request.getEntity(), uriRequest);
|
||||||
org.apache.http.HttpResponse httpResponse = httpClient
|
org.apache.http.HttpResponse httpResponse = httpClient
|
||||||
.execute(uriRequest);
|
.execute(uriRequest);
|
||||||
response = new HttpComponent4_1Response(httpClient, httpResponse);
|
response = new HttpComponent4_1Response(httpResponse,
|
||||||
|
getContent(httpResponse));
|
||||||
|
handleResponse(response);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new HttpClientException("I/O error on "
|
throw new HttpClientException("I/O error on "
|
||||||
+ request.getMethod().name() + " request for \""
|
+ request.getMethod().name() + " request for \""
|
||||||
|
|||||||
@ -1,16 +1,13 @@
|
|||||||
package com.foxinmy.weixin4j.http.factory;
|
package com.foxinmy.weixin4j.http.factory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import org.apache.http.Header;
|
import org.apache.http.Header;
|
||||||
import org.apache.http.HttpEntity;
|
|
||||||
import org.apache.http.ProtocolVersion;
|
import org.apache.http.ProtocolVersion;
|
||||||
import org.apache.http.StatusLine;
|
import org.apache.http.StatusLine;
|
||||||
|
|
||||||
import com.foxinmy.weixin4j.http.HttpClientException;
|
import com.foxinmy.weixin4j.http.AbstractHttpResponse;
|
||||||
import com.foxinmy.weixin4j.http.HttpHeaders;
|
import com.foxinmy.weixin4j.http.HttpHeaders;
|
||||||
import com.foxinmy.weixin4j.http.HttpResponse;
|
|
||||||
import com.foxinmy.weixin4j.http.HttpStatus;
|
import com.foxinmy.weixin4j.http.HttpStatus;
|
||||||
import com.foxinmy.weixin4j.http.HttpVersion;
|
import com.foxinmy.weixin4j.http.HttpVersion;
|
||||||
|
|
||||||
@ -23,18 +20,16 @@ import com.foxinmy.weixin4j.http.HttpVersion;
|
|||||||
* @since JDK 1.7
|
* @since JDK 1.7
|
||||||
* @see
|
* @see
|
||||||
*/
|
*/
|
||||||
public class HttpComponent4_1Response implements HttpResponse {
|
public class HttpComponent4_1Response extends AbstractHttpResponse {
|
||||||
private final org.apache.http.client.HttpClient httpClient;
|
|
||||||
private final org.apache.http.HttpResponse httpResponse;
|
private final org.apache.http.HttpResponse httpResponse;
|
||||||
|
|
||||||
private HttpHeaders headers;
|
private HttpHeaders headers;
|
||||||
private HttpVersion protocol;
|
private HttpVersion protocol;
|
||||||
private HttpStatus status;
|
private HttpStatus status;
|
||||||
|
|
||||||
public HttpComponent4_1Response(
|
public HttpComponent4_1Response(org.apache.http.HttpResponse httpResponse,
|
||||||
org.apache.http.client.HttpClient httpClient,
|
byte[] content) throws IOException {
|
||||||
org.apache.http.HttpResponse httpResponse) {
|
super(content);
|
||||||
this.httpClient = httpClient;
|
|
||||||
this.httpResponse = httpResponse;
|
this.httpResponse = httpResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +59,7 @@ public class HttpComponent4_1Response implements HttpResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpStatus getStatus() throws HttpClientException {
|
public HttpStatus getStatus() {
|
||||||
if (status == null) {
|
if (status == null) {
|
||||||
StatusLine statusLine = httpResponse.getStatusLine();
|
StatusLine statusLine = httpResponse.getStatusLine();
|
||||||
status = new HttpStatus(statusLine.getStatusCode(),
|
status = new HttpStatus(statusLine.getStatusCode(),
|
||||||
@ -74,17 +69,11 @@ public class HttpComponent4_1Response implements HttpResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InputStream getBody() throws HttpClientException {
|
public void close() {
|
||||||
try {
|
try {
|
||||||
HttpEntity entity = this.httpResponse.getEntity();
|
httpResponse.getEntity().consumeContent();
|
||||||
return (entity != null ? entity.getContent() : null);
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new HttpClientException("I/O Error on getBody", e);
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void close() {
|
|
||||||
httpClient.getConnectionManager().closeExpiredConnections();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -69,7 +69,9 @@ public class HttpComponent4_2 extends HttpComponent4 {
|
|||||||
addHeaders(request.getHeaders(), uriRequest);
|
addHeaders(request.getHeaders(), uriRequest);
|
||||||
addEntity(request.getEntity(), uriRequest);
|
addEntity(request.getEntity(), uriRequest);
|
||||||
CloseableHttpResponse httpResponse = httpClient.execute(uriRequest);
|
CloseableHttpResponse httpResponse = httpClient.execute(uriRequest);
|
||||||
response = new HttpComponent4_2Response(httpResponse);
|
response = new HttpComponent4_2Response(httpResponse,
|
||||||
|
getContent(httpResponse));
|
||||||
|
handleResponse(response);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new HttpClientException("I/O error on "
|
throw new HttpClientException("I/O error on "
|
||||||
+ request.getMethod().name() + " request for \""
|
+ request.getMethod().name() + " request for \""
|
||||||
|
|||||||
@ -1,17 +1,15 @@
|
|||||||
package com.foxinmy.weixin4j.http.factory;
|
package com.foxinmy.weixin4j.http.factory;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import org.apache.http.Header;
|
import org.apache.http.Header;
|
||||||
import org.apache.http.HttpEntity;
|
|
||||||
import org.apache.http.ProtocolVersion;
|
import org.apache.http.ProtocolVersion;
|
||||||
import org.apache.http.StatusLine;
|
import org.apache.http.StatusLine;
|
||||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
|
|
||||||
import com.foxinmy.weixin4j.http.HttpClientException;
|
import com.foxinmy.weixin4j.http.AbstractHttpResponse;
|
||||||
import com.foxinmy.weixin4j.http.HttpHeaders;
|
import com.foxinmy.weixin4j.http.HttpHeaders;
|
||||||
import com.foxinmy.weixin4j.http.HttpResponse;
|
|
||||||
import com.foxinmy.weixin4j.http.HttpStatus;
|
import com.foxinmy.weixin4j.http.HttpStatus;
|
||||||
import com.foxinmy.weixin4j.http.HttpVersion;
|
import com.foxinmy.weixin4j.http.HttpVersion;
|
||||||
|
|
||||||
@ -24,7 +22,7 @@ import com.foxinmy.weixin4j.http.HttpVersion;
|
|||||||
* @since JDK 1.7
|
* @since JDK 1.7
|
||||||
* @see
|
* @see
|
||||||
*/
|
*/
|
||||||
public class HttpComponent4_2Response implements HttpResponse {
|
public class HttpComponent4_2Response extends AbstractHttpResponse {
|
||||||
|
|
||||||
private final CloseableHttpResponse httpResponse;
|
private final CloseableHttpResponse httpResponse;
|
||||||
|
|
||||||
@ -32,7 +30,9 @@ public class HttpComponent4_2Response implements HttpResponse {
|
|||||||
private HttpVersion protocol;
|
private HttpVersion protocol;
|
||||||
private HttpStatus status;
|
private HttpStatus status;
|
||||||
|
|
||||||
public HttpComponent4_2Response(CloseableHttpResponse httpResponse) {
|
public HttpComponent4_2Response(CloseableHttpResponse httpResponse,
|
||||||
|
byte[] content) {
|
||||||
|
super(content);
|
||||||
this.httpResponse = httpResponse;
|
this.httpResponse = httpResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ public class HttpComponent4_2Response implements HttpResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HttpStatus getStatus() throws HttpClientException {
|
public HttpStatus getStatus() {
|
||||||
if (status == null) {
|
if (status == null) {
|
||||||
StatusLine statusLine = httpResponse.getStatusLine();
|
StatusLine statusLine = httpResponse.getStatusLine();
|
||||||
status = new HttpStatus(statusLine.getStatusCode(),
|
status = new HttpStatus(statusLine.getStatusCode(),
|
||||||
@ -71,20 +71,10 @@ public class HttpComponent4_2Response implements HttpResponse {
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public InputStream getBody() throws HttpClientException {
|
|
||||||
try {
|
|
||||||
HttpEntity entity = this.httpResponse.getEntity();
|
|
||||||
return (entity != null ? entity.getContent() : null);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new HttpClientException("I/O Error on getBody", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
try {
|
try {
|
||||||
// EntityUtils.consume(httpResponse.getEntity());
|
EntityUtils.consume(httpResponse.getEntity());
|
||||||
httpResponse.close();
|
httpResponse.close();
|
||||||
} catch (IOException ex) {
|
} catch (IOException ex) {
|
||||||
;
|
;
|
||||||
|
|||||||
@ -0,0 +1,223 @@
|
|||||||
|
package com.foxinmy.weixin4j.http.factory;
|
||||||
|
|
||||||
|
import io.netty.bootstrap.Bootstrap;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.ByteBufAllocator;
|
||||||
|
import io.netty.buffer.ByteBufOutputStream;
|
||||||
|
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;
|
||||||
|
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 java.io.IOException;
|
||||||
|
import java.net.InetAddress;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map.Entry;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
import javax.net.ssl.SSLContext;
|
||||||
|
import javax.net.ssl.SSLEngine;
|
||||||
|
|
||||||
|
import com.foxinmy.weixin4j.http.AbstractHttpClient;
|
||||||
|
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.http.entity.HttpEntity;
|
||||||
|
import com.foxinmy.weixin4j.util.SettableFuture;
|
||||||
|
import com.foxinmy.weixin4j.util.StringUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Netty 4.x
|
||||||
|
*
|
||||||
|
* @className Netty4HttpClient
|
||||||
|
* @author jy
|
||||||
|
* @date 2015年8月30日
|
||||||
|
* @since JDK 1.7
|
||||||
|
* @see
|
||||||
|
*/
|
||||||
|
public class Netty4HttpClient extends AbstractHttpClient {
|
||||||
|
|
||||||
|
private final Bootstrap bootstrap;
|
||||||
|
|
||||||
|
public Netty4HttpClient(Bootstrap bootstrap) {
|
||||||
|
this.bootstrap = bootstrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpResponse execute(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
|
||||||
|
public void operationComplete(ChannelFuture channelFuture)
|
||||||
|
throws Exception {
|
||||||
|
if (channelFuture.isSuccess()) {
|
||||||
|
Channel channel = channelFuture.channel();
|
||||||
|
// ssl
|
||||||
|
SSLContext sslContext = null;
|
||||||
|
if (useSSL) {
|
||||||
|
if (params != null
|
||||||
|
&& params.getSSLContext() != null) {
|
||||||
|
sslContext = params.getSSLContext();
|
||||||
|
} else {
|
||||||
|
sslContext = HttpClientFactory
|
||||||
|
.allowSSLContext();
|
||||||
|
}
|
||||||
|
SSLEngine sslEngine = sslContext.createSSLEngine();
|
||||||
|
sslEngine.setUseClientMode(true);
|
||||||
|
channel.pipeline().addFirst(
|
||||||
|
new SslHandler(sslEngine));
|
||||||
|
}
|
||||||
|
channel.pipeline().addLast(new RequestHandler(future));
|
||||||
|
channel.writeAndFlush(uriRequest);
|
||||||
|
} else {
|
||||||
|
future.setException(channelFuture.cause());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
InetSocketAddress address = new InetSocketAddress(
|
||||||
|
InetAddress.getByName(uri.getHost()), getPort(uri));
|
||||||
|
if (useProxy) {
|
||||||
|
address = (InetSocketAddress) params.getProxy().address();
|
||||||
|
}
|
||||||
|
bootstrap.connect(address).syncUninterruptibly()
|
||||||
|
.addListener(listener);
|
||||||
|
response = future.get();
|
||||||
|
handleResponse(response);
|
||||||
|
} catch (IOException | InterruptedException | ExecutionException 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 DefaultHttpRequest createRequest(HttpRequest request)
|
||||||
|
throws IOException {
|
||||||
|
HttpMethod method = HttpMethod.valueOf(request.getMethod().name());
|
||||||
|
URI uri = request.getURI();
|
||||||
|
String url = StringUtil.isBlank(uri.getRawPath()) ? "/" : uri
|
||||||
|
.getRawPath();
|
||||||
|
if (StringUtil.isNotBlank(uri.getRawQuery())) {
|
||||||
|
url += "?" + uri.getRawQuery();
|
||||||
|
}
|
||||||
|
DefaultHttpRequest uriRequest = new DefaultHttpRequest(
|
||||||
|
HttpVersion.HTTP_1_1, method, url);
|
||||||
|
// entity
|
||||||
|
HttpEntity entity = request.getEntity();
|
||||||
|
if (entity != null) {
|
||||||
|
ByteBuf byteBuf = ByteBufAllocator.DEFAULT.buffer();
|
||||||
|
try (ByteBufOutputStream out = new ByteBufOutputStream(byteBuf)) {
|
||||||
|
entity.writeTo(out);
|
||||||
|
}
|
||||||
|
uriRequest = new DefaultFullHttpRequest(
|
||||||
|
uriRequest.getProtocolVersion(), uriRequest.getMethod(),
|
||||||
|
uriRequest.getUri(), byteBuf);
|
||||||
|
if (entity.getContentType() != null) {
|
||||||
|
uriRequest.headers().add(HttpHeaders.CONTENT_TYPE,
|
||||||
|
entity.getContentType().toString());
|
||||||
|
}
|
||||||
|
if (entity.getContentLength() < 0) {
|
||||||
|
uriRequest.headers().add(HttpHeaders.TRANSFER_ENCODING,
|
||||||
|
io.netty.handler.codec.http.HttpHeaders.Values.CHUNKED);
|
||||||
|
} else {
|
||||||
|
uriRequest.headers().add(HttpHeaders.CONTENT_LENGTH,
|
||||||
|
entity.getContentLength());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// header
|
||||||
|
HttpHeaders headers = request.getHeaders();
|
||||||
|
if (headers == null) {
|
||||||
|
headers = new HttpHeaders();
|
||||||
|
}
|
||||||
|
if (!headers.containsKey(HttpHeaders.HOST)) {
|
||||||
|
headers.set(HttpHeaders.HOST, uri.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, "netty/httpclient");
|
||||||
|
}
|
||||||
|
for (Iterator<Entry<String, List<String>>> headerIterator = headers
|
||||||
|
.entrySet().iterator(); headerIterator.hasNext();) {
|
||||||
|
Entry<String, List<String>> header = headerIterator.next();
|
||||||
|
uriRequest.headers().add(header.getKey(), header.getValue());
|
||||||
|
}
|
||||||
|
uriRequest.headers().set(HttpHeaders.CONNECTION,
|
||||||
|
io.netty.handler.codec.http.HttpHeaders.Values.CLOSE);
|
||||||
|
return uriRequest;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getPort(URI uri) {
|
||||||
|
int port = uri.getPort();
|
||||||
|
if (port == -1) {
|
||||||
|
if ("http".equalsIgnoreCase(uri.getScheme())) {
|
||||||
|
port = 80;
|
||||||
|
} else if ("https".equalsIgnoreCase(uri.getScheme())) {
|
||||||
|
port = 443;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class RequestHandler extends
|
||||||
|
SimpleChannelInboundHandler<FullHttpResponse> {
|
||||||
|
|
||||||
|
private final SettableFuture<HttpResponse> future;
|
||||||
|
|
||||||
|
public RequestHandler(SettableFuture<HttpResponse> future) {
|
||||||
|
this.future = future;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void channelRead0(ChannelHandlerContext context,
|
||||||
|
FullHttpResponse response) throws Exception {
|
||||||
|
byte[] content = null;
|
||||||
|
ByteBuf byteBuf = response.content();
|
||||||
|
if (byteBuf.hasArray()) {
|
||||||
|
content = byteBuf.array();
|
||||||
|
} else {
|
||||||
|
content = new byte[byteBuf.readableBytes()];
|
||||||
|
byteBuf.readBytes(content);
|
||||||
|
}
|
||||||
|
future.set(new Netty4HttpResponse(context, response, content));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void exceptionCaught(ChannelHandlerContext context,
|
||||||
|
Throwable cause) throws Exception {
|
||||||
|
future.setException(cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,64 @@
|
|||||||
|
package com.foxinmy.weixin4j.http.factory;
|
||||||
|
|
||||||
|
import io.netty.bootstrap.Bootstrap;
|
||||||
|
import io.netty.channel.ChannelInitializer;
|
||||||
|
import io.netty.channel.ChannelOption;
|
||||||
|
import io.netty.channel.ChannelPipeline;
|
||||||
|
import io.netty.channel.EventLoopGroup;
|
||||||
|
import io.netty.channel.nio.NioEventLoopGroup;
|
||||||
|
import io.netty.channel.socket.SocketChannel;
|
||||||
|
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||||
|
import io.netty.handler.codec.http.HttpClientCodec;
|
||||||
|
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 com.foxinmy.weixin4j.http.HttpClient;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 使用Netty
|
||||||
|
*
|
||||||
|
* @className Netty4HttpClientFactory
|
||||||
|
* @author jy
|
||||||
|
* @date 2015年8月30日
|
||||||
|
* @since JDK 1.7
|
||||||
|
* @see
|
||||||
|
*/
|
||||||
|
public class Netty4HttpClientFactory extends HttpClientFactory {
|
||||||
|
/**
|
||||||
|
* worker线程数,默认设置为cpu的核数 * 4
|
||||||
|
*/
|
||||||
|
private final int workerThreads;
|
||||||
|
|
||||||
|
public Netty4HttpClientFactory() {
|
||||||
|
this(Runtime.getRuntime().availableProcessors() * 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Netty4HttpClientFactory(int workerThreads) {
|
||||||
|
this.workerThreads = workerThreads;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpClient newInstance() {
|
||||||
|
Bootstrap b = new Bootstrap();
|
||||||
|
b.option(ChannelOption.SO_KEEPALIVE, true).option(
|
||||||
|
ChannelOption.TCP_NODELAY, true);
|
||||||
|
EventLoopGroup workerGroup = new NioEventLoopGroup(workerThreads);
|
||||||
|
b.group(workerGroup).channel(NioSocketChannel.class)
|
||||||
|
.handler(new ChannelInitializer<SocketChannel>() {
|
||||||
|
@Override
|
||||||
|
protected void initChannel(SocketChannel channel)
|
||||||
|
throws Exception {
|
||||||
|
ChannelPipeline pipeline = channel.pipeline();
|
||||||
|
pipeline.addLast(new HttpClientCodec());
|
||||||
|
pipeline.addLast(new HttpContentDecompressor());
|
||||||
|
pipeline.addLast(new ChunkedWriteHandler());
|
||||||
|
pipeline.addLast(new HttpResponseDecoder());
|
||||||
|
pipeline.addLast(new HttpObjectAggregator(
|
||||||
|
Integer.MAX_VALUE));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return new Netty4HttpClient(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,78 @@
|
|||||||
|
package com.foxinmy.weixin4j.http.factory;
|
||||||
|
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.handler.codec.http.FullHttpResponse;
|
||||||
|
import io.netty.handler.codec.http.HttpResponseStatus;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.foxinmy.weixin4j.http.AbstractHttpResponse;
|
||||||
|
import com.foxinmy.weixin4j.http.HttpHeaders;
|
||||||
|
import com.foxinmy.weixin4j.http.HttpStatus;
|
||||||
|
import com.foxinmy.weixin4j.http.HttpVersion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Netty Respone::Requires Netty 4.x or higher
|
||||||
|
*
|
||||||
|
* @className Netty4HttpResponse
|
||||||
|
* @author jy
|
||||||
|
* @date 2015年8月30日
|
||||||
|
* @since JDK 1.7
|
||||||
|
* @see
|
||||||
|
*/
|
||||||
|
public class Netty4HttpResponse extends AbstractHttpResponse {
|
||||||
|
|
||||||
|
private final ChannelHandlerContext context;
|
||||||
|
private final FullHttpResponse response;
|
||||||
|
|
||||||
|
private HttpVersion protocol;
|
||||||
|
private HttpStatus status;
|
||||||
|
private volatile HttpHeaders headers;
|
||||||
|
|
||||||
|
public Netty4HttpResponse(ChannelHandlerContext context,
|
||||||
|
FullHttpResponse response, byte[] content) {
|
||||||
|
super(content);
|
||||||
|
this.context = context;
|
||||||
|
this.response = response;
|
||||||
|
this.response.retain();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpHeaders getHeaders() {
|
||||||
|
if (this.headers == null) {
|
||||||
|
HttpHeaders headers = new HttpHeaders();
|
||||||
|
for (Map.Entry<String, String> entry : this.response.headers()) {
|
||||||
|
headers.add(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
this.headers = headers;
|
||||||
|
}
|
||||||
|
return this.headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpVersion getProtocol() {
|
||||||
|
if (protocol == null) {
|
||||||
|
io.netty.handler.codec.http.HttpVersion version = response
|
||||||
|
.getProtocolVersion();
|
||||||
|
this.protocol = new HttpVersion(version.protocolName(),
|
||||||
|
version.majorVersion(), version.majorVersion(),
|
||||||
|
version.isKeepAliveDefault());
|
||||||
|
}
|
||||||
|
return protocol;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HttpStatus getStatus() {
|
||||||
|
if (status == null) {
|
||||||
|
HttpResponseStatus status = response.getStatus();
|
||||||
|
this.status = new HttpStatus(status.code(), status.reasonPhrase());
|
||||||
|
}
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void close() {
|
||||||
|
this.response.release();
|
||||||
|
this.context.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -20,6 +20,7 @@ import com.foxinmy.weixin4j.http.entity.FormUrlEntity;
|
|||||||
import com.foxinmy.weixin4j.http.entity.HttpEntity;
|
import com.foxinmy.weixin4j.http.entity.HttpEntity;
|
||||||
import com.foxinmy.weixin4j.http.entity.StringEntity;
|
import com.foxinmy.weixin4j.http.entity.StringEntity;
|
||||||
import com.foxinmy.weixin4j.http.factory.HttpClientFactory;
|
import com.foxinmy.weixin4j.http.factory.HttpClientFactory;
|
||||||
|
import com.foxinmy.weixin4j.http.factory.Netty4HttpClientFactory;
|
||||||
import com.foxinmy.weixin4j.model.Consts;
|
import com.foxinmy.weixin4j.model.Consts;
|
||||||
import com.foxinmy.weixin4j.util.StringUtil;
|
import com.foxinmy.weixin4j.util.StringUtil;
|
||||||
import com.foxinmy.weixin4j.util.WeixinErrorUtil;
|
import com.foxinmy.weixin4j.util.WeixinErrorUtil;
|
||||||
@ -44,6 +45,7 @@ public class WeixinRequestExecutor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public WeixinRequestExecutor(HttpParams params) {
|
public WeixinRequestExecutor(HttpParams params) {
|
||||||
|
HttpClientFactory.setDefaultFactory(new Netty4HttpClientFactory());
|
||||||
this.httpClient = HttpClientFactory.getInstance();
|
this.httpClient = HttpClientFactory.getInstance();
|
||||||
this.params = params;
|
this.params = params;
|
||||||
}
|
}
|
||||||
@ -97,10 +99,6 @@ public class WeixinRequestExecutor {
|
|||||||
HttpResponse httpResponse = httpClient.execute(request);
|
HttpResponse httpResponse = httpClient.execute(request);
|
||||||
HttpStatus status = httpResponse.getStatus();
|
HttpStatus status = httpResponse.getStatus();
|
||||||
HttpHeaders headers = httpResponse.getHeaders();
|
HttpHeaders headers = httpResponse.getHeaders();
|
||||||
if (status.getStatusCode() >= HttpStatus.SC_MULTIPLE_CHOICES) {
|
|
||||||
throw new WeixinException(String.format("request fail : %d-%s",
|
|
||||||
status.getStatusCode(), status.getStatusText()));
|
|
||||||
}
|
|
||||||
WeixinResponse response = new WeixinResponse(headers, status,
|
WeixinResponse response = new WeixinResponse(headers, status,
|
||||||
httpResponse.getBody());
|
httpResponse.getBody());
|
||||||
String contentType = headers.getFirst(HttpHeaders.CONTENT_TYPE);
|
String contentType = headers.getFirst(HttpHeaders.CONTENT_TYPE);
|
||||||
|
|||||||
@ -42,6 +42,7 @@ public class WeixinResponse {
|
|||||||
try {
|
try {
|
||||||
text = StringUtil.newStringUtf8(IOUtil.toByteArray(body));
|
text = StringUtil.newStringUtf8(IOUtil.toByteArray(body));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -0,0 +1,191 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2002-2014 the original author or authors.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.foxinmy.weixin4j.util;
|
||||||
|
|
||||||
|
import java.util.concurrent.Callable;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.Future;
|
||||||
|
import java.util.concurrent.FutureTask;
|
||||||
|
import java.util.concurrent.TimeUnit;
|
||||||
|
import java.util.concurrent.TimeoutException;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A {@link org.springframework.util.concurrent.ListenableFuture
|
||||||
|
* ListenableFuture} whose value can be set via {@link #set(Object)} or
|
||||||
|
* {@link #setException(Throwable)}. It may also be cancelled.
|
||||||
|
*
|
||||||
|
* <p>
|
||||||
|
* Inspired by {@code com.google.common.util.concurrent.SettableFuture}.
|
||||||
|
*
|
||||||
|
* @author Mattias Severson
|
||||||
|
* @author Rossen Stoyanchev
|
||||||
|
* @since 4.1
|
||||||
|
*/
|
||||||
|
public class SettableFuture<T> implements Future<T> {
|
||||||
|
|
||||||
|
private final SettableTask<T> settableTask;
|
||||||
|
|
||||||
|
private final FutureTask<T> futureTask;
|
||||||
|
|
||||||
|
public SettableFuture() {
|
||||||
|
this.settableTask = new SettableTask<T>();
|
||||||
|
this.futureTask = new FutureTask<T>(this.settableTask);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of this future. This method will return {@code true} if the
|
||||||
|
* value was set successfully, or {@code false} if the future has already
|
||||||
|
* been set or cancelled.
|
||||||
|
*
|
||||||
|
* @param value
|
||||||
|
* the value that will be set.
|
||||||
|
* @return {@code true} if the value was successfully set, else
|
||||||
|
* {@code false}.
|
||||||
|
*/
|
||||||
|
public boolean set(T value) {
|
||||||
|
boolean success = this.settableTask.setValue(value);
|
||||||
|
if (success) {
|
||||||
|
this.futureTask.run();
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the exception of this future. This method will return {@code true} if
|
||||||
|
* the exception was set successfully, or {@code false} if the future has
|
||||||
|
* already been set or cancelled.
|
||||||
|
*
|
||||||
|
* @param exception
|
||||||
|
* the value that will be set.
|
||||||
|
* @return {@code true} if the exception was successfully set, else
|
||||||
|
* {@code false}.
|
||||||
|
*/
|
||||||
|
public boolean setException(Throwable exception) {
|
||||||
|
boolean success = this.settableTask.setException(exception);
|
||||||
|
if (success) {
|
||||||
|
this.futureTask.run();
|
||||||
|
}
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean cancel(boolean mayInterruptIfRunning) {
|
||||||
|
this.settableTask.setCancelled();
|
||||||
|
boolean cancelled = this.futureTask.cancel(mayInterruptIfRunning);
|
||||||
|
if (cancelled && mayInterruptIfRunning) {
|
||||||
|
interruptTask();
|
||||||
|
}
|
||||||
|
return cancelled;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isCancelled() {
|
||||||
|
return this.futureTask.isCancelled();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDone() {
|
||||||
|
return this.futureTask.isDone();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the value.
|
||||||
|
* <p>
|
||||||
|
* Will return the value if it has been set via {@link #set(Object)}, throw
|
||||||
|
* an {@link java.util.concurrent.ExecutionException} if it has been set via
|
||||||
|
* {@link #setException(Throwable)} or throw a
|
||||||
|
* {@link java.util.concurrent.CancellationException} if it has been
|
||||||
|
* cancelled.
|
||||||
|
*
|
||||||
|
* @return The value associated with this future.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public T get() throws InterruptedException, ExecutionException {
|
||||||
|
return this.futureTask.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the value.
|
||||||
|
* <p>
|
||||||
|
* Will return the value if it has been set via {@link #set(Object)}, throw
|
||||||
|
* an {@link java.util.concurrent.ExecutionException} if it has been set via
|
||||||
|
* {@link #setException(Throwable)} or throw a
|
||||||
|
* {@link java.util.concurrent.CancellationException} if it has been
|
||||||
|
* cancelled.
|
||||||
|
*
|
||||||
|
* @param timeout
|
||||||
|
* the maximum time to wait.
|
||||||
|
* @param unit
|
||||||
|
* the time unit of the timeout argument.
|
||||||
|
* @return The value associated with this future.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public T get(long timeout, TimeUnit unit) throws InterruptedException,
|
||||||
|
ExecutionException, TimeoutException {
|
||||||
|
return this.futureTask.get(timeout, unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Subclasses can override this method to implement interruption of the
|
||||||
|
* future's computation. The method is invoked automatically by a successful
|
||||||
|
* call to {@link #cancel(boolean) cancel(true)}.
|
||||||
|
* <p>
|
||||||
|
* The default implementation does nothing.
|
||||||
|
*/
|
||||||
|
protected void interruptTask() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class SettableTask<T> implements Callable<T> {
|
||||||
|
|
||||||
|
private static final String NO_VALUE = SettableFuture.class
|
||||||
|
.getName() + ".NO_VALUE";
|
||||||
|
|
||||||
|
private final AtomicReference<Object> value = new AtomicReference<Object>(
|
||||||
|
NO_VALUE);
|
||||||
|
|
||||||
|
private volatile boolean cancelled = false;
|
||||||
|
|
||||||
|
public boolean setValue(T value) {
|
||||||
|
if (this.cancelled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return this.value.compareAndSet(NO_VALUE, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean setException(Throwable exception) {
|
||||||
|
if (this.cancelled) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return this.value.compareAndSet(NO_VALUE, exception);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCancelled() {
|
||||||
|
this.cancelled = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
@Override
|
||||||
|
public T call() throws Exception {
|
||||||
|
if (value.get() instanceof Exception) {
|
||||||
|
throw (Exception) value.get();
|
||||||
|
}
|
||||||
|
return (T) value.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -1,6 +1,9 @@
|
|||||||
package com.foxinmy.weixin4j.base.test;
|
package com.foxinmy.weixin4j.base.test;
|
||||||
|
|
||||||
import org.apache.commons.httpclient.methods.GetMethod;
|
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.HttpClient;
|
||||||
import com.foxinmy.weixin4j.http.HttpClientException;
|
import com.foxinmy.weixin4j.http.HttpClientException;
|
||||||
@ -11,11 +14,7 @@ import com.foxinmy.weixin4j.http.HttpResponse;
|
|||||||
import com.foxinmy.weixin4j.http.factory.HttpClientFactory;
|
import com.foxinmy.weixin4j.http.factory.HttpClientFactory;
|
||||||
import com.foxinmy.weixin4j.http.factory.HttpComponent3Factory;
|
import com.foxinmy.weixin4j.http.factory.HttpComponent3Factory;
|
||||||
import com.foxinmy.weixin4j.http.factory.HttpComponent4Factory;
|
import com.foxinmy.weixin4j.http.factory.HttpComponent4Factory;
|
||||||
import com.foxinmy.weixin4j.http.factory.SimpleHttpClientFactory;
|
import com.foxinmy.weixin4j.util.IOUtil;
|
||||||
import com.foxinmy.weixin4j.model.WeixinAccount;
|
|
||||||
import com.foxinmy.weixin4j.token.FileTokenStorager;
|
|
||||||
import com.foxinmy.weixin4j.token.TokenHolder;
|
|
||||||
import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
|
|
||||||
|
|
||||||
public class HttpClientTest {
|
public class HttpClientTest {
|
||||||
|
|
||||||
@ -23,13 +22,12 @@ public class HttpClientTest {
|
|||||||
"https://www.baidu.com");
|
"https://www.baidu.com");
|
||||||
static {
|
static {
|
||||||
HttpParams params = new HttpParams();
|
HttpParams params = new HttpParams();
|
||||||
//params.setProxy(new Proxy(Type.HTTP, new InetSocketAddress(
|
params.setProxy(new Proxy(Type.HTTP, new InetSocketAddress(
|
||||||
// "218.92.227.170", 11095)));
|
"117.136.234.9", 80)));
|
||||||
request.setParams(params);
|
request.setParams(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void test1() throws HttpClientException {
|
public static void test1() throws HttpClientException {
|
||||||
HttpClientFactory.setDefaultFactory(new SimpleHttpClientFactory());
|
|
||||||
HttpClient httpClient = HttpClientFactory.getInstance();
|
HttpClient httpClient = HttpClientFactory.getInstance();
|
||||||
HttpResponse response = httpClient.execute(request);
|
HttpResponse response = httpClient.execute(request);
|
||||||
print(response);
|
print(response);
|
||||||
@ -51,28 +49,23 @@ public class HttpClientTest {
|
|||||||
|
|
||||||
public static void print(HttpResponse response) throws HttpClientException {
|
public static void print(HttpResponse response) throws HttpClientException {
|
||||||
System.err.println(response.getStatus());
|
System.err.println(response.getStatus());
|
||||||
System.err.println(response.getBody());
|
try {
|
||||||
|
System.err.println(new String(
|
||||||
|
IOUtil.toByteArray(response.getBody())));
|
||||||
|
} catch (IOException e) {
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
System.err.println(response.getHeaders());
|
System.err.println(response.getHeaders());
|
||||||
System.err.println(response.getProtocol());
|
System.err.println(response.getProtocol());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void test() {
|
|
||||||
org.apache.commons.httpclient.HttpClient hc = new org.apache.commons.httpclient.HttpClient();
|
|
||||||
hc.getHostConfiguration().setProxy("127.0.0.1", 1080);
|
|
||||||
org.apache.commons.httpclient.HttpMethod hm = new GetMethod(
|
|
||||||
"http://www.baidu.com");
|
|
||||||
try {
|
|
||||||
hc.executeMethod(hm);
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
//test1();
|
test1();
|
||||||
System.out.println("---------------------");
|
System.out.println("---------------------");
|
||||||
//test2();
|
// test2();
|
||||||
System.out.println("---------------------");
|
System.out.println("---------------------");
|
||||||
//test3();
|
// test3();
|
||||||
|
// test4();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -149,3 +149,7 @@
|
|||||||
+ version upgrade to 1.5.3
|
+ version upgrade to 1.5.3
|
||||||
|
|
||||||
+ 媒体接口类(MediaApi)查询素材接口调整:去掉offset,count替换为Pageable类
|
+ 媒体接口类(MediaApi)查询素材接口调整:去掉offset,count替换为Pageable类
|
||||||
|
|
||||||
|
* 2015-09-08
|
||||||
|
|
||||||
|
+ 新增批量获取用户信息接口
|
||||||
@ -1,5 +1,6 @@
|
|||||||
package com.foxinmy.weixin4j.mp.type;
|
package com.foxinmy.weixin4j.mp.type;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 国家地区语言版本
|
* 国家地区语言版本
|
||||||
* @className Lang
|
* @className Lang
|
||||||
|
|||||||
@ -54,7 +54,7 @@ base on netty.
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
// 当消息类型为文本(text)时回复「HelloWorld」, 否则回复调试消息
|
// 当消息类型为文本(text)时回复「HelloWorld」, 否则回复调试消息
|
||||||
new WeixinServerBootstrap(token,appid, aesKey).addHandler(
|
new WeixinServerBootstrap(token, appid, aesKey).addHandler(
|
||||||
messageHandler, DebugMessageHandler.global).startup();
|
messageHandler, DebugMessageHandler.global).startup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -47,7 +47,7 @@ public class ScanEventMessage extends EventMessage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getParameter() {
|
public String getParameter() {
|
||||||
return eventKey.replace("qrscene_", "");
|
return eventKey.replaceFirst("qrscene_", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user