{
/**
*
* 创建门店
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java
index 2e6bf88e5..9e64d0431 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpCardServiceImpl.java
@@ -1,17 +1,10 @@
package me.chanjar.weixin.mp.api.impl;
-import java.util.Arrays;
-import java.util.concurrent.locks.Lock;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive;
import com.google.gson.reflect.TypeToken;
-
import me.chanjar.weixin.common.bean.WxCardApiSignature;
import me.chanjar.weixin.common.bean.result.WxError;
import me.chanjar.weixin.common.exception.WxErrorException;
@@ -22,11 +15,18 @@ import me.chanjar.weixin.mp.api.WxMpCardService;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.result.WxMpCardResult;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+import org.apache.http.HttpHost;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Arrays;
+import java.util.concurrent.locks.Lock;
/**
* Created by Binary Wang on 2016/7/27.
*/
-public class WxMpCardServiceImpl implements WxMpCardService {
+public class WxMpCardServiceImpl implements WxMpCardService {
private final Logger log = LoggerFactory.getLogger(WxMpCardServiceImpl.class);
@@ -36,6 +36,15 @@ public class WxMpCardServiceImpl implements WxMpCardService {
this.wxMpService = wxMpService;
}
+ /**
+ * 得到WxMpService
+ * @return
+ */
+ @Override
+ public WxMpService getWxMpService(){
+ return this.wxMpService;
+ }
+
/**
* 获得卡券api_ticket,不强制刷新卡券api_ticket
*
@@ -62,27 +71,27 @@ public class WxMpCardServiceImpl implements WxMpCardService {
*/
@Override
public String getCardApiTicket(boolean forceRefresh) throws WxErrorException {
- Lock lock = wxMpService.getWxMpConfigStorage().getCardApiTicketLock();
+ Lock lock = getWxMpService().getWxMpConfigStorage().getCardApiTicketLock();
try {
lock.lock();
if (forceRefresh) {
- this.wxMpService.getWxMpConfigStorage().expireCardApiTicket();
+ this.getWxMpService().getWxMpConfigStorage().expireCardApiTicket();
}
- if (this.wxMpService.getWxMpConfigStorage().isCardApiTicketExpired()) {
+ if (this.getWxMpService().getWxMpConfigStorage().isCardApiTicketExpired()) {
String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=wx_card";
String responseContent = this.wxMpService.execute(new SimpleGetRequestExecutor(), url, null);
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject();
String cardApiTicket = tmpJsonObject.get("ticket").getAsString();
int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt();
- this.wxMpService.getWxMpConfigStorage().updateCardApiTicket(cardApiTicket, expiresInSeconds);
+ this.getWxMpService().getWxMpConfigStorage().updateCardApiTicket(cardApiTicket, expiresInSeconds);
}
} finally {
lock.unlock();
}
- return this.wxMpService.getWxMpConfigStorage().getCardApiTicket();
+ return this.getWxMpService().getWxMpConfigStorage().getCardApiTicket();
}
/**
@@ -210,7 +219,7 @@ public class WxMpCardServiceImpl implements WxMpCardService {
param.addProperty("card_id", cardId);
param.addProperty("openid", openId);
param.addProperty("is_mark", isMark);
- String responseContent = this.wxMpService.post(url, param.toString());
+ String responseContent = this.getWxMpService().post(url, param.toString());
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
WxMpCardResult cardResult = WxMpGsonBuilder.INSTANCE.create().fromJson(tmpJsonElement,
new TypeToken() { }.getType());
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpDeviceServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpDeviceServiceImpl.java
index 5c9423651..3f7378e3d 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpDeviceServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpDeviceServiceImpl.java
@@ -16,7 +16,7 @@ public class WxMpDeviceServiceImpl implements WxMpDeviceService {
private WxMpService wxMpService;
- WxMpDeviceServiceImpl(WxMpService wxMpService) {
+ public WxMpDeviceServiceImpl(WxMpService wxMpService) {
this.wxMpService = wxMpService;
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpKefuServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpKefuServiceImpl.java
index 09a68adf8..4667f3279 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpKefuServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpKefuServiceImpl.java
@@ -1,28 +1,21 @@
package me.chanjar.weixin.mp.api.impl;
-import java.io.File;
-import java.util.Date;
-
-import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import com.google.gson.JsonObject;
-
import me.chanjar.weixin.common.bean.result.WxError;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor;
import me.chanjar.weixin.mp.api.WxMpKefuService;
import me.chanjar.weixin.mp.api.WxMpService;
+import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfAccountRequest;
import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfSessionRequest;
-import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfList;
-import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfMsgList;
-import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfOnlineList;
-import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionGetResult;
-import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionList;
-import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionWaitCaseList;
+import me.chanjar.weixin.mp.bean.kefu.result.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.File;
+import java.util.Date;
/**
*
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImpl.java
index af9fa54c3..4242063bd 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpMaterialServiceImpl.java
@@ -10,9 +10,6 @@ import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor;
import me.chanjar.weixin.common.util.json.WxGsonBuilder;
import me.chanjar.weixin.mp.api.WxMpMaterialService;
import me.chanjar.weixin.mp.api.WxMpService;
-import me.chanjar.weixin.mp.bean.material.WxMpMaterial;
-import me.chanjar.weixin.mp.bean.material.WxMpMaterialArticleUpdate;
-import me.chanjar.weixin.mp.bean.material.WxMpMaterialNews;
import me.chanjar.weixin.mp.bean.material.*;
import me.chanjar.weixin.mp.util.http.*;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpUserTagServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpUserTagServiceImpl.java
index d1bdae1e2..a1fee9370 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpUserTagServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpUserTagServiceImpl.java
@@ -1,14 +1,9 @@
package me.chanjar.weixin.mp.api.impl;
-import java.util.List;
-
-import org.apache.commons.lang3.StringUtils;
-
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.reflect.TypeToken;
-
import me.chanjar.weixin.common.bean.result.WxError;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
@@ -16,6 +11,9 @@ import me.chanjar.weixin.mp.api.WxMpUserTagService;
import me.chanjar.weixin.mp.bean.tag.WxTagListUser;
import me.chanjar.weixin.mp.bean.tag.WxUserTag;
import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder;
+import org.apache.commons.lang3.StringUtils;
+
+import java.util.List;
/**
*
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/apache/WxMpServiceImpl.java
similarity index 95%
rename from weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImpl.java
rename to weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/apache/WxMpServiceImpl.java
index 406e87126..5e6f863a9 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/WxMpServiceImpl.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/apache/WxMpServiceImpl.java
@@ -1,4 +1,4 @@
-package me.chanjar.weixin.mp.api.impl;
+package me.chanjar.weixin.mp.api.impl.apache;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
@@ -13,7 +13,10 @@ import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.common.util.RandomUtils;
import me.chanjar.weixin.common.util.crypto.SHA1;
import me.chanjar.weixin.common.util.http.*;
+import me.chanjar.weixin.common.util.http.apache.ApacheHttpClientBuilder;
+import me.chanjar.weixin.common.util.http.apache.DefaultApacheHttpClientBuilder;
import me.chanjar.weixin.mp.api.*;
+import me.chanjar.weixin.mp.api.impl.*;
import me.chanjar.weixin.mp.bean.*;
import me.chanjar.weixin.mp.bean.result.*;
import org.apache.http.HttpHost;
@@ -28,7 +31,7 @@ import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.concurrent.locks.Lock;
-public class WxMpServiceImpl implements WxMpService {
+public class WxMpServiceImpl implements WxMpService,RequestHttp {
private static final JsonParser JSON_PARSER = new JsonParser();
@@ -243,7 +246,7 @@ public class WxMpServiceImpl implements WxMpService {
private WxMpOAuth2AccessToken getOAuth2AccessToken(StringBuilder url) throws WxErrorException {
try {
RequestExecutor executor = new SimpleGetRequestExecutor();
- String responseText = executor.execute(this.getHttpclient(), this.httpProxy, url.toString(), null);
+ String responseText = executor.execute(this, url.toString(), null);
return WxMpOAuth2AccessToken.fromJson(responseText);
} catch (IOException e) {
throw new RuntimeException(e);
@@ -287,7 +290,7 @@ public class WxMpServiceImpl implements WxMpService {
try {
RequestExecutor executor = new SimpleGetRequestExecutor();
- String responseText = executor.execute(getHttpclient(), this.httpProxy, url.toString(), null);
+ String responseText = executor.execute(this, url.toString(), null);
return WxMpUser.fromJson(responseText);
} catch (IOException e) {
throw new RuntimeException(e);
@@ -303,7 +306,7 @@ public class WxMpServiceImpl implements WxMpService {
try {
RequestExecutor executor = new SimpleGetRequestExecutor();
- executor.execute(getHttpclient(), this.httpProxy, url.toString(), null);
+ executor.execute(this, url.toString(), null);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (WxErrorException e) {
@@ -373,7 +376,7 @@ public class WxMpServiceImpl implements WxMpService {
throw new RuntimeException("微信服务端异常,超出重试次数");
}
- protected synchronized T executeInternal(RequestExecutor executor, String uri, E data) throws WxErrorException {
+ public synchronized T executeInternal(RequestExecutor executor, String uri, E data) throws WxErrorException {
if (uri.indexOf("access_token=") != -1) {
throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri);
}
@@ -383,7 +386,7 @@ public class WxMpServiceImpl implements WxMpService {
uriWithAccessToken += uri.indexOf('?') == -1 ? "?access_token=" + accessToken : "&access_token=" + accessToken;
try {
- return executor.execute(getHttpclient(), this.httpProxy, uriWithAccessToken, data);
+ return executor.execute(this, uriWithAccessToken, data);
} catch (WxErrorException e) {
WxError error = e.getError();
/*
@@ -410,11 +413,12 @@ public class WxMpServiceImpl implements WxMpService {
}
}
- @Override
+ //@Override
public HttpHost getHttpProxy() {
return this.httpProxy;
}
+ //@Override
public CloseableHttpClient getHttpclient() {
return this.httpClient;
}
@@ -518,4 +522,14 @@ public class WxMpServiceImpl implements WxMpService {
public WxMpDeviceService getDeviceService() {
return this.deviceService;
}
+
+ @Override
+ public Object getRequestHttpClient() {
+ return this.httpClient;
+ }
+
+ @Override
+ public Object getRequestHttpProxy() {
+ return this.httpProxy;
+ }
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/jodd/WxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/jodd/WxMpServiceImpl.java
new file mode 100644
index 000000000..fa342f66d
--- /dev/null
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/impl/jodd/WxMpServiceImpl.java
@@ -0,0 +1,516 @@
+package me.chanjar.weixin.mp.api.impl.jodd;
+
+import com.google.gson.JsonArray;
+import com.google.gson.JsonElement;
+import com.google.gson.JsonObject;
+import com.google.gson.JsonParser;
+import jodd.http.*;
+import jodd.http.net.SocketHttpConnectionProvider;
+import me.chanjar.weixin.common.bean.WxAccessToken;
+import me.chanjar.weixin.common.bean.WxJsapiSignature;
+import me.chanjar.weixin.common.bean.result.WxError;
+import me.chanjar.weixin.common.exception.WxErrorException;
+import me.chanjar.weixin.common.session.StandardSessionManager;
+import me.chanjar.weixin.common.session.WxSessionManager;
+import me.chanjar.weixin.common.util.RandomUtils;
+import me.chanjar.weixin.common.util.crypto.SHA1;
+import me.chanjar.weixin.common.util.http.*;
+import me.chanjar.weixin.mp.api.*;
+import me.chanjar.weixin.mp.api.impl.*;
+import me.chanjar.weixin.mp.bean.*;
+import me.chanjar.weixin.mp.bean.result.*;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.util.concurrent.locks.Lock;
+
+public class WxMpServiceImpl implements WxMpService,RequestHttp {
+
+ private static final JsonParser JSON_PARSER = new JsonParser();
+
+ protected final Logger log = LoggerFactory.getLogger(this.getClass());
+ protected WxSessionManager sessionManager = new StandardSessionManager();
+ private WxMpConfigStorage wxMpConfigStorage;
+ private WxMpKefuService kefuService = new WxMpKefuServiceImpl(this);
+ private WxMpMaterialService materialService = new WxMpMaterialServiceImpl(this);
+ private WxMpMenuService menuService = new WxMpMenuServiceImpl(this);
+ private WxMpUserService userService = new WxMpUserServiceImpl(this);
+ private WxMpUserTagService tagService = new WxMpUserTagServiceImpl(this);
+ private WxMpQrcodeService qrCodeService = new WxMpQrcodeServiceImpl(this);
+ private WxMpCardService cardService = new WxMpCardServiceImpl(this);
+ private WxMpStoreService storeService = new WxMpStoreServiceImpl(this);
+ private WxMpDataCubeService dataCubeService = new WxMpDataCubeServiceImpl(this);
+ private WxMpUserBlacklistService blackListService = new WxMpUserBlacklistServiceImpl(this);
+ private WxMpTemplateMsgService templateMsgService = new WxMpTemplateMsgServiceImpl(this);
+ private WxMpDeviceService deviceService = new WxMpDeviceServiceImpl(this);
+
+ private HttpConnectionProvider httpClient;
+ private ProxyInfo httpProxy;
+ private int retrySleepMillis = 1000;
+ private int maxRetryTimes = 5;
+
+ private void initHttpClient() {
+ WxMpConfigStorage configStorage = this.getWxMpConfigStorage();
+
+ if (configStorage.getHttpProxyHost() != null && configStorage.getHttpProxyPort() > 0) {
+ httpProxy = new ProxyInfo(ProxyInfo.ProxyType.HTTP, configStorage.getHttpProxyHost(), configStorage.getHttpProxyPort(), configStorage.getHttpProxyUsername(), configStorage.getHttpProxyPassword());
+ }
+
+ httpClient = JoddHttp.httpConnectionProvider;
+ }
+
+ @Override
+ public boolean checkSignature(String timestamp, String nonce, String signature) {
+ try {
+ return SHA1.gen(this.getWxMpConfigStorage().getToken(), timestamp, nonce)
+ .equals(signature);
+ } catch (Exception e) {
+ return false;
+ }
+ }
+
+ @Override
+ public String getAccessToken() throws WxErrorException {
+ return getAccessToken(false);
+ }
+
+ @Override
+ public String getAccessToken(boolean forceRefresh) throws WxErrorException {
+ Lock lock = this.getWxMpConfigStorage().getAccessTokenLock();
+ try {
+ lock.lock();
+
+ if (forceRefresh) {
+ this.getWxMpConfigStorage().expireAccessToken();
+ }
+
+ if (this.getWxMpConfigStorage().isAccessTokenExpired()) {
+ String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential" +
+ "&appid=" + this.getWxMpConfigStorage().getAppId() + "&secret="
+ + this.getWxMpConfigStorage().getSecret();
+
+ HttpRequest request = HttpRequest.get(url);
+ if (this.httpProxy != null) {
+ SocketHttpConnectionProvider provider = new SocketHttpConnectionProvider();
+ provider.useProxy(httpProxy);
+ request.withConnectionProvider(provider);
+ }
+ HttpResponse response = request.send();
+ String resultContent = response.bodyText();
+ WxError error = WxError.fromJson(resultContent);
+ if (error.getErrorCode() != 0) {
+ throw new WxErrorException(error);
+ }
+ WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);
+ this.getWxMpConfigStorage().updateAccessToken(accessToken.getAccessToken(),
+ accessToken.getExpiresIn());
+ }
+ } finally {
+ lock.unlock();
+ }
+ return this.getWxMpConfigStorage().getAccessToken();
+ }
+
+ @Override
+ public String getJsapiTicket() throws WxErrorException {
+ return getJsapiTicket(false);
+ }
+
+ @Override
+ public String getJsapiTicket(boolean forceRefresh) throws WxErrorException {
+ Lock lock = this.getWxMpConfigStorage().getJsapiTicketLock();
+ try {
+ lock.lock();
+
+ if (forceRefresh) {
+ this.getWxMpConfigStorage().expireJsapiTicket();
+ }
+
+ if (this.getWxMpConfigStorage().isJsapiTicketExpired()) {
+ String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi";
+ String responseContent = execute(new SimpleGetRequestExecutor(), url, null);
+ JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent);
+ JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject();
+ String jsapiTicket = tmpJsonObject.get("ticket").getAsString();
+ int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt();
+ this.getWxMpConfigStorage().updateJsapiTicket(jsapiTicket, expiresInSeconds);
+ }
+ } finally {
+ lock.unlock();
+ }
+ return this.getWxMpConfigStorage().getJsapiTicket();
+ }
+
+ @Override
+ public WxJsapiSignature createJsapiSignature(String url) throws WxErrorException {
+ long timestamp = System.currentTimeMillis() / 1000;
+ String noncestr = RandomUtils.getRandomStr();
+ String jsapiTicket = getJsapiTicket(false);
+ String signature = SHA1.genWithAmple("jsapi_ticket=" + jsapiTicket,
+ "noncestr=" + noncestr, "timestamp=" + timestamp, "url=" + url);
+ WxJsapiSignature jsapiSignature = new WxJsapiSignature();
+ jsapiSignature.setAppId(this.getWxMpConfigStorage().getAppId());
+ jsapiSignature.setTimestamp(timestamp);
+ jsapiSignature.setNonceStr(noncestr);
+ jsapiSignature.setUrl(url);
+ jsapiSignature.setSignature(signature);
+ return jsapiSignature;
+ }
+
+ @Override
+ public WxMpMassUploadResult massNewsUpload(WxMpMassNews news) throws WxErrorException {
+ String url = "https://api.weixin.qq.com/cgi-bin/media/uploadnews";
+ String responseContent = this.post(url, news.toJson());
+ return WxMpMassUploadResult.fromJson(responseContent);
+ }
+
+ @Override
+ public WxMpMassUploadResult massVideoUpload(WxMpMassVideo video) throws WxErrorException {
+ String url = "https://api.weixin.qq.com/cgi-bin/media/uploadvideo";
+ String responseContent = this.post(url, video.toJson());
+ return WxMpMassUploadResult.fromJson(responseContent);
+ }
+
+ @Override
+ public WxMpMassSendResult massGroupMessageSend(WxMpMassTagMessage message) throws WxErrorException {
+ String url = "https://api.weixin.qq.com/cgi-bin/message/mass/sendall";
+ String responseContent = this.post(url, message.toJson());
+ return WxMpMassSendResult.fromJson(responseContent);
+ }
+
+ @Override
+ public WxMpMassSendResult massOpenIdsMessageSend(WxMpMassOpenIdsMessage message) throws WxErrorException {
+ String url = "https://api.weixin.qq.com/cgi-bin/message/mass/send";
+ String responseContent = this.post(url, message.toJson());
+ return WxMpMassSendResult.fromJson(responseContent);
+ }
+
+ @Override
+ public WxMpMassSendResult massMessagePreview(WxMpMassPreviewMessage wxMpMassPreviewMessage) throws Exception {
+ String url = "https://api.weixin.qq.com/cgi-bin/message/mass/preview";
+ String responseContent = this.post(url, wxMpMassPreviewMessage.toJson());
+ return WxMpMassSendResult.fromJson(responseContent);
+ }
+
+ @Override
+ public String shortUrl(String long_url) throws WxErrorException {
+ String url = "https://api.weixin.qq.com/cgi-bin/shorturl";
+ JsonObject o = new JsonObject();
+ o.addProperty("action", "long2short");
+ o.addProperty("long_url", long_url);
+ String responseContent = this.post(url, o.toString());
+ JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent);
+ return tmpJsonElement.getAsJsonObject().get("short_url").getAsString();
+ }
+
+ @Override
+ public WxMpSemanticQueryResult semanticQuery(WxMpSemanticQuery semanticQuery) throws WxErrorException {
+ String url = "https://api.weixin.qq.com/semantic/semproxy/search";
+ String responseContent = this.post(url, semanticQuery.toJson());
+ return WxMpSemanticQueryResult.fromJson(responseContent);
+ }
+
+ @Override
+ public String oauth2buildAuthorizationUrl(String redirectURI, String scope, String state) {
+ StringBuilder url = new StringBuilder();
+ url.append("https://open.weixin.qq.com/connect/oauth2/authorize?");
+ url.append("appid=").append(this.getWxMpConfigStorage().getAppId());
+ url.append("&redirect_uri=").append(URIUtil.encodeURIComponent(redirectURI));
+ url.append("&response_type=code");
+ url.append("&scope=").append(scope);
+ if (state != null) {
+ url.append("&state=").append(state);
+ }
+ url.append("#wechat_redirect");
+ return url.toString();
+ }
+
+ @Override
+ public String buildQrConnectUrl(String redirectURI, String scope,
+ String state) {
+ StringBuilder url = new StringBuilder();
+ url.append("https://open.weixin.qq.com/connect/qrconnect?");
+ url.append("appid=").append(this.getWxMpConfigStorage().getAppId());
+ url.append("&redirect_uri=").append(URIUtil.encodeURIComponent(redirectURI));
+ url.append("&response_type=code");
+ url.append("&scope=").append(scope);
+ if (state != null) {
+ url.append("&state=").append(state);
+ }
+
+ url.append("#wechat_redirect");
+ return url.toString();
+ }
+
+ private WxMpOAuth2AccessToken getOAuth2AccessToken(StringBuilder url) throws WxErrorException {
+ try {
+ RequestExecutor executor = new SimpleGetRequestExecutor();
+ String responseText = executor.execute(this, url.toString(), null);
+ return WxMpOAuth2AccessToken.fromJson(responseText);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public WxMpOAuth2AccessToken oauth2getAccessToken(String code) throws WxErrorException {
+ StringBuilder url = new StringBuilder();
+ url.append("https://api.weixin.qq.com/sns/oauth2/access_token?");
+ url.append("appid=").append(this.getWxMpConfigStorage().getAppId());
+ url.append("&secret=").append(this.getWxMpConfigStorage().getSecret());
+ url.append("&code=").append(code);
+ url.append("&grant_type=authorization_code");
+
+ return this.getOAuth2AccessToken(url);
+ }
+
+ @Override
+ public WxMpOAuth2AccessToken oauth2refreshAccessToken(String refreshToken) throws WxErrorException {
+ StringBuilder url = new StringBuilder();
+ url.append("https://api.weixin.qq.com/sns/oauth2/refresh_token?");
+ url.append("appid=").append(this.getWxMpConfigStorage().getAppId());
+ url.append("&grant_type=refresh_token");
+ url.append("&refresh_token=").append(refreshToken);
+
+ return this.getOAuth2AccessToken(url);
+ }
+
+ @Override
+ public WxMpUser oauth2getUserInfo(WxMpOAuth2AccessToken oAuth2AccessToken, String lang) throws WxErrorException {
+ StringBuilder url = new StringBuilder();
+ url.append("https://api.weixin.qq.com/sns/userinfo?");
+ url.append("access_token=").append(oAuth2AccessToken.getAccessToken());
+ url.append("&openid=").append(oAuth2AccessToken.getOpenId());
+ if (lang == null) {
+ url.append("&lang=zh_CN");
+ } else {
+ url.append("&lang=").append(lang);
+ }
+
+ try {
+ RequestExecutor executor = new SimpleGetRequestExecutor();
+ String responseText = executor.execute(this, url.toString(), null);
+ return WxMpUser.fromJson(responseText);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public boolean oauth2validateAccessToken(WxMpOAuth2AccessToken oAuth2AccessToken) {
+ StringBuilder url = new StringBuilder();
+ url.append("https://api.weixin.qq.com/sns/auth?");
+ url.append("access_token=").append(oAuth2AccessToken.getAccessToken());
+ url.append("&openid=").append(oAuth2AccessToken.getOpenId());
+
+ try {
+ RequestExecutor executor = new SimpleGetRequestExecutor();
+ executor.execute(this, url.toString(), null);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ } catch (WxErrorException e) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public String[] getCallbackIP() throws WxErrorException {
+ String url = "https://api.weixin.qq.com/cgi-bin/getcallbackip";
+ String responseContent = get(url, null);
+ JsonElement tmpJsonElement = JSON_PARSER.parse(responseContent);
+ JsonArray ipList = tmpJsonElement.getAsJsonObject().get("ip_list").getAsJsonArray();
+ String[] ipArray = new String[ipList.size()];
+ for (int i = 0; i < ipList.size(); i++) {
+ ipArray[i] = ipList.get(i).getAsString();
+ }
+ return ipArray;
+ }
+
+ @Override
+ public String get(String url, String queryParam) throws WxErrorException {
+ return execute(new SimpleGetRequestExecutor(), url, queryParam);
+ }
+
+ @Override
+ public String post(String url, String postData) throws WxErrorException {
+ return execute(new SimplePostRequestExecutor(), url, postData);
+ }
+
+ //@Override
+ public HttpConnectionProvider getHttpclient() {
+ return this.httpClient;
+ }
+
+ //@Override
+ public Object getHttpProxy() {
+ return null;
+ }
+
+ /**
+ * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求
+ */
+ public T execute(RequestExecutor executor, String uri, E data) throws WxErrorException {
+ int retryTimes = 0;
+ do {
+ try {
+ T result = executeInternal(executor, uri, data);
+ this.log.debug("\n[URL]: {}\n[PARAMS]: {}\n[RESPONSE]: {}", uri, data, result);
+ return result;
+ } catch (WxErrorException e) {
+ if (retryTimes + 1 > this.maxRetryTimes) {
+ this.log.warn("重试达到最大次数【{}】", maxRetryTimes);
+ //最后一次重试失败后,直接抛出异常,不再等待
+ throw new RuntimeException("微信服务端异常,超出重试次数");
+ }
+
+ WxError error = e.getError();
+ // -1 系统繁忙, 1000ms后重试
+ if (error.getErrorCode() == -1) {
+ int sleepMillis = this.retrySleepMillis * (1 << retryTimes);
+ try {
+ this.log.warn("微信系统繁忙,{} ms 后重试(第{}次)", sleepMillis, retryTimes + 1);
+ Thread.sleep(sleepMillis);
+ } catch (InterruptedException e1) {
+ throw new RuntimeException(e1);
+ }
+ } else {
+ throw e;
+ }
+ }
+ } while (retryTimes++ < this.maxRetryTimes);
+
+ this.log.warn("重试达到最大次数【{}】", this.maxRetryTimes);
+ throw new RuntimeException("微信服务端异常,超出重试次数");
+ }
+
+ public synchronized T executeInternal(RequestExecutor executor, String uri, E data) throws WxErrorException {
+ if (uri.indexOf("access_token=") != -1) {
+ throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri);
+ }
+ String accessToken = getAccessToken(false);
+
+ String uriWithAccessToken = uri;
+ uriWithAccessToken += uri.indexOf('?') == -1 ? "?access_token=" + accessToken : "&access_token=" + accessToken;
+
+ try {
+ return executor.execute(this, uriWithAccessToken, data);
+ } catch (WxErrorException e) {
+ WxError error = e.getError();
+ /*
+ * 发生以下情况时尝试刷新access_token
+ * 40001 获取access_token时AppSecret错误,或者access_token无效
+ * 42001 access_token超时
+ */
+ if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001) {
+ // 强制设置wxMpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token
+ this.getWxMpConfigStorage().expireAccessToken();
+ if (this.getWxMpConfigStorage().autoRefreshToken()) {
+ return this.execute(executor, uri, data);
+ }
+ }
+
+ if (error.getErrorCode() != 0) {
+ this.log.error("\n[URL]: {}\n[PARAMS]: {}\n[RESPONSE]: {}", uri, data, error);
+ throw new WxErrorException(error);
+ }
+ return null;
+ } catch (IOException e) {
+ this.log.error("\n[URL]: {}\n[PARAMS]: {}\n[EXCEPTION]: {}", uri, data, e.getMessage());
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public Object getRequestHttpClient() {
+ return this.httpClient;
+ }
+
+ @Override
+ public Object getRequestHttpProxy() {
+ return this.httpProxy;
+ }
+
+
+ @Override
+ public WxMpConfigStorage getWxMpConfigStorage() {
+ return this.wxMpConfigStorage;
+ }
+
+ @Override
+ public void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider) {
+ this.wxMpConfigStorage = wxConfigProvider;
+ this.initHttpClient();
+ }
+
+ @Override
+ public void setRetrySleepMillis(int retrySleepMillis) {
+ this.retrySleepMillis = retrySleepMillis;
+ }
+
+ @Override
+ public void setMaxRetryTimes(int maxRetryTimes) {
+ this.maxRetryTimes = maxRetryTimes;
+ }
+
+ @Override
+ public WxMpKefuService getKefuService() {
+ return this.kefuService;
+ }
+
+ @Override
+ public WxMpMaterialService getMaterialService() {
+ return this.materialService;
+ }
+
+ @Override
+ public WxMpMenuService getMenuService() {
+ return this.menuService;
+ }
+
+ @Override
+ public WxMpUserService getUserService() {
+ return this.userService;
+ }
+
+ @Override
+ public WxMpUserTagService getUserTagService() {
+ return this.tagService;
+ }
+
+ @Override
+ public WxMpQrcodeService getQrcodeService() {
+ return this.qrCodeService;
+ }
+
+ @Override
+ public WxMpCardService getCardService() {
+ return this.cardService;
+ }
+
+ @Override
+ public WxMpDataCubeService getDataCubeService() {
+ return this.dataCubeService;
+ }
+
+ @Override
+ public WxMpUserBlacklistService getBlackListService() {
+ return this.blackListService;
+ }
+
+ @Override
+ public WxMpStoreService getStoreService() {
+ return this.storeService;
+ }
+
+ @Override
+ public WxMpTemplateMsgService getTemplateMsgService() {
+ return this.templateMsgService;
+ }
+
+ @Override
+ public WxMpDeviceService getDeviceService() {
+ return this.deviceService;
+ }
+}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialDeleteRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialDeleteRequestExecutor.java
index 9502afe66..ef3f31b6e 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialDeleteRequestExecutor.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialDeleteRequestExecutor.java
@@ -1,9 +1,14 @@
package me.chanjar.weixin.mp.util.http;
+import jodd.http.HttpConnectionProvider;
+import jodd.http.HttpRequest;
+import jodd.http.HttpResponse;
+import jodd.http.ProxyInfo;
import me.chanjar.weixin.common.bean.result.WxError;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.http.RequestExecutor;
-import me.chanjar.weixin.common.util.http.Utf8ResponseHandler;
+import me.chanjar.weixin.common.util.http.RequestHttp;
+import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler;
import me.chanjar.weixin.common.util.json.WxGsonBuilder;
import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig;
@@ -24,7 +29,44 @@ public class MaterialDeleteRequestExecutor implements RequestExecutor params = new HashMap<>();
params.put("media_id", materialId);
httpPost.setEntity(new StringEntity(WxGsonBuilder.create().toJson(params)));
- try(CloseableHttpResponse response = httpclient.execute(httpPost)){
+ try (CloseableHttpResponse response = httpclient.execute(httpPost)) {
String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response);
WxError error = WxError.fromJson(responseContent);
if (error.getErrorCode() != 0) {
@@ -42,9 +84,10 @@ public class MaterialDeleteRequestExecutor implements RequestExecutor params = new HashMap<>();
params.put("media_id", materialId);
httpPost.setEntity(new StringEntity(WxGsonBuilder.create().toJson(params)));
- try(CloseableHttpResponse response = httpclient.execute(httpPost)){
+ try (CloseableHttpResponse response = httpclient.execute(httpPost)) {
String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response);
WxError error = WxError.fromJson(responseContent);
if (error.getErrorCode() != 0) {
@@ -43,10 +65,29 @@ public class MaterialNewsInfoRequestExecutor implements RequestExecutor {
@Override
- public WxMpMaterialUploadResult execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, WxMpMaterial material) throws WxErrorException, IOException {
+ public WxMpMaterialUploadResult execute(RequestHttp requestHttp, String uri, WxMpMaterial material) throws WxErrorException, IOException {
+ if (requestHttp.getRequestHttpClient() instanceof CloseableHttpClient) {
+ CloseableHttpClient httpClient = (CloseableHttpClient) requestHttp.getRequestHttpClient();
+ HttpHost httpProxy = (HttpHost) requestHttp.getRequestHttpProxy();
+ return executeApache(httpClient, httpProxy, uri, material);
+ }
+ if (requestHttp.getRequestHttpClient() instanceof HttpConnectionProvider) {
+ HttpConnectionProvider provider = (HttpConnectionProvider) requestHttp.getRequestHttpClient();
+ ProxyInfo proxyInfo = (ProxyInfo) requestHttp.getRequestHttpProxy();
+ return executeJodd(provider, proxyInfo, uri, material);
+ } else {
+ //这里需要抛出异常,需要优化
+ return null;
+ }
+ }
+
+ private WxMpMaterialUploadResult executeJodd(HttpConnectionProvider provider, ProxyInfo httpProxy, String uri, WxMpMaterial material) throws WxErrorException, IOException {
+ HttpRequest request = HttpRequest.post(uri);
+ if (httpProxy != null) {
+ provider.useProxy(httpProxy);
+ }
+ request.withConnectionProvider(provider);
+
+ if (material == null) {
+ throw new WxErrorException(WxError.newBuilder().setErrorMsg("非法请求,material参数为空").build());
+ }
+
+ File file = material.getFile();
+ if (file == null || !file.exists()) {
+ throw new FileNotFoundException();
+ }
+ request.form("media", file);
+ Map form = material.getForm();
+ if (material.getForm() != null) {
+ request.form("description", WxGsonBuilder.create().toJson(form));
+ }
+
+ HttpResponse response = request.send();
+ String responseContent = response.bodyText();
+ WxError error = WxError.fromJson(responseContent);
+ if (error.getErrorCode() != 0) {
+ throw new WxErrorException(error);
+ } else {
+ return WxMpMaterialUploadResult.fromJson(responseContent);
+ }
+ }
+
+ private WxMpMaterialUploadResult executeApache(CloseableHttpClient httpclient, HttpHost httpProxy, String uri,
+ WxMpMaterial material) throws WxErrorException, IOException {
HttpPost httpPost = new HttpPost(uri);
if (httpProxy != null) {
RequestConfig response = RequestConfig.custom().setProxy(httpProxy).build();
@@ -40,8 +95,8 @@ public class MaterialUploadRequestExecutor implements RequestExecutor form = material.getForm();
if (material.getForm() != null) {
multipartEntityBuilder.addTextBody("description", WxGsonBuilder.create().toJson(form));
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialVideoInfoRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialVideoInfoRequestExecutor.java
index 4eb15e46a..fb5818926 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialVideoInfoRequestExecutor.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MaterialVideoInfoRequestExecutor.java
@@ -1,9 +1,14 @@
package me.chanjar.weixin.mp.util.http;
+import jodd.http.HttpConnectionProvider;
+import jodd.http.HttpRequest;
+import jodd.http.HttpResponse;
+import jodd.http.ProxyInfo;
import me.chanjar.weixin.common.bean.result.WxError;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.http.RequestExecutor;
-import me.chanjar.weixin.common.util.http.Utf8ResponseHandler;
+import me.chanjar.weixin.common.util.http.RequestHttp;
+import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler;
import me.chanjar.weixin.common.util.json.WxGsonBuilder;
import me.chanjar.weixin.mp.bean.material.WxMpMaterialVideoInfoResult;
import org.apache.http.HttpHost;
@@ -24,7 +29,43 @@ public class MaterialVideoInfoRequestExecutor implements RequestExecutor params = new HashMap<>();
params.put("media_id", materialId);
httpPost.setEntity(new StringEntity(WxGsonBuilder.create().toJson(params)));
- try(CloseableHttpResponse response = httpclient.execute(httpPost)){
+ try (CloseableHttpResponse response = httpclient.execute(httpPost)) {
String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response);
WxError error = WxError.fromJson(responseContent);
if (error.getErrorCode() != 0) {
@@ -42,9 +83,10 @@ public class MaterialVideoInfoRequestExecutor implements RequestExecutor {
@@ -33,18 +37,32 @@ public class MaterialVoiceAndImageDownloadRequestExecutor implements RequestExec
}
@Override
- public InputStream execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, String materialId) throws WxErrorException, IOException {
- HttpPost httpPost = new HttpPost(uri);
- if (httpProxy != null) {
- RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build();
- httpPost.setConfig(config);
+ public InputStream execute(RequestHttp requestHttp, String uri, String materialId) throws WxErrorException, IOException {
+ if (requestHttp.getRequestHttpClient() instanceof CloseableHttpClient) {
+ CloseableHttpClient httpClient = (CloseableHttpClient) requestHttp.getRequestHttpClient();
+ HttpHost httpProxy = (HttpHost) requestHttp.getRequestHttpProxy();
+ return executeApache(httpClient, httpProxy, uri, materialId);
}
+ if (requestHttp.getRequestHttpClient() instanceof HttpConnectionProvider) {
+ HttpConnectionProvider provider = (HttpConnectionProvider) requestHttp.getRequestHttpClient();
+ ProxyInfo proxyInfo = (ProxyInfo) requestHttp.getRequestHttpProxy();
+ return executeJodd(provider, proxyInfo, uri, materialId);
+ } else {
+ //这里需要抛出异常,需要优化
+ return null;
+ }
+ }
- Map params = new HashMap<>();
- params.put("media_id", materialId);
- httpPost.setEntity(new StringEntity(WxGsonBuilder.create().toJson(params)));
- try (CloseableHttpResponse response = httpclient.execute(httpPost);
- InputStream inputStream = InputStreamResponseHandler.INSTANCE.handleResponse(response);){
+ private InputStream executeJodd(HttpConnectionProvider provider, ProxyInfo proxyInfo, String uri, String materialId) throws WxErrorException, IOException {
+ HttpRequest request = HttpRequest.post(uri);
+ if (proxyInfo != null) {
+ provider.useProxy(proxyInfo);
+ }
+ request.withConnectionProvider(provider);
+
+ request.query("media_id", materialId);
+ HttpResponse response = request.send();
+ try (InputStream inputStream = new ByteArrayInputStream(response.bodyBytes())) {
// 下载媒体文件出错
byte[] responseContent = IOUtils.toByteArray(inputStream);
String responseContentString = new String(responseContent, "UTF-8");
@@ -59,9 +77,41 @@ public class MaterialVoiceAndImageDownloadRequestExecutor implements RequestExec
}
}
return new ByteArrayInputStream(responseContent);
- }finally {
+ }
+
+ }
+
+ private InputStream executeApache(CloseableHttpClient httpclient, HttpHost httpProxy, String uri,
+ String materialId) throws WxErrorException, IOException {
+ HttpPost httpPost = new HttpPost(uri);
+ if (httpProxy != null) {
+ RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build();
+ httpPost.setConfig(config);
+ }
+
+ Map params = new HashMap<>();
+ params.put("media_id", materialId);
+ httpPost.setEntity(new StringEntity(WxGsonBuilder.create().toJson(params)));
+ try (CloseableHttpResponse response = httpclient.execute(httpPost);
+ InputStream inputStream = InputStreamResponseHandler.INSTANCE.handleResponse(response);) {
+ // 下载媒体文件出错
+ byte[] responseContent = IOUtils.toByteArray(inputStream);
+ String responseContentString = new String(responseContent, "UTF-8");
+ if (responseContentString.length() < 100) {
+ try {
+ WxError wxError = WxGsonBuilder.create().fromJson(responseContentString, WxError.class);
+ if (wxError.getErrorCode() != 0) {
+ throw new WxErrorException(wxError);
+ }
+ } catch (com.google.gson.JsonSyntaxException ex) {
+ return new ByteArrayInputStream(responseContent);
+ }
+ }
+ return new ByteArrayInputStream(responseContent);
+ } finally {
httpPost.releaseConnection();
}
}
+
}
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MediaImgUploadRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MediaImgUploadRequestExecutor.java
index 2129e8a7a..c22bc3109 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MediaImgUploadRequestExecutor.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/MediaImgUploadRequestExecutor.java
@@ -1,9 +1,14 @@
package me.chanjar.weixin.mp.util.http;
+import jodd.http.HttpConnectionProvider;
+import jodd.http.HttpRequest;
+import jodd.http.HttpResponse;
+import jodd.http.ProxyInfo;
import me.chanjar.weixin.common.bean.result.WxError;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.http.RequestExecutor;
-import me.chanjar.weixin.common.util.http.Utf8ResponseHandler;
+import me.chanjar.weixin.common.util.http.RequestHttp;
+import me.chanjar.weixin.common.util.http.apache.Utf8ResponseHandler;
import me.chanjar.weixin.mp.bean.material.WxMediaImgUploadResult;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
@@ -22,8 +27,50 @@ import java.io.IOException;
* @author miller
*/
public class MediaImgUploadRequestExecutor implements RequestExecutor {
+
@Override
- public WxMediaImgUploadResult execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, File data) throws WxErrorException, IOException {
+ public WxMediaImgUploadResult execute(RequestHttp requestHttp, String uri, File data) throws WxErrorException, IOException {
+ if (requestHttp.getRequestHttpClient() instanceof CloseableHttpClient) {
+ CloseableHttpClient httpClient = (CloseableHttpClient) requestHttp.getRequestHttpClient();
+ HttpHost httpProxy = (HttpHost) requestHttp.getRequestHttpProxy();
+ return executeApache(httpClient, httpProxy, uri, data);
+ }
+ if (requestHttp.getRequestHttpClient() instanceof HttpConnectionProvider) {
+ HttpConnectionProvider provider = (HttpConnectionProvider) requestHttp.getRequestHttpClient();
+ ProxyInfo proxyInfo = (ProxyInfo) requestHttp.getRequestHttpProxy();
+ return executeJodd(provider, proxyInfo, uri, data);
+ } else {
+ //这里需要抛出异常,需要优化
+ return null;
+ }
+
+ }
+
+
+ private WxMediaImgUploadResult executeJodd(HttpConnectionProvider provider, ProxyInfo proxyInfo, String uri, File data) throws WxErrorException, IOException {
+ if (data == null) {
+ throw new WxErrorException(WxError.newBuilder().setErrorMsg("文件对象为空").build());
+ }
+
+ HttpRequest request = HttpRequest.post(uri);
+ if (proxyInfo != null) {
+ provider.useProxy(proxyInfo);
+ }
+ request.withConnectionProvider(provider);
+
+ request.form("media", data);
+ HttpResponse response = request.send();
+ String responseContent = response.bodyText();
+ WxError error = WxError.fromJson(responseContent);
+ if (error.getErrorCode() != 0) {
+ throw new WxErrorException(error);
+ }
+
+ return WxMediaImgUploadResult.fromJson(responseContent);
+ }
+
+ private WxMediaImgUploadResult executeApache(CloseableHttpClient httpclient, HttpHost httpProxy, String uri,
+ File data) throws WxErrorException, IOException {
if (data == null) {
throw new WxErrorException(WxError.newBuilder().setErrorMsg("文件对象为空").build());
}
@@ -52,4 +99,5 @@ public class MediaImgUploadRequestExecutor implements RequestExecutor {
@Override
- public File execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri,
- WxMpQrCodeTicket ticket) throws WxErrorException, IOException {
+ public File execute(RequestHttp requestHttp, String uri,
+ WxMpQrCodeTicket ticket) throws WxErrorException, IOException {
+ if (requestHttp.getRequestHttpClient() instanceof CloseableHttpClient) {
+ CloseableHttpClient httpClient = (CloseableHttpClient) requestHttp.getRequestHttpClient();
+ HttpHost httpProxy = (HttpHost) requestHttp.getRequestHttpProxy();
+ return executeApache(httpClient, httpProxy, uri, ticket);
+ }
+ if (requestHttp.getRequestHttpClient() instanceof HttpConnectionProvider) {
+ HttpConnectionProvider provider = (HttpConnectionProvider) requestHttp.getRequestHttpClient();
+ ProxyInfo proxyInfo = (ProxyInfo) requestHttp.getRequestHttpProxy();
+ return executeJodd(provider, proxyInfo, uri, ticket);
+ } else {
+ //这里需要抛出异常,需要优化
+ return null;
+ }
+ }
+
+ private File executeJodd(HttpConnectionProvider provider, ProxyInfo proxyInfo, String uri, WxMpQrCodeTicket ticket) throws WxErrorException, IOException {
if (ticket != null) {
if (uri.indexOf('?') == -1) {
uri += '?';
}
- uri += uri.endsWith("?")
- ? "ticket=" + URLEncoder.encode(ticket.getTicket(), "UTF-8")
- : "&ticket=" + URLEncoder.encode(ticket.getTicket(), "UTF-8");
+ uri += uri.endsWith("?")
+ ? "ticket=" + URLEncoder.encode(ticket.getTicket(), "UTF-8")
+ : "&ticket=" + URLEncoder.encode(ticket.getTicket(), "UTF-8");
}
-
+
+ HttpRequest request = HttpRequest.get(uri);
+ if (proxyInfo != null) {
+ provider.useProxy(proxyInfo);
+ }
+ request.withConnectionProvider(provider);
+
+ HttpResponse response = request.send();
+ String contentTypeHeader = response.header("Content-Type");
+ if (MimeTypes.MIME_TEXT_PLAIN.equals(contentTypeHeader)) {
+ String responseContent = response.bodyText();
+ throw new WxErrorException(WxError.fromJson(responseContent));
+ }
+ try (InputStream inputStream = new ByteArrayInputStream(response.bodyBytes())) {
+ return FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), "jpg");
+ }
+ }
+
+ private File executeApache(CloseableHttpClient httpclient, HttpHost httpProxy, String uri,
+ WxMpQrCodeTicket ticket) throws WxErrorException, IOException {
+ if (ticket != null) {
+ if (uri.indexOf('?') == -1) {
+ uri += '?';
+ }
+ uri += uri.endsWith("?")
+ ? "ticket=" + URLEncoder.encode(ticket.getTicket(), "UTF-8")
+ : "&ticket=" + URLEncoder.encode(ticket.getTicket(), "UTF-8");
+ }
+
HttpGet httpGet = new HttpGet(uri);
if (httpProxy != null) {
RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build();
@@ -47,7 +98,7 @@ public class QrCodeRequestExecutor implements RequestExecutor 0) {
// 出错
@@ -60,7 +111,6 @@ public class QrCodeRequestExecutor implements RequestExecutor T executeInternal(
+ public synchronized T executeInternal(
RequestExecutor executor, String uri, E data)
throws WxErrorException {
this.log.info("Executed");
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpStoreServiceImplTest.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpStoreServiceImplTest.java
index e4edca749..baa34443f 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpStoreServiceImplTest.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/impl/WxMpStoreServiceImplTest.java
@@ -25,7 +25,7 @@ public class WxMpStoreServiceImplTest {
private WxMpService wxMpService;
/**
- * Test method for {@link me.chanjar.weixin.mp.api.impl.WxMpStoreServiceImpl#add(me.chanjar.weixin.mp.bean.store.WxMpStoreBaseInfo)}.
+ * Test method for {@link WxMpStoreServiceImpl#add(me.chanjar.weixin.mp.bean.store.WxMpStoreBaseInfo)}.
*
* @throws WxErrorException
*/
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/ApiTestModule.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/ApiTestModule.java
index 31ad47b6f..2cfaec543 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/ApiTestModule.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/api/test/ApiTestModule.java
@@ -6,7 +6,7 @@ import com.thoughtworks.xstream.XStream;
import me.chanjar.weixin.common.util.xml.XStreamInitializer;
import me.chanjar.weixin.mp.api.WxMpConfigStorage;
import me.chanjar.weixin.mp.api.WxMpService;
-import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
+import me.chanjar.weixin.mp.api.impl.apache.WxMpServiceImpl;
import java.io.IOException;
import java.io.InputStream;
diff --git a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoServer.java b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoServer.java
index 1c1893762..e2c75f83d 100644
--- a/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoServer.java
+++ b/weixin-java-mp/src/test/java/me/chanjar/weixin/mp/demo/WxMpDemoServer.java
@@ -5,7 +5,7 @@ import me.chanjar.weixin.mp.api.WxMpConfigStorage;
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
import me.chanjar.weixin.mp.api.WxMpService;
-import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
+import me.chanjar.weixin.mp.api.impl.apache.WxMpServiceImpl;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.servlet.ServletHolder;
diff --git a/weixin-java-pay/build.gradle b/weixin-java-pay/build.gradle
new file mode 100644
index 000000000..2f0c7e9a8
--- /dev/null
+++ b/weixin-java-pay/build.gradle
@@ -0,0 +1,12 @@
+description = 'WeiXin Java Tools - PAY'
+dependencies {
+ compile project(':weixin-java-common')
+ testCompile group: 'junit', name: 'junit', version: '4.11'
+ testCompile group: 'org.testng', name: 'testng', version: '6.8.7'
+ testCompile group: 'org.mockito', name: 'mockito-all', version: '1.9.5'
+ testCompile group: 'com.google.inject', name: 'guice', version: '3.0'
+ testCompile group: 'org.eclipse.jetty', name: 'jetty-server', version: '9.3.0.RC0'
+ testCompile group: 'org.eclipse.jetty', name: 'jetty-servlet', version: '9.3.0.RC0'
+ testCompile group: 'joda-time', name: 'joda-time', version: '2.9.4'
+}
+test.useTestNG()