From a69c9722613157b91671cbcfb104e5bdcab93c1c Mon Sep 17 00:00:00 2001 From: Daniel Qian Date: Sat, 1 Nov 2014 13:42:18 +0800 Subject: [PATCH 1/8] =?UTF-8?q?issue=20#24=20=E6=A8=A1=E6=9D=BF=E6=B6=88?= =?UTF-8?q?=E6=81=AF=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../chanjar/weixin/common/api/WxConsts.java | 1 + .../me/chanjar/weixin/mp/api/WxMpService.java | 12 +++- .../weixin/mp/api/WxMpServiceImpl.java | 8 ++- .../weixin/mp/bean/WxMpTemplateData.java | 49 +++++++++++++++ .../weixin/mp/bean/WxMpTemplateMessage.java | 62 +++++++++++++++++++ .../weixin/mp/util/json/WxMpGsonBuilder.java | 1 + .../json/WxMpTemplateMessageGsonAdapter.java | 50 +++++++++++++++ 7 files changed, 181 insertions(+), 2 deletions(-) create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpTemplateData.java create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpTemplateMessage.java create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpTemplateMessageGsonAdapter.java diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java index 084c8ee0..8a843e94 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java @@ -88,6 +88,7 @@ public class WxConsts { public static final String EVT_PIC_PHOTO_OR_ALBUM = "pic_photo_or_album"; public static final String EVT_PIC_WEIXIN = "pic_weixin"; public static final String EVT_LOCATION_SELECT = "location_select"; + public static final String EVT_TEMPLATESENDJOBFINISH = "TEMPLATESENDJOBFINISH"; /////////////////////// // 上传多媒体文件的类型 diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java index 4b3a20fc..3beb5406 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java @@ -306,7 +306,17 @@ public interface WxMpService { * @throws WxErrorException */ public String shortUrl(String long_url) throws WxErrorException; - + + /** + *
+   * 发送模板消息
+   * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=模板消息接口
+   * 
+ * @param templateMessage + * @throws WxErrorException + */ + public void templateSend(WxMpTemplateMessage templateMessage) throws WxErrorException; + /** * 注入 {@link WxMpConfigStorage} 的实现 * @param wxConfigProvider diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java index c40af33d..a2834a9a 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java @@ -31,6 +31,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.StringReader; import java.util.List; +import java.util.Map; import java.util.UUID; import java.util.concurrent.atomic.AtomicBoolean; @@ -272,7 +273,12 @@ public class WxMpServiceImpl implements WxMpService { JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent))); return tmpJsonElement.getAsJsonObject().get("short_url").getAsString(); } - + + public void templateSend(WxMpTemplateMessage templateMessage) throws WxErrorException { + String url = "https://api.weixin.qq.com/cgi-bin/message/template/send"; + execute(new SimplePostRequestExecutor(), url, templateMessage.toJson()); + } + /** * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求 * @param executor diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpTemplateData.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpTemplateData.java new file mode 100644 index 00000000..e328fe85 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpTemplateData.java @@ -0,0 +1,49 @@ +package me.chanjar.weixin.mp.bean; + +/** + * @author Daniel Qian + */ +public class WxMpTemplateData { + + private String name; + private String value; + private String color; + + public WxMpTemplateData() { + } + + public WxMpTemplateData(String name, String value) { + this.name = name; + this.value = value; + } + + public WxMpTemplateData(String name, String value, String color) { + this.name = name; + this.value = value; + this.color = color; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getValue() { + return value; + } + + public void setValue(String value) { + this.value = value; + } + + public String getColor() { + return color; + } + public void setColor(String color) { + this.color = color; + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpTemplateMessage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpTemplateMessage.java new file mode 100644 index 00000000..cd6ac5f7 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpTemplateMessage.java @@ -0,0 +1,62 @@ +package me.chanjar.weixin.mp.bean; + +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by qianjia on 14/11/1. + */ +public class WxMpTemplateMessage { + + private String toUser; + private String templateId; + private String url; + private String topColor; + private List datas = new ArrayList(); + + public String getToUser() { + return toUser; + } + + public void setToUser(String toUser) { + this.toUser = toUser; + } + + public String getTemplateId() { + return templateId; + } + + public void setTemplateId(String templateId) { + this.templateId = templateId; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getTopColor() { + return topColor; + } + + public void setTopColor(String topColor) { + this.topColor = topColor; + } + + public List getDatas() { + return datas; + } + + public void setDatas(List datas) { + this.datas = datas; + } + + public String toJson() { + return WxMpGsonBuilder.INSTANCE.create().toJson(this); + } +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java index 021b660d..dc2367b6 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java @@ -22,6 +22,7 @@ public class WxMpGsonBuilder { INSTANCE.registerTypeAdapter(WxMpMassSendResult.class, new WxMpMassSendResultAdapter()); INSTANCE.registerTypeAdapter(WxMpMassUploadResult.class, new WxMpMassUploadResultAdapter()); INSTANCE.registerTypeAdapter(WxMpQrCodeTicket.class, new WxQrCodeTicketAdapter()); + INSTANCE.registerTypeAdapter(WxMpTemplateMessage.class, new WxMpTemplateMessageGsonAdapter()); } public static Gson create() { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpTemplateMessageGsonAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpTemplateMessageGsonAdapter.java new file mode 100644 index 00000000..ad603d3b --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpTemplateMessageGsonAdapter.java @@ -0,0 +1,50 @@ +/* + * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. + * + * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended + * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction + * arose from modification of the original source, or other redistribution of this source + * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. + */ +package me.chanjar.weixin.mp.util.json; + +import com.google.gson.*; +import me.chanjar.weixin.common.api.WxConsts; +import me.chanjar.weixin.mp.bean.WxMpCustomMessage; +import me.chanjar.weixin.mp.bean.WxMpTemplateData; +import me.chanjar.weixin.mp.bean.WxMpTemplateMessage; + +import java.lang.reflect.Type; + +/** + * @author qianjia + */ +public class WxMpTemplateMessageGsonAdapter implements JsonSerializer { + + public JsonElement serialize(WxMpTemplateMessage message, Type typeOfSrc, JsonSerializationContext context) { + JsonObject messageJson = new JsonObject(); + messageJson.addProperty("touser", message.getToUser()); + messageJson.addProperty("template_id", message.getTemplateId()); + if (message.getUrl() != null) { + messageJson.addProperty("url", message.getUrl()); + } + if (message.getTopColor() != null) { + messageJson.addProperty("topcolor", message.getTopColor()); + } + + JsonObject datas = new JsonObject(); + messageJson.add("data", datas); + + for (WxMpTemplateData data : message.getDatas()) { + JsonObject dataJson = new JsonObject(); + dataJson.addProperty("value", data.getValue()); + if (data.getColor() != null) { + dataJson.addProperty("color", data.getColor()); + } + datas.add(data.getName(), dataJson); + } + + return messageJson; + } + +} From 294ad07259e351453d4e736165ac748861513fd2 Mon Sep 17 00:00:00 2001 From: Daniel Qian Date: Sat, 1 Nov 2014 13:44:33 +0800 Subject: [PATCH 2/8] upgrade to 1.0.4-SNAPSHOT --- pom.xml | 2 +- weixin-java-common/pom.xml | 2 +- weixin-java-cp/pom.xml | 2 +- weixin-java-mp/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index b8c86bcf..e05f30a7 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 me.chanjar weixin-java-parent - 1.0.3 + 1.0.4-SNAPSHOT pom WeiXin Java Tools - Parent 微信公众号、企业号上级POM diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index 81478a25..6aef9c57 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -6,7 +6,7 @@ me.chanjar weixin-java-parent - 1.0.3 + 1.0.4-SNAPSHOT weixin-java-common diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index c6f60df0..87ed3ccf 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -6,7 +6,7 @@ me.chanjar weixin-java-parent - 1.0.3 + 1.0.4-SNAPSHOT weixin-java-cp diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml index 570540f3..003ee776 100644 --- a/weixin-java-mp/pom.xml +++ b/weixin-java-mp/pom.xml @@ -6,7 +6,7 @@ me.chanjar weixin-java-parent - 1.0.3 + 1.0.4-SNAPSHOT weixin-java-mp WeiXin Java Tools - MP From d659e5b62104b616e9ab5f7868a32220bc51068e Mon Sep 17 00:00:00 2001 From: Daniel Qian Date: Sat, 1 Nov 2014 13:57:02 +0800 Subject: [PATCH 3/8] =?UTF-8?q?=E5=BC=80=E6=94=BElow-level=E6=96=B9?= =?UTF-8?q?=E6=B3=95=EF=BC=8C=E5=BD=93=E6=9C=AC=E9=A1=B9=E7=9B=AE=E8=B7=9F?= =?UTF-8?q?=E4=B8=8D=E4=B8=8A=E5=BE=AE=E4=BF=A1api=E7=9A=84=E6=9B=B4?= =?UTF-8?q?=E6=96=B0=E9=80=9F=E5=BA=A6=E7=9A=84=E6=97=B6=E5=80=99=EF=BC=8C?= =?UTF-8?q?=E5=BC=80=E5=8F=91=E4=BA=BA=E5=91=98=E8=BF=98=E5=8F=AF=E4=BB=A5?= =?UTF-8?q?=E4=BD=BF=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../me/chanjar/weixin/cp/api/WxCpService.java | 39 ++++++++++++++++++- .../weixin/cp/api/WxCpServiceImpl.java | 8 ++++ .../me/chanjar/weixin/mp/api/WxMpService.java | 39 ++++++++++++++++++- .../weixin/mp/api/WxMpServiceImpl.java | 10 ++++- 4 files changed, 91 insertions(+), 5 deletions(-) diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java index 26646167..1355f17a 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpService.java @@ -7,6 +7,7 @@ import java.util.List; import me.chanjar.weixin.common.bean.WxMenu; import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; +import me.chanjar.weixin.common.util.http.RequestExecutor; import me.chanjar.weixin.cp.bean.*; import me.chanjar.weixin.cp.bean.WxCpDepart; import me.chanjar.weixin.cp.bean.WxCpUser; @@ -65,8 +66,8 @@ public interface WxCpService { * 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=上传下载多媒体文件 * * - * @param mediaType 媒体类型, 请看{@link WxConsts} - * @param fileType 文件类型,请看{@link WxConsts} + * @param mediaType 媒体类型, 请看{@link me.chanjar.weixin.common.api.WxConsts} + * @param fileType 文件类型,请看{@link me.chanjar.weixin.common.api.WxConsts} * @param inputStream 输入流 * @throws WxErrorException */ @@ -281,6 +282,40 @@ public interface WxCpService { */ public void tagRemoveUsers(String tagId, List userIds) throws WxErrorException; + /** + * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的GET请求 + * @param url + * @param queryParam + * @return + * @throws WxErrorException + */ + String get(String url, String queryParam) throws WxErrorException; + + /** + * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的POST请求 + * @param url + * @param postData + * @return + * @throws WxErrorException + */ + String post(String url, String postData) throws WxErrorException; + + /** + *
+   * Service没有实现某个API的时候,可以用这个,
+   * 比{@link #get}和{@link #post}方法更灵活,可以自己构造RequestExecutor用来处理不同的参数和不同的返回类型。
+   * 可以参考,{@link me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor}的实现方法
+   * 
+ * @param executor + * @param uri + * @param data + * @param + * @param + * @return + * @throws WxErrorException + */ + public T execute(RequestExecutor executor, String uri, E data) throws WxErrorException; + /** * 注入 {@link WxCpConfigStorage} 的实现 * diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java index 4d9b2af3..279ac6b2 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java @@ -308,6 +308,14 @@ public class WxCpServiceImpl implements WxCpService { execute(new SimplePostRequestExecutor(), url, jsonObject.toString()); } + public String get(String url, String queryParam) throws WxErrorException { + return execute(new SimpleGetRequestExecutor(), url, queryParam); + } + + public String post(String url, String postData) throws WxErrorException { + return execute(new SimplePostRequestExecutor(), url, postData); + } + /** * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求 * diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java index 3beb5406..1323e615 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java @@ -2,6 +2,7 @@ package me.chanjar.weixin.mp.api; import me.chanjar.weixin.common.bean.WxMenu; import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; +import me.chanjar.weixin.common.util.http.RequestExecutor; import me.chanjar.weixin.mp.bean.*; import me.chanjar.weixin.mp.bean.result.*; import me.chanjar.weixin.common.exception.WxErrorException; @@ -318,8 +319,42 @@ public interface WxMpService { public void templateSend(WxMpTemplateMessage templateMessage) throws WxErrorException; /** - * 注入 {@link WxMpConfigStorage} 的实现 - * @param wxConfigProvider + * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的GET请求 + * @param url + * @param queryParam + * @return + * @throws WxErrorException + */ + String get(String url, String queryParam) throws WxErrorException; + + /** + * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的POST请求 + * @param url + * @param postData + * @return + * @throws WxErrorException */ + String post(String url, String postData) throws WxErrorException; + + /** + *
+   * Service没有实现某个API的时候,可以用这个,
+   * 比{@link #get}和{@link #post}方法更灵活,可以自己构造RequestExecutor用来处理不同的参数和不同的返回类型。
+   * 可以参考,{@link me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor}的实现方法
+   * 
+ * @param executor + * @param uri + * @param data + * @param + * @param + * @return + * @throws WxErrorException + */ + public T execute(RequestExecutor executor, String uri, E data) throws WxErrorException; + + /** + * 注入 {@link WxMpConfigStorage} 的实现 + * @param wxConfigProvider + */ public void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider); } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java index a2834a9a..95a49889 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java @@ -279,7 +279,15 @@ public class WxMpServiceImpl implements WxMpService { execute(new SimplePostRequestExecutor(), url, templateMessage.toJson()); } - /** + public String get(String url, String queryParam) throws WxErrorException { + return execute(new SimpleGetRequestExecutor(), url, queryParam); + } + + public String post(String url, String postData) throws WxErrorException { + return execute(new SimplePostRequestExecutor(), url, postData); + } + + /** * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求 * @param executor * @param uri From 3067468f7157b77f13f8ac5c0d36031e202e375a Mon Sep 17 00:00:00 2001 From: Daniel Qian Date: Mon, 3 Nov 2014 15:56:31 +0800 Subject: [PATCH 4/8] =?UTF-8?q?issue=20#29=20http=E4=BB=A3=E7=90=86?= =?UTF-8?q?=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../http/MediaDownloadRequestExecutor.java | 10 +++- .../util/http/MediaUploadRequestExecutor.java | 9 +++- .../common/util/http/RequestExecutor.java | 5 +- .../util/http/SimpleGetRequestExecutor.java | 10 +++- .../util/http/SimplePostRequestExecutor.java | 18 ++++++- .../weixin/cp/api/WxCpConfigStorage.java | 8 +++ .../cp/api/WxCpInMemoryConfigStorage.java | 46 +++++++++++++++- .../weixin/cp/api/WxCpServiceImpl.java | 44 ++++++++++++++-- .../weixin/cp/api/WxCpMediaAPITest.java | 1 + .../weixin/cp/api/WxCpMessageAPITest.java | 1 + .../weixin/cp/api/WxCpMessageRouterTest.java | 1 + .../chanjar/weixin/cp/api/WxMenuAPITest.java | 1 + .../weixin/mp/api/WxMpConfigStorage.java | 8 +++ .../mp/api/WxMpInMemoryConfigStorage.java | 52 +++++++++++++++++++ .../weixin/mp/api/WxMpServiceImpl.java | 47 +++++++++++++++-- .../mp/util/http/QrCodeRequestExecutor.java | 10 +++- 16 files changed, 254 insertions(+), 17 deletions(-) diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/MediaDownloadRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/MediaDownloadRequestExecutor.java index caa8e03b..7fc05d94 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/MediaDownloadRequestExecutor.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/MediaDownloadRequestExecutor.java @@ -8,10 +8,13 @@ import me.chanjar.weixin.common.util.http.RequestExecutor; import me.chanjar.weixin.common.util.http.Utf8ResponseHandler; import org.apache.commons.lang3.StringUtils; import org.apache.http.Header; +import org.apache.http.HttpHost; import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.entity.ContentType; +import org.apache.http.impl.client.CloseableHttpClient; import java.io.File; import java.io.IOException; @@ -27,7 +30,7 @@ import java.util.regex.Pattern; public class MediaDownloadRequestExecutor implements RequestExecutor { @Override - public File execute(String uri, String queryParam) throws WxErrorException, ClientProtocolException, IOException { + public File execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, String queryParam) throws WxErrorException, ClientProtocolException, IOException { if (queryParam != null) { if (uri.indexOf('?') == -1) { uri += '?'; @@ -36,6 +39,11 @@ public class MediaDownloadRequestExecutor implements RequestExecutor { @Override - public WxMediaUploadResult execute(String uri, File file) throws WxErrorException, ClientProtocolException, IOException { + public WxMediaUploadResult execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, File file) throws WxErrorException, ClientProtocolException, IOException { HttpPost httpPost = new HttpPost(uri); + if (httpProxy != null) { + RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build(); + httpPost.setConfig(config); + } if (file != null) { HttpEntity entity = MultipartEntityBuilder .create() diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/RequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/RequestExecutor.java index e7959dca..84de1b6d 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/RequestExecutor.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/RequestExecutor.java @@ -2,6 +2,7 @@ package me.chanjar.weixin.common.util.http; import java.io.IOException; +import org.apache.http.HttpHost; import org.apache.http.client.ClientProtocolException; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; @@ -17,8 +18,6 @@ import me.chanjar.weixin.common.exception.WxErrorException; */ public interface RequestExecutor { - public static final CloseableHttpClient httpclient = HttpClients.createDefault(); + public T execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, E data) throws WxErrorException, ClientProtocolException, IOException; - public T execute(String uri, E data) throws WxErrorException, ClientProtocolException, IOException; - } diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/SimpleGetRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/SimpleGetRequestExecutor.java index 4d5ea024..5ad0f0b8 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/SimpleGetRequestExecutor.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/SimpleGetRequestExecutor.java @@ -2,12 +2,15 @@ package me.chanjar.weixin.common.util.http; import java.io.IOException; +import org.apache.http.HttpHost; import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import me.chanjar.weixin.common.bean.result.WxError; import me.chanjar.weixin.common.exception.WxErrorException; +import org.apache.http.impl.client.CloseableHttpClient; /** * 简单的GET请求执行器,请求的参数是String, 返回的结果也是String @@ -17,7 +20,7 @@ import me.chanjar.weixin.common.exception.WxErrorException; public class SimpleGetRequestExecutor implements RequestExecutor { @Override - public String execute(String uri, String queryParam) throws WxErrorException, ClientProtocolException, IOException { + public String execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, String queryParam) throws WxErrorException, ClientProtocolException, IOException { if (queryParam != null) { if (uri.indexOf('?') == -1) { uri += '?'; @@ -25,6 +28,11 @@ public class SimpleGetRequestExecutor implements RequestExecutor uri += uri.endsWith("?") ? queryParam : '&' + queryParam; } HttpGet httpGet = new HttpGet(uri); + if (httpProxy != null) { + RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build(); + httpGet.setConfig(config); + } + CloseableHttpResponse response = httpclient.execute(httpGet); String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); WxError error = WxError.fromJson(responseContent); diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/SimplePostRequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/SimplePostRequestExecutor.java index 8025d6dc..d50fe251 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/SimplePostRequestExecutor.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/SimplePostRequestExecutor.java @@ -5,10 +5,20 @@ import java.io.IOException; import me.chanjar.weixin.common.bean.result.WxError; import me.chanjar.weixin.common.exception.WxErrorException; import org.apache.http.Consts; +import org.apache.http.HttpHost; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.CredentialsProvider; +import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.BasicCredentialsProvider; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.util.EntityUtils; /** * 简单的POST请求执行器,请求的参数是String, 返回的结果也是String @@ -18,12 +28,18 @@ import org.apache.http.entity.StringEntity; public class SimplePostRequestExecutor implements RequestExecutor { @Override - public String execute(String uri, String postEntity) throws WxErrorException, ClientProtocolException, IOException { + public String execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, String postEntity) throws WxErrorException, ClientProtocolException, IOException { HttpPost httpPost = new HttpPost(uri); + if (httpProxy != null) { + RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build(); + httpPost.setConfig(config); + } + if (postEntity != null) { StringEntity entity = new StringEntity(postEntity, Consts.UTF_8); httpPost.setEntity(entity); } + CloseableHttpResponse response = httpclient.execute(httpPost); String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); WxError error = WxError.fromJson(responseContent); diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpConfigStorage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpConfigStorage.java index d61b0035..7837a6f4 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpConfigStorage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpConfigStorage.java @@ -27,4 +27,12 @@ public interface WxCpConfigStorage { public int getExpiresIn(); + public String getHttp_proxy_host(); + + public int getHttp_proxy_port(); + + public String getHttp_proxy_username(); + + public String getHttp_proxy_password(); + } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpInMemoryConfigStorage.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpInMemoryConfigStorage.java index 26d15f4b..49e5f392 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpInMemoryConfigStorage.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpInMemoryConfigStorage.java @@ -18,6 +18,11 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage { protected String agentId; protected int expiresIn; + protected String http_proxy_host; + protected int http_proxy_port; + protected String http_proxy_username; + protected String http_proxy_password; + public void updateAccessToken(WxAccessToken accessToken) { updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); } @@ -83,16 +88,53 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage { this.agentId = agentId; } + public String getHttp_proxy_host() { + return http_proxy_host; + } + + public void setHttp_proxy_host(String http_proxy_host) { + this.http_proxy_host = http_proxy_host; + } + + public int getHttp_proxy_port() { + return http_proxy_port; + } + + public void setHttp_proxy_port(int http_proxy_port) { + this.http_proxy_port = http_proxy_port; + } + + public String getHttp_proxy_username() { + return http_proxy_username; + } + + public void setHttp_proxy_username(String http_proxy_username) { + this.http_proxy_username = http_proxy_username; + } + + public String getHttp_proxy_password() { + return http_proxy_password; + } + + public void setHttp_proxy_password(String http_proxy_password) { + this.http_proxy_password = http_proxy_password; + } + @Override public String toString() { - return "WxInMemoryCpConfigStorage{" + - "appidOrCorpid='" + corpId + '\'' + + return "WxCpInMemoryConfigStorage{" + + "corpId='" + corpId + '\'' + ", corpSecret='" + corpSecret + '\'' + ", token='" + token + '\'' + ", accessToken='" + accessToken + '\'' + ", aesKey='" + aesKey + '\'' + ", agentId='" + agentId + '\'' + ", expiresIn=" + expiresIn + + ", http_proxy_host='" + http_proxy_host + '\'' + + ", http_proxy_port=" + http_proxy_port + + ", http_proxy_username='" + http_proxy_username + '\'' + + ", http_proxy_password='" + http_proxy_password + '\'' + '}'; } + } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java index 279ac6b2..89a66c52 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java @@ -20,9 +20,14 @@ import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor; import me.chanjar.weixin.common.util.crypto.SHA1; import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpHost; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.CredentialsProvider; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.client.BasicResponseHandler; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; @@ -51,12 +56,14 @@ public class WxCpServiceImpl implements WxCpService { */ protected static final AtomicBoolean GLOBAL_ACCESS_TOKEN_REFRESH_FLAG = new AtomicBoolean(false); - protected static final CloseableHttpClient httpclient = HttpClients.createDefault(); - protected WxCpConfigStorage wxCpConfigStorage; protected final ThreadLocal retryTimes = new ThreadLocal(); + protected CloseableHttpClient httpClient; + + protected HttpHost httpProxy; + public boolean checkSignature(String msgSignature, String timestamp, String nonce, String data) { try { return SHA1.gen(wxCpConfigStorage.getToken(), timestamp, nonce, data).equals(msgSignature); @@ -78,6 +85,7 @@ public class WxCpServiceImpl implements WxCpService { + "&corpsecret=" + wxCpConfigStorage.getCorpSecret(); try { HttpGet httpGet = new HttpGet(url); + CloseableHttpClient httpclient = getHttpclient(); CloseableHttpResponse response = httpclient.execute(httpGet); String resultContent = new BasicResponseHandler().handleResponse(response); WxError error = WxError.fromJson(resultContent); @@ -335,7 +343,7 @@ public class WxCpServiceImpl implements WxCpService { uriWithAccessToken += uri.indexOf('?') == -1 ? "?access_token=" + accessToken : "&access_token=" + accessToken; try { - return executor.execute(uriWithAccessToken, data); + return executor.execute(getHttpclient(), httpProxy, uriWithAccessToken, data); } catch (WxErrorException e) { WxError error = e.getError(); /* @@ -379,8 +387,38 @@ public class WxCpServiceImpl implements WxCpService { } } + protected CloseableHttpClient getHttpclient() { + return httpClient; + } + public void setWxCpConfigStorage(WxCpConfigStorage wxConfigProvider) { this.wxCpConfigStorage = wxConfigProvider; + + String http_proxy_host = wxCpConfigStorage.getHttp_proxy_host(); + int http_proxy_port = wxCpConfigStorage.getHttp_proxy_port(); + String http_proxy_username = wxCpConfigStorage.getHttp_proxy_username(); + String http_proxy_password = wxCpConfigStorage.getHttp_proxy_password(); + + if(StringUtils.isNotBlank(http_proxy_host)) { + // 使用代理服务器 + if(StringUtils.isNotBlank(http_proxy_username)) { + // 需要用户认证的代理服务器 + CredentialsProvider credsProvider = new BasicCredentialsProvider(); + credsProvider.setCredentials( + new AuthScope(http_proxy_host, http_proxy_port), + new UsernamePasswordCredentials(http_proxy_username, http_proxy_password)); + httpClient = HttpClients + .custom() + .setDefaultCredentialsProvider(credsProvider) + .build(); + } else { + // 无需用户认证的代理服务器 + httpClient = HttpClients.createDefault(); + } + httpProxy = new HttpHost(http_proxy_host, http_proxy_port); + } else { + httpClient = HttpClients.createDefault(); + } } } diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMediaAPITest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMediaAPITest.java index 7c47ee2f..f04b1fd4 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMediaAPITest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMediaAPITest.java @@ -5,6 +5,7 @@ import java.io.InputStream; import java.util.ArrayList; import java.util.List; +import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.bean.result.WxMediaUploadResult; import org.testng.Assert; import org.testng.annotations.DataProvider; diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageAPITest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageAPITest.java index 08966280..1672faaa 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageAPITest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageAPITest.java @@ -1,5 +1,6 @@ package me.chanjar.weixin.cp.api; +import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.cp.bean.WxCpMessage; import org.testng.annotations.Guice; import org.testng.annotations.Test; diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageRouterTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageRouterTest.java index 7542a951..59962c6f 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageRouterTest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageRouterTest.java @@ -2,6 +2,7 @@ package me.chanjar.weixin.cp.api; import java.util.Map; +import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.cp.bean.WxCpXmlMessage; import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; import org.testng.Assert; diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxMenuAPITest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxMenuAPITest.java index 7ed9caa8..c00d73e2 100644 --- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxMenuAPITest.java +++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxMenuAPITest.java @@ -2,6 +2,7 @@ package me.chanjar.weixin.cp.api; import javax.xml.bind.JAXBException; +import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.bean.WxMenu; import org.testng.Assert; import org.testng.annotations.DataProvider; diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpConfigStorage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpConfigStorage.java index e90013ff..e7ee779c 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpConfigStorage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpConfigStorage.java @@ -25,4 +25,12 @@ public interface WxMpConfigStorage { public int getExpiresIn(); + public String getHttp_proxy_host(); + + public int getHttp_proxy_port(); + + public String getHttp_proxy_username(); + + public String getHttp_proxy_password(); + } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java index 0218067b..d0f9c33d 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpInMemoryConfigStorage.java @@ -16,6 +16,11 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { protected String aesKey; protected int expiresIn; + protected String http_proxy_host; + protected int http_proxy_port; + protected String http_proxy_username; + protected String http_proxy_password; + public void updateAccessToken(WxAccessToken accessToken) { updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); } @@ -73,5 +78,52 @@ public class WxMpInMemoryConfigStorage implements WxMpConfigStorage { this.expiresIn = expiresIn; } + public String getHttp_proxy_host() { + return http_proxy_host; + } + + public void setHttp_proxy_host(String http_proxy_host) { + this.http_proxy_host = http_proxy_host; + } + + public int getHttp_proxy_port() { + return http_proxy_port; + } + + public void setHttp_proxy_port(int http_proxy_port) { + this.http_proxy_port = http_proxy_port; + } + + public String getHttp_proxy_username() { + return http_proxy_username; + } + + public void setHttp_proxy_username(String http_proxy_username) { + this.http_proxy_username = http_proxy_username; + } + + public String getHttp_proxy_password() { + return http_proxy_password; + } + + public void setHttp_proxy_password(String http_proxy_password) { + this.http_proxy_password = http_proxy_password; + } + + @Override + public String toString() { + return "WxMpInMemoryConfigStorage{" + + "appId='" + appId + '\'' + + ", secret='" + secret + '\'' + + ", token='" + token + '\'' + + ", accessToken='" + accessToken + '\'' + + ", aesKey='" + aesKey + '\'' + + ", expiresIn=" + expiresIn + + ", http_proxy_host='" + http_proxy_host + '\'' + + ", http_proxy_port=" + http_proxy_port + + ", http_proxy_username='" + http_proxy_username + '\'' + + ", http_proxy_password='" + http_proxy_password + '\'' + + '}'; + } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java index 95a49889..1e43f62c 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java @@ -19,9 +19,15 @@ import me.chanjar.weixin.mp.bean.result.*; import me.chanjar.weixin.mp.util.http.QrCodeRequestExecutor; import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; import org.apache.commons.lang3.StringUtils; +import org.apache.http.HttpHost; +import org.apache.http.auth.AuthScope; +import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.CredentialsProvider; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.client.BasicResponseHandler; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; @@ -44,12 +50,14 @@ public class WxMpServiceImpl implements WxMpService { */ protected static final AtomicBoolean GLOBAL_ACCESS_TOKEN_REFRESH_FLAG = new AtomicBoolean(false); - protected static final CloseableHttpClient httpclient = HttpClients.createDefault(); - protected WxMpConfigStorage wxMpConfigStorage; protected final ThreadLocal retryTimes = new ThreadLocal(); + protected CloseableHttpClient httpClient; + + protected HttpHost httpProxy; + public boolean checkSignature(String timestamp, String nonce, String signature) { try { return SHA1.gen(wxMpConfigStorage.getToken(), timestamp, nonce).equals(signature); @@ -67,6 +75,7 @@ public class WxMpServiceImpl implements WxMpService { ; try { HttpGet httpGet = new HttpGet(url); + CloseableHttpClient httpclient = getHttpclient(); CloseableHttpResponse response = httpclient.execute(httpGet); String resultContent = new BasicResponseHandler().handleResponse(response); WxError error = WxError.fromJson(resultContent); @@ -305,7 +314,7 @@ public class WxMpServiceImpl implements WxMpService { uriWithAccessToken += uri.indexOf('?') == -1 ? "?access_token=" + accessToken : "&access_token=" + accessToken; try { - return executor.execute(uriWithAccessToken, data); + return executor.execute(getHttpclient(), httpProxy, uriWithAccessToken, data); } catch (WxErrorException e) { WxError error = e.getError(); /* @@ -348,9 +357,39 @@ public class WxMpServiceImpl implements WxMpService { throw new RuntimeException(e); } } - + + protected CloseableHttpClient getHttpclient() { + return httpClient; + } + public void setWxMpConfigStorage(WxMpConfigStorage wxConfigProvider) { this.wxMpConfigStorage = wxConfigProvider; + + String http_proxy_host = wxMpConfigStorage.getHttp_proxy_host(); + int http_proxy_port = wxMpConfigStorage.getHttp_proxy_port(); + String http_proxy_username = wxMpConfigStorage.getHttp_proxy_username(); + String http_proxy_password = wxMpConfigStorage.getHttp_proxy_password(); + + if(StringUtils.isNotBlank(http_proxy_host)) { + // 使用代理服务器 + if(StringUtils.isNotBlank(http_proxy_username)) { + // 需要用户认证的代理服务器 + CredentialsProvider credsProvider = new BasicCredentialsProvider(); + credsProvider.setCredentials( + new AuthScope(http_proxy_host, http_proxy_port), + new UsernamePasswordCredentials(http_proxy_username, http_proxy_password)); + httpClient = HttpClients + .custom() + .setDefaultCredentialsProvider(credsProvider) + .build(); + } else { + // 无需用户认证的代理服务器 + httpClient = HttpClients.createDefault(); + } + httpProxy = new HttpHost(http_proxy_host, http_proxy_port); + } else { + httpClient = HttpClients.createDefault(); + } } } diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/QrCodeRequestExecutor.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/QrCodeRequestExecutor.java index 554c9b8f..593bdb05 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/QrCodeRequestExecutor.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/http/QrCodeRequestExecutor.java @@ -8,10 +8,13 @@ import me.chanjar.weixin.common.util.http.Utf8ResponseHandler; import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; import me.chanjar.weixin.common.exception.WxErrorException; import org.apache.http.Header; +import org.apache.http.HttpHost; import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.entity.ContentType; +import org.apache.http.impl.client.CloseableHttpClient; import java.io.File; import java.io.IOException; @@ -27,7 +30,7 @@ import java.util.UUID; public class QrCodeRequestExecutor implements RequestExecutor { @Override - public File execute(String uri, WxMpQrCodeTicket ticket) throws WxErrorException, ClientProtocolException, IOException { + public File execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, WxMpQrCodeTicket ticket) throws WxErrorException, ClientProtocolException, IOException { if (ticket != null) { if (uri.indexOf('?') == -1) { uri += '?'; @@ -39,6 +42,11 @@ public class QrCodeRequestExecutor implements RequestExecutor Date: Mon, 3 Nov 2014 21:29:40 +0800 Subject: [PATCH 5/8] =?UTF-8?q?issue=20#29=20http=E4=BB=A3=E7=90=86?= =?UTF-8?q?=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../weixin/common/util/http/RequestExecutor.java | 12 +++++++++++- .../me/chanjar/weixin/cp/api/WxCpServiceImpl.java | 5 +++++ .../me/chanjar/weixin/mp/api/WxMpServiceImpl.java | 5 +++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/RequestExecutor.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/RequestExecutor.java index 84de1b6d..5d407cb9 100644 --- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/RequestExecutor.java +++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/RequestExecutor.java @@ -11,13 +11,23 @@ import me.chanjar.weixin.common.exception.WxErrorException; /** * http请求执行器 - * @author Daniel Qian * * @param 返回值类型 * @param 请求参数类型 */ public interface RequestExecutor { + /** + * + * @param httpclient 传入的httpClient + * @param httpProxy http代理对象,如果没有配置代理则为空 + * @param uri uri + * @param data 数据 + * @return + * @throws WxErrorException + * @throws ClientProtocolException + * @throws IOException + */ public T execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, E data) throws WxErrorException, ClientProtocolException, IOException; } diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java index 89a66c52..39b8e3db 100644 --- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java +++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java @@ -25,6 +25,7 @@ import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.CredentialsProvider; +import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.BasicCredentialsProvider; @@ -85,6 +86,10 @@ public class WxCpServiceImpl implements WxCpService { + "&corpsecret=" + wxCpConfigStorage.getCorpSecret(); try { HttpGet httpGet = new HttpGet(url); + if (httpProxy != null) { + RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build(); + httpGet.setConfig(config); + } CloseableHttpClient httpclient = getHttpclient(); CloseableHttpResponse response = httpclient.execute(httpGet); String resultContent = new BasicResponseHandler().handleResponse(response); diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java index 1e43f62c..aebeee68 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java @@ -24,6 +24,7 @@ import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.ClientProtocolException; import org.apache.http.client.CredentialsProvider; +import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; @@ -75,6 +76,10 @@ public class WxMpServiceImpl implements WxMpService { ; try { HttpGet httpGet = new HttpGet(url); + if (httpProxy != null) { + RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build(); + httpGet.setConfig(config); + } CloseableHttpClient httpclient = getHttpclient(); CloseableHttpResponse response = httpclient.execute(httpGet); String resultContent = new BasicResponseHandler().handleResponse(response); From a44c18ade60346d36b780be54834d9cf9f33fba7 Mon Sep 17 00:00:00 2001 From: Daniel Qian Date: Mon, 3 Nov 2014 21:46:40 +0800 Subject: [PATCH 6/8] =?UTF-8?q?issue=20#28=20=E6=B7=BB=E5=8A=A0=E8=AF=AD?= =?UTF-8?q?=E4=B9=89=E7=90=86=E8=A7=A3=E6=8E=A5=E5=8F=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../weixin/mp/bean/WxMpSemanticQuery.java | 91 +++++++++++++++++++ .../bean/result/WxMpSemanticQueryResult.java | 73 +++++++++++++++ .../weixin/mp/util/json/WxMpGsonBuilder.java | 1 + .../json/WxMpSemanticQueryResultAdapter.java | 51 +++++++++++ 4 files changed, 216 insertions(+) create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpSemanticQuery.java create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpSemanticQueryResult.java create mode 100644 weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpSemanticQueryResultAdapter.java diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpSemanticQuery.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpSemanticQuery.java new file mode 100644 index 00000000..aac3bd10 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/WxMpSemanticQuery.java @@ -0,0 +1,91 @@ +package me.chanjar.weixin.mp.bean; + +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +/** + * 语义理解查询用对象 + * + * http://mp.weixin.qq.com/wiki/index.php?title=语义理解 + * + * @author Daniel Qian + */ +public class WxMpSemanticQuery { + + private String query; + private String category; + private Float latitude; + private Float longitude; + private String city; + private String region; + private String appid; + private String uid; + + public String getQuery() { + return query; + } + + public void setQuery(String query) { + this.query = query; + } + + public String getCategory() { + return category; + } + + public void setCategory(String category) { + this.category = category; + } + + public Float getLatitude() { + return latitude; + } + + public void setLatitude(Float latitude) { + this.latitude = latitude; + } + + public Float getLongitude() { + return longitude; + } + + public void setLongitude(Float longitude) { + this.longitude = longitude; + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city; + } + + public String getRegion() { + return region; + } + + public void setRegion(String region) { + this.region = region; + } + + public String getAppid() { + return appid; + } + + public void setAppid(String appid) { + this.appid = appid; + } + + public String getUid() { + return uid; + } + + public void setUid(String uid) { + this.uid = uid; + } + + public String toJson() { + return WxMpGsonBuilder.create().toJson(this); + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpSemanticQueryResult.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpSemanticQueryResult.java new file mode 100644 index 00000000..a0972c35 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/bean/result/WxMpSemanticQueryResult.java @@ -0,0 +1,73 @@ +package me.chanjar.weixin.mp.bean.result; + +import me.chanjar.weixin.mp.util.json.WxMpGsonBuilder; + +/** + * 语义理解查询结果对象 + * + * http://mp.weixin.qq.com/wiki/index.php?title=语义理解 + * + * @author Daniel Qian + */ +public class WxMpSemanticQueryResult { + + private String query; + private String type; + private String semantic; + private String result; + private String answer; + private String text; + + public String getQuery() { + return query; + } + + public void setQuery(String query) { + this.query = query; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public String getSemantic() { + return semantic; + } + + public void setSemantic(String semantic) { + this.semantic = semantic; + } + + public String getResult() { + return result; + } + + public void setResult(String result) { + this.result = result; + } + + public String getAnswer() { + return answer; + } + + public void setAnswer(String answer) { + this.answer = answer; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } + + public static WxMpSemanticQueryResult fromJson(String json) { + return WxMpGsonBuilder.create().fromJson(json, WxMpSemanticQueryResult.class); + } + +} diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java index dc2367b6..7285bc8b 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpGsonBuilder.java @@ -23,6 +23,7 @@ public class WxMpGsonBuilder { INSTANCE.registerTypeAdapter(WxMpMassUploadResult.class, new WxMpMassUploadResultAdapter()); INSTANCE.registerTypeAdapter(WxMpQrCodeTicket.class, new WxQrCodeTicketAdapter()); INSTANCE.registerTypeAdapter(WxMpTemplateMessage.class, new WxMpTemplateMessageGsonAdapter()); + INSTANCE.registerTypeAdapter(WxMpSemanticQueryResult.class, new WxMpSemanticQueryResultAdapter()); } public static Gson create() { diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpSemanticQueryResultAdapter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpSemanticQueryResultAdapter.java new file mode 100644 index 00000000..c0d1e805 --- /dev/null +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/util/json/WxMpSemanticQueryResultAdapter.java @@ -0,0 +1,51 @@ +/* + * KINGSTAR MEDIA SOLUTIONS Co.,LTD. Copyright c 2005-2013. All rights reserved. + * + * This source code is the property of KINGSTAR MEDIA SOLUTIONS LTD. It is intended + * only for the use of KINGSTAR MEDIA application development. Reengineering, reproduction + * arose from modification of the original source, or other redistribution of this source + * is not permitted without written permission of the KINGSTAR MEDIA SOLUTIONS LTD. + */ +package me.chanjar.weixin.mp.util.json; + +import com.google.gson.*; +import me.chanjar.weixin.common.util.json.GsonHelper; +import me.chanjar.weixin.mp.bean.result.WxMpMassSendResult; +import me.chanjar.weixin.mp.bean.result.WxMpQrCodeTicket; +import me.chanjar.weixin.mp.bean.result.WxMpSemanticQueryResult; + +import java.lang.reflect.Type; + +/** + * + * @author Daniel Qian + * + */ +public class WxMpSemanticQueryResultAdapter implements JsonDeserializer { + + public WxMpSemanticQueryResult deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { + WxMpSemanticQueryResult result = new WxMpSemanticQueryResult(); + JsonObject resultJsonObject = json.getAsJsonObject(); + + if (GsonHelper.getString(resultJsonObject, "query") != null) { + result.setQuery(GsonHelper.getString(resultJsonObject, "query")); + } + if (GsonHelper.getString(resultJsonObject, "type") != null) { + result.setType(GsonHelper.getString(resultJsonObject, "type")); + } + if (resultJsonObject.get("semantic") != null) { + result.setSemantic(resultJsonObject.get("semantic").toString()); + } + if (resultJsonObject.get("result") != null) { + result.setResult(resultJsonObject.get("result").toString()); + } + if (GsonHelper.getString(resultJsonObject, "answer") != null) { + result.setAnswer(GsonHelper.getString(resultJsonObject, "answer")); + } + if (GsonHelper.getString(resultJsonObject, "text") != null) { + result.setText(GsonHelper.getString(resultJsonObject, "text")); + } + return result; + } + +} From a49f834188a1226e9de2306995a0571ee270eb96 Mon Sep 17 00:00:00 2001 From: Daniel Qian Date: Mon, 3 Nov 2014 21:51:12 +0800 Subject: [PATCH 7/8] issue #28 --- .../java/me/chanjar/weixin/mp/api/WxMpService.java | 11 +++++++++++ .../me/chanjar/weixin/mp/api/WxMpServiceImpl.java | 6 ++++++ 2 files changed, 17 insertions(+) diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java index 1323e615..daaa062f 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpService.java @@ -318,6 +318,17 @@ public interface WxMpService { */ public void templateSend(WxMpTemplateMessage templateMessage) throws WxErrorException; + /** + *
+   * 语义查询接口
+   * 详情请见:http://mp.weixin.qq.com/wiki/index.php?title=语义理解
+   * 
+ * @param semanticQuery + * @return + * @throws WxErrorException + */ + WxMpSemanticQueryResult semanticQuery(WxMpSemanticQuery semanticQuery) throws WxErrorException; + /** * 当本Service没有实现某个API的时候,可以用这个,针对所有微信API中的GET请求 * @param url diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java index aebeee68..a4b4cc37 100644 --- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java +++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpServiceImpl.java @@ -293,6 +293,12 @@ public class WxMpServiceImpl implements WxMpService { execute(new SimplePostRequestExecutor(), url, templateMessage.toJson()); } + public WxMpSemanticQueryResult semanticQuery(WxMpSemanticQuery semanticQuery) throws WxErrorException { + String url = "https://api.weixin.qq.com/semantic/semproxy/search"; + String responseContent = execute(new SimplePostRequestExecutor(), url, semanticQuery.toJson()); + return WxMpSemanticQueryResult.fromJson(responseContent); + } + public String get(String url, String queryParam) throws WxErrorException { return execute(new SimpleGetRequestExecutor(), url, queryParam); } From 9d54743901c0b3eaf0bab64560dd256048d29daa Mon Sep 17 00:00:00 2001 From: Daniel Qian Date: Mon, 3 Nov 2014 21:54:08 +0800 Subject: [PATCH 8/8] update version to 1.0.4 --- pom.xml | 2 +- weixin-java-common/pom.xml | 2 +- weixin-java-cp/pom.xml | 2 +- weixin-java-mp/pom.xml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/pom.xml b/pom.xml index e05f30a7..9ff35595 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ 4.0.0 me.chanjar weixin-java-parent - 1.0.4-SNAPSHOT + 1.0.4 pom WeiXin Java Tools - Parent 微信公众号、企业号上级POM diff --git a/weixin-java-common/pom.xml b/weixin-java-common/pom.xml index 6aef9c57..1d9c3ebc 100644 --- a/weixin-java-common/pom.xml +++ b/weixin-java-common/pom.xml @@ -6,7 +6,7 @@ me.chanjar weixin-java-parent - 1.0.4-SNAPSHOT + 1.0.4 weixin-java-common diff --git a/weixin-java-cp/pom.xml b/weixin-java-cp/pom.xml index 87ed3ccf..7f96ee7a 100644 --- a/weixin-java-cp/pom.xml +++ b/weixin-java-cp/pom.xml @@ -6,7 +6,7 @@ me.chanjar weixin-java-parent - 1.0.4-SNAPSHOT + 1.0.4 weixin-java-cp diff --git a/weixin-java-mp/pom.xml b/weixin-java-mp/pom.xml index 003ee776..940e79f3 100644 --- a/weixin-java-mp/pom.xml +++ b/weixin-java-mp/pom.xml @@ -6,7 +6,7 @@ me.chanjar weixin-java-parent - 1.0.4-SNAPSHOT + 1.0.4 weixin-java-mp WeiXin Java Tools - MP