@@ -3,8 +3,9 @@ package me.chanjar.weixin.common.util.http; | |||
import java.io.IOException; | |||
import me.chanjar.weixin.common.WxType; | |||
import me.chanjar.weixin.common.error.WxError; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientSimpleGetRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.apache.ApacheSimpleGetRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.jodd.JoddHttpSimpleGetRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.okhttp.OkHttpSimpleGetRequestExecutor; | |||
@@ -29,7 +30,7 @@ public abstract class SimpleGetRequestExecutor<H, P> implements RequestExecutor< | |||
public static RequestExecutor<String, String> create(RequestHttp requestHttp) { | |||
switch (requestHttp.getRequestType()) { | |||
case APACHE_HTTP: | |||
return new ApacheHttpClientSimpleGetRequestExecutor(requestHttp); | |||
return new ApacheSimpleGetRequestExecutor(requestHttp); | |||
case JODD_HTTP: | |||
return new JoddHttpSimpleGetRequestExecutor(requestHttp); | |||
case OK_HTTP: | |||
@@ -39,4 +40,12 @@ public abstract class SimpleGetRequestExecutor<H, P> implements RequestExecutor< | |||
} | |||
} | |||
protected String handleResponse(WxType wxType, String responseContent) throws WxErrorException { | |||
WxError error = WxError.fromJson(responseContent, wxType); | |||
if (error.getErrorCode() != 0) { | |||
throw new WxErrorException(error); | |||
} | |||
return responseContent; | |||
} | |||
} |
@@ -1,10 +1,12 @@ | |||
package me.chanjar.weixin.common.util.http; | |||
import me.chanjar.weixin.common.WxType; | |||
import me.chanjar.weixin.common.error.WxError; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.common.util.http.apache.ApacheSimplePostRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.jodd.JoddHttpSimplePostRequestExecutor; | |||
import me.chanjar.weixin.common.util.http.okhttp.OkHttpSimplePostRequestExecutor; | |||
import org.jetbrains.annotations.NotNull; | |||
import java.io.IOException; | |||
@@ -39,4 +41,21 @@ public abstract class SimplePostRequestExecutor<H, P> implements RequestExecutor | |||
} | |||
} | |||
@NotNull | |||
public String handleResponse(WxType wxType, String responseContent) throws WxErrorException { | |||
if (responseContent.isEmpty()) { | |||
throw new WxErrorException(WxError.builder().errorCode(9999).errorMsg("无响应内容").build()); | |||
} | |||
if (responseContent.startsWith("<xml>")) { | |||
//xml格式输出直接返回 | |||
return responseContent; | |||
} | |||
WxError error = WxError.fromJson(responseContent, wxType); | |||
if (error.getErrorCode() != 0) { | |||
throw new WxErrorException(error); | |||
} | |||
return responseContent; | |||
} | |||
} |
@@ -19,8 +19,8 @@ import java.io.IOException; | |||
* @author ecoolper | |||
* @date 2017/5/4 | |||
*/ | |||
public class ApacheHttpClientSimpleGetRequestExecutor extends SimpleGetRequestExecutor<CloseableHttpClient, HttpHost> { | |||
public ApacheHttpClientSimpleGetRequestExecutor(RequestHttp requestHttp) { | |||
public class ApacheSimpleGetRequestExecutor extends SimpleGetRequestExecutor<CloseableHttpClient, HttpHost> { | |||
public ApacheSimpleGetRequestExecutor(RequestHttp requestHttp) { | |||
super(requestHttp); | |||
} | |||
@@ -40,11 +40,7 @@ public class ApacheHttpClientSimpleGetRequestExecutor extends SimpleGetRequestEx | |||
try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpGet)) { | |||
String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); | |||
WxError error = WxError.fromJson(responseContent, wxType); | |||
if (error.getErrorCode() != 0) { | |||
throw new WxErrorException(error); | |||
} | |||
return responseContent; | |||
return handleResponse(wxType, responseContent); | |||
} finally { | |||
httpGet.releaseConnection(); | |||
} |
@@ -12,6 +12,7 @@ import org.apache.http.client.methods.CloseableHttpResponse; | |||
import org.apache.http.client.methods.HttpPost; | |||
import org.apache.http.entity.StringEntity; | |||
import org.apache.http.impl.client.CloseableHttpClient; | |||
import org.jetbrains.annotations.NotNull; | |||
import java.io.IOException; | |||
@@ -42,22 +43,10 @@ public class ApacheSimplePostRequestExecutor extends SimplePostRequestExecutor<C | |||
try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) { | |||
String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); | |||
if (responseContent.isEmpty()) { | |||
throw new WxErrorException(WxError.builder().errorCode(9999).errorMsg("无响应内容").build()); | |||
} | |||
if (responseContent.startsWith("<xml>")) { | |||
//xml格式输出直接返回 | |||
return responseContent; | |||
} | |||
WxError error = WxError.fromJson(responseContent, wxType); | |||
if (error.getErrorCode() != 0) { | |||
throw new WxErrorException(error); | |||
} | |||
return responseContent; | |||
return this.handleResponse(wxType, responseContent); | |||
} finally { | |||
httpPost.releaseConnection(); | |||
} | |||
} | |||
} |
@@ -1,5 +1,7 @@ | |||
package me.chanjar.weixin.common.util.http.apache; | |||
import lombok.Data; | |||
import lombok.extern.slf4j.Slf4j; | |||
import org.apache.commons.lang3.StringUtils; | |||
import org.apache.http.HttpHost; | |||
import org.apache.http.annotation.NotThreadSafe; | |||
@@ -23,8 +25,6 @@ import org.apache.http.impl.client.HttpClients; | |||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; | |||
import org.apache.http.protocol.HttpContext; | |||
import org.apache.http.ssl.SSLContexts; | |||
import org.slf4j.Logger; | |||
import org.slf4j.LoggerFactory; | |||
import javax.net.ssl.SSLContext; | |||
import java.io.IOException; | |||
@@ -41,26 +41,65 @@ import java.util.concurrent.atomic.AtomicBoolean; | |||
* | |||
* @author kakotor | |||
*/ | |||
@Slf4j | |||
@Data | |||
@NotThreadSafe | |||
public class DefaultApacheHttpClientBuilder implements ApacheHttpClientBuilder { | |||
protected final Logger log = LoggerFactory.getLogger(DefaultApacheHttpClientBuilder.class); | |||
private final AtomicBoolean prepared = new AtomicBoolean(false); | |||
/** | |||
* 获取链接的超时时间设置 | |||
* <p> | |||
* 设置为零时不超时,一直等待. | |||
* 设置为负数是使用系统默认设置(非3000ms的默认值,而是httpClient的默认设置). | |||
* </p> | |||
*/ | |||
private int connectionRequestTimeout = -1; | |||
/** | |||
* 建立链接的超时时间,默认为5000ms.由于是在链接池获取链接,此设置应该并不起什么作用 | |||
* <p> | |||
* 设置为零时不超时,一直等待. | |||
* 设置为负数是使用系统默认设置(非上述的5000ms的默认值,而是httpclient的默认设置). | |||
* </p> | |||
*/ | |||
private int connectionTimeout = 5000; | |||
/** | |||
* 默认NIO的socket超时设置,默认5000ms. | |||
*/ | |||
private int soTimeout = 5000; | |||
/** | |||
* 空闲链接的超时时间,默认60000ms. | |||
* <p> | |||
* 超时的链接将在下一次空闲链接检查是被销毁 | |||
* </p> | |||
*/ | |||
private int idleConnTimeout = 60000; | |||
/** | |||
* 检查空间链接的间隔周期,默认60000ms. | |||
*/ | |||
private int checkWaitTime = 60000; | |||
/** | |||
* 每路的最大链接数,默认10 | |||
*/ | |||
private int maxConnPerHost = 10; | |||
/** | |||
* 最大总连接数,默认50 | |||
*/ | |||
private int maxTotalConn = 50; | |||
/** | |||
* 自定义httpclient的User Agent | |||
*/ | |||
private String userAgent; | |||
private HttpRequestRetryHandler httpRequestRetryHandler = new HttpRequestRetryHandler() { | |||
private final HttpRequestRetryHandler httpRequestRetryHandler = new HttpRequestRetryHandler() { | |||
@Override | |||
public boolean retryRequest(IOException exception, int executionCount, HttpContext context) { | |||
return false; | |||
} | |||
}; | |||
private SSLConnectionSocketFactory sslConnectionSocketFactory = SSLConnectionSocketFactory.getSocketFactory(); | |||
private PlainConnectionSocketFactory plainConnectionSocketFactory = PlainConnectionSocketFactory.getSocketFactory(); | |||
private final PlainConnectionSocketFactory plainConnectionSocketFactory = PlainConnectionSocketFactory.getSocketFactory(); | |||
private String httpProxyHost; | |||
private int httpProxyPort; | |||
private String httpProxyUsername; | |||
@@ -111,90 +150,6 @@ public class DefaultApacheHttpClientBuilder implements ApacheHttpClientBuilder { | |||
return this; | |||
} | |||
/** | |||
* 获取链接的超时时间设置,默认3000ms | |||
* <p> | |||
* 设置为零时不超时,一直等待. | |||
* 设置为负数是使用系统默认设置(非上述的3000ms的默认值,而是httpclient的默认设置). | |||
* </p> | |||
* | |||
* @param connectionRequestTimeout 获取链接的超时时间设置(单位毫秒),默认3000ms | |||
*/ | |||
public void setConnectionRequestTimeout(int connectionRequestTimeout) { | |||
this.connectionRequestTimeout = connectionRequestTimeout; | |||
} | |||
/** | |||
* 建立链接的超时时间,默认为5000ms.由于是在链接池获取链接,此设置应该并不起什么作用 | |||
* <p> | |||
* 设置为零时不超时,一直等待. | |||
* 设置为负数是使用系统默认设置(非上述的5000ms的默认值,而是httpclient的默认设置). | |||
* </p> | |||
* | |||
* @param connectionTimeout 建立链接的超时时间设置(单位毫秒),默认5000ms | |||
*/ | |||
public void setConnectionTimeout(int connectionTimeout) { | |||
this.connectionTimeout = connectionTimeout; | |||
} | |||
/** | |||
* 默认NIO的socket超时设置,默认5000ms. | |||
* | |||
* @param soTimeout 默认NIO的socket超时设置,默认5000ms. | |||
* @see java.net.SocketOptions#SO_TIMEOUT | |||
*/ | |||
public void setSoTimeout(int soTimeout) { | |||
this.soTimeout = soTimeout; | |||
} | |||
/** | |||
* 空闲链接的超时时间,默认60000ms. | |||
* <p> | |||
* 超时的链接将在下一次空闲链接检查是被销毁 | |||
* </p> | |||
* | |||
* @param idleConnTimeout 空闲链接的超时时间,默认60000ms. | |||
*/ | |||
public void setIdleConnTimeout(int idleConnTimeout) { | |||
this.idleConnTimeout = idleConnTimeout; | |||
} | |||
/** | |||
* 检查空间链接的间隔周期,默认60000ms. | |||
* | |||
* @param checkWaitTime 检查空间链接的间隔周期,默认60000ms. | |||
*/ | |||
public void setCheckWaitTime(int checkWaitTime) { | |||
this.checkWaitTime = checkWaitTime; | |||
} | |||
/** | |||
* 每路的最大链接数,默认10 | |||
* | |||
* @param maxConnPerHost 每路的最大链接数,默认10 | |||
*/ | |||
public void setMaxConnPerHost(int maxConnPerHost) { | |||
this.maxConnPerHost = maxConnPerHost; | |||
} | |||
/** | |||
* 最大总连接数,默认50 | |||
* | |||
* @param maxTotalConn 最大总连接数,默认50 | |||
*/ | |||
public void setMaxTotalConn(int maxTotalConn) { | |||
this.maxTotalConn = maxTotalConn; | |||
} | |||
/** | |||
* 自定义httpclient的User Agent | |||
* | |||
* @param userAgent User Agent | |||
*/ | |||
public void setUserAgent(String userAgent) { | |||
this.userAgent = userAgent; | |||
} | |||
public IdleConnectionMonitorThread getIdleConnectionMonitorThread() { | |||
return this.idleConnectionMonitorThread; | |||
} | |||
@@ -268,7 +223,7 @@ public class DefaultApacheHttpClientBuilder implements ApacheHttpClientBuilder { | |||
null, | |||
SSLConnectionSocketFactory.getDefaultHostnameVerifier()); | |||
} catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) { | |||
this.log.error(e.getMessage(), e); | |||
log.error("构建SSL连接工厂时发生异常!", e); | |||
} | |||
return null; | |||
@@ -41,13 +41,7 @@ public class JoddHttpSimpleGetRequestExecutor extends SimpleGetRequestExecutor<H | |||
HttpResponse response = request.send(); | |||
response.charset(StringPool.UTF_8); | |||
String responseContent = response.bodyText(); | |||
WxError error = WxError.fromJson(responseContent, wxType); | |||
if (error.getErrorCode() != 0) { | |||
throw new WxErrorException(error); | |||
} | |||
return responseContent; | |||
return handleResponse(wxType, response.bodyText()); | |||
} | |||
} |
@@ -6,7 +6,6 @@ import jodd.http.HttpResponse; | |||
import jodd.http.ProxyInfo; | |||
import jodd.util.StringPool; | |||
import me.chanjar.weixin.common.WxType; | |||
import me.chanjar.weixin.common.error.WxError; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.common.util.http.RequestHttp; | |||
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; | |||
@@ -40,21 +39,7 @@ public class JoddHttpSimplePostRequestExecutor extends SimplePostRequestExecutor | |||
HttpResponse response = request.send(); | |||
response.charset(StringPool.UTF_8); | |||
String responseContent = response.bodyText(); | |||
if (responseContent.isEmpty()) { | |||
throw new WxErrorException(WxError.builder().errorCode(9999).errorMsg("无响应内容").build()); | |||
} | |||
if (responseContent.startsWith("<xml>")) { | |||
//xml格式输出直接返回 | |||
return responseContent; | |||
} | |||
WxError error = WxError.fromJson(responseContent, wxType); | |||
if (error.getErrorCode() != 0) { | |||
throw new WxErrorException(error); | |||
} | |||
return responseContent; | |||
return this.handleResponse(wxType, response.bodyText()); | |||
} | |||
} |
@@ -35,12 +35,7 @@ public class OkHttpSimpleGetRequestExecutor extends SimpleGetRequestExecutor<OkH | |||
OkHttpClient client = requestHttp.getRequestHttpClient(); | |||
Request request = new Request.Builder().url(uri).build(); | |||
Response response = client.newCall(request).execute(); | |||
String responseContent = response.body().string(); | |||
WxError error = WxError.fromJson(responseContent, wxType); | |||
if (error.getErrorCode() != 0) { | |||
throw new WxErrorException(error); | |||
} | |||
return responseContent; | |||
return this.handleResponse(wxType, response.body().string()); | |||
} | |||
} |
@@ -2,13 +2,13 @@ package me.chanjar.weixin.common.util.http.okhttp; | |||
import lombok.extern.slf4j.Slf4j; | |||
import me.chanjar.weixin.common.WxType; | |||
import me.chanjar.weixin.common.error.WxError; | |||
import me.chanjar.weixin.common.error.WxErrorException; | |||
import me.chanjar.weixin.common.util.http.RequestHttp; | |||
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor; | |||
import okhttp3.*; | |||
import java.io.IOException; | |||
import java.util.Objects; | |||
/** | |||
* . | |||
@@ -24,16 +24,10 @@ public class OkHttpSimplePostRequestExecutor extends SimplePostRequestExecutor<O | |||
@Override | |||
public String execute(String uri, String postEntity, WxType wxType) throws WxErrorException, IOException { | |||
RequestBody body = RequestBody.create(MediaType.parse("text/plain; charset=utf-8"), postEntity); | |||
RequestBody body = RequestBody.Companion.create(postEntity, MediaType.parse("text/plain; charset=utf-8")); | |||
Request request = new Request.Builder().url(uri).post(body).build(); | |||
Response response = requestHttp.getRequestHttpClient().newCall(request).execute(); | |||
String responseContent = response.body().string(); | |||
WxError error = WxError.fromJson(responseContent, wxType); | |||
if (error.getErrorCode() != 0) { | |||
throw new WxErrorException(error); | |||
} | |||
return responseContent; | |||
return this.handleResponse(wxType, Objects.requireNonNull(response.body()).string()); | |||
} | |||
} |
@@ -10,6 +10,7 @@ import lombok.Getter; | |||
import lombok.Setter; | |||
import lombok.extern.slf4j.Slf4j; | |||
import me.chanjar.weixin.common.WxType; | |||
import me.chanjar.weixin.common.bean.WxAccessToken; | |||
import me.chanjar.weixin.common.bean.WxJsapiSignature; | |||
import me.chanjar.weixin.common.bean.WxNetCheckResult; | |||
import me.chanjar.weixin.common.enums.TicketType; | |||
@@ -400,6 +401,17 @@ public abstract class BaseWxMpServiceImpl<H, P> implements WxMpService, RequestH | |||
return this.configStorageMap.get(WxMpConfigStorageHolder.get()); | |||
} | |||
protected String extractAccessToken(String resultContent) throws WxErrorException { | |||
WxMpConfigStorage config = this.getWxMpConfigStorage(); | |||
WxError error = WxError.fromJson(resultContent, WxType.MP); | |||
if (error.getErrorCode() != 0) { | |||
throw new WxErrorException(error); | |||
} | |||
WxAccessToken accessToken = WxAccessToken.fromJson(resultContent); | |||
config.updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); | |||
return config.getAccessToken(); | |||
} | |||
@Override | |||
public void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider) { | |||
final String defaultMpId = WxMpConfigStorageHolder.get(); | |||
@@ -85,14 +85,7 @@ public class WxMpServiceHttpClientImpl extends BaseWxMpServiceImpl<CloseableHttp | |||
httpGet.setConfig(requestConfig); | |||
} | |||
try (CloseableHttpResponse response = getRequestHttpClient().execute(httpGet)) { | |||
String resultContent = new BasicResponseHandler().handleResponse(response); | |||
WxError error = WxError.fromJson(resultContent, WxType.MP); | |||
if (error.getErrorCode() != 0) { | |||
throw new WxErrorException(error); | |||
} | |||
WxAccessToken accessToken = WxAccessToken.fromJson(resultContent); | |||
config.updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); | |||
return config.getAccessToken(); | |||
return this.extractAccessToken(new BasicResponseHandler().handleResponse(response)); | |||
} finally { | |||
httpGet.releaseConnection(); | |||
} | |||
@@ -103,4 +96,5 @@ public class WxMpServiceHttpClientImpl extends BaseWxMpServiceImpl<CloseableHttp | |||
lock.unlock(); | |||
} | |||
} | |||
} |
@@ -65,23 +65,14 @@ public class WxMpServiceJoddHttpImpl extends BaseWxMpServiceImpl<HttpConnectionP | |||
String url = String.format(GET_ACCESS_TOKEN_URL.getUrl(config), config.getAppId(), config.getSecret()); | |||
HttpRequest request = HttpRequest.get(url); | |||
if (this.getRequestHttpProxy() != null) { | |||
SocketHttpConnectionProvider provider = new SocketHttpConnectionProvider(); | |||
provider.useProxy(getRequestHttpProxy()); | |||
request.withConnectionProvider(provider); | |||
} | |||
HttpResponse response = request.send(); | |||
String resultContent = response.bodyText(); | |||
WxError error = WxError.fromJson(resultContent, WxType.MP); | |||
if (error.getErrorCode() != 0) { | |||
throw new WxErrorException(error); | |||
} | |||
WxAccessToken accessToken = WxAccessToken.fromJson(resultContent); | |||
config.updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); | |||
return config.getAccessToken(); | |||
return this.extractAccessToken(request.send().bodyText()); | |||
} finally { | |||
lock.unlock(); | |||
} | |||
@@ -10,6 +10,7 @@ import me.chanjar.weixin.mp.config.WxMpConfigStorage; | |||
import okhttp3.*; | |||
import java.io.IOException; | |||
import java.util.Objects; | |||
import java.util.concurrent.locks.Lock; | |||
import static me.chanjar.weixin.mp.enums.WxMpApiUrl.Other.GET_ACCESS_TOKEN_URL; | |||
@@ -55,15 +56,7 @@ public class WxMpServiceOkHttpImpl extends BaseWxMpServiceImpl<OkHttpClient, OkH | |||
Request request = new Request.Builder().url(url).get().build(); | |||
Response response = getRequestHttpClient().newCall(request).execute(); | |||
String resultContent = response.body().string(); | |||
WxError error = WxError.fromJson(resultContent, WxType.MP); | |||
if (error.getErrorCode() != 0) { | |||
throw new WxErrorException(error); | |||
} | |||
WxAccessToken accessToken = WxAccessToken.fromJson(resultContent); | |||
config.updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); | |||
return config.getAccessToken(); | |||
return this.extractAccessToken(Objects.requireNonNull(response.body()).string()); | |||
} catch (IOException e) { | |||
throw new RuntimeException(e); | |||
} finally { | |||