{
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/FileBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/FileBuilder.java
index f67cf6e50..6b36cf6cf 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/FileBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/FileBuilder.java
@@ -1,7 +1,7 @@
package me.chanjar.weixin.cp.bean.messagebuilder;
import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.cp.bean.WxCpMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpMessage;
/**
* 获得消息builder
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/ImageBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/ImageBuilder.java
index ddf3b7373..6735385c9 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/ImageBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/ImageBuilder.java
@@ -1,7 +1,7 @@
package me.chanjar.weixin.cp.bean.messagebuilder;
import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.cp.bean.WxCpMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpMessage;
/**
* 获得消息builder
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MarkdownMsgBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MarkdownMsgBuilder.java
index 6e0a4a330..6b6af40ac 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MarkdownMsgBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MarkdownMsgBuilder.java
@@ -1,7 +1,7 @@
package me.chanjar.weixin.cp.bean.messagebuilder;
import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.cp.bean.WxCpMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpMessage;
/**
*
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MiniProgramNoticeMsgBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MiniProgramNoticeMsgBuilder.java
index cf44c0f0f..928ea3863 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MiniProgramNoticeMsgBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MiniProgramNoticeMsgBuilder.java
@@ -1,7 +1,7 @@
package me.chanjar.weixin.cp.bean.messagebuilder;
import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.cp.bean.WxCpMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpMessage;
import java.util.Map;
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MpnewsBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MpnewsBuilder.java
index 75739803f..bc1467e14 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MpnewsBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MpnewsBuilder.java
@@ -1,7 +1,7 @@
package me.chanjar.weixin.cp.bean.messagebuilder;
import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.cp.bean.WxCpMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpMessage;
import me.chanjar.weixin.cp.bean.article.MpnewsArticle;
import java.util.ArrayList;
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/NewsBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/NewsBuilder.java
index 9d0d2f603..ef661e6ed 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/NewsBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/NewsBuilder.java
@@ -1,7 +1,7 @@
package me.chanjar.weixin.cp.bean.messagebuilder;
import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.cp.bean.WxCpMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpMessage;
import me.chanjar.weixin.cp.bean.article.NewArticle;
import java.util.ArrayList;
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TaskCardBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TaskCardBuilder.java
index 3c2d77924..57a77503b 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TaskCardBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TaskCardBuilder.java
@@ -1,7 +1,7 @@
package me.chanjar.weixin.cp.bean.messagebuilder;
import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.cp.bean.WxCpMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpMessage;
import me.chanjar.weixin.cp.bean.taskcard.TaskCardButton;
import java.util.List;
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TextBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TextBuilder.java
index 5079b5f84..e072b9a79 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TextBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TextBuilder.java
@@ -1,7 +1,7 @@
package me.chanjar.weixin.cp.bean.messagebuilder;
import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.cp.bean.WxCpMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpMessage;
/**
* 文本消息builder
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TextCardBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TextCardBuilder.java
index 6cae763d1..306187ee4 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TextCardBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TextCardBuilder.java
@@ -1,7 +1,7 @@
package me.chanjar.weixin.cp.bean.messagebuilder;
import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.cp.bean.WxCpMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpMessage;
/**
*
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VideoBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VideoBuilder.java
index 8d4739940..2c7fab5c8 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VideoBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VideoBuilder.java
@@ -1,7 +1,7 @@
package me.chanjar.weixin.cp.bean.messagebuilder;
import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.cp.bean.WxCpMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpMessage;
/**
* 视频消息builder
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VoiceBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VoiceBuilder.java
index 33c36abcb..0e0b9f828 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VoiceBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VoiceBuilder.java
@@ -1,7 +1,7 @@
package me.chanjar.weixin.cp.bean.messagebuilder;
import me.chanjar.weixin.common.api.WxConsts;
-import me.chanjar.weixin.cp.bean.WxCpMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpMessage;
/**
* 语音消息builder
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/BaseBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/BaseBuilder.java
index 303ed3c46..90495a463 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/BaseBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/BaseBuilder.java
@@ -1,6 +1,6 @@
package me.chanjar.weixin.cp.bean.outxmlbuilder;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
public abstract class BaseBuilder {
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/ImageBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/ImageBuilder.java
index f8cd25f44..ded7e157e 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/ImageBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/ImageBuilder.java
@@ -1,6 +1,6 @@
package me.chanjar.weixin.cp.bean.outxmlbuilder;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutImageMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutImageMessage;
/**
* 图片消息builder
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/NewsBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/NewsBuilder.java
index 5a67056ab..190ab1c97 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/NewsBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/NewsBuilder.java
@@ -1,7 +1,7 @@
package me.chanjar.weixin.cp.bean.outxmlbuilder;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutNewsMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutNewsMessage.Item;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutNewsMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutNewsMessage.Item;
import java.util.ArrayList;
import java.util.Collections;
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/TextBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/TextBuilder.java
index dcdb58ca4..6a7086845 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/TextBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/TextBuilder.java
@@ -1,6 +1,6 @@
package me.chanjar.weixin.cp.bean.outxmlbuilder;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutTextMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutTextMessage;
/**
* 文本消息builder
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/VideoBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/VideoBuilder.java
index 7eb38ec1a..e823da746 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/VideoBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/VideoBuilder.java
@@ -1,6 +1,6 @@
package me.chanjar.weixin.cp.bean.outxmlbuilder;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutVideoMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutVideoMessage;
/**
* 视频消息builder
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/VoiceBuilder.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/VoiceBuilder.java
index 8bc13d9fe..2d1466124 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/VoiceBuilder.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/VoiceBuilder.java
@@ -1,6 +1,6 @@
package me.chanjar.weixin.cp.bean.outxmlbuilder;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutVoiceMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutVoiceMessage;
/**
* 语音消息builder
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpDefaultConfigImpl.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpDefaultConfigImpl.java
index a9b449530..80aca779d 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpDefaultConfigImpl.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/impl/WxCpDefaultConfigImpl.java
@@ -24,7 +24,7 @@ public class WxCpDefaultConfigImpl implements WxCpConfigStorage, Serializable {
private volatile String token;
protected volatile String accessToken;
- protected Lock accessTokenLock = new ReentrantLock();
+ protected transient Lock accessTokenLock = new ReentrantLock();
private volatile String aesKey;
protected volatile Integer agentId;
private volatile long expiresTime;
@@ -37,16 +37,16 @@ public class WxCpDefaultConfigImpl implements WxCpConfigStorage, Serializable {
private volatile String httpProxyPassword;
private volatile String jsapiTicket;
- protected Lock jsapiTicketLock = new ReentrantLock();
+ protected transient Lock jsapiTicketLock = new ReentrantLock();
private volatile long jsapiTicketExpiresTime;
private volatile String agentJsapiTicket;
- protected Lock agentJsapiTicketLock = new ReentrantLock();
+ protected transient Lock agentJsapiTicketLock = new ReentrantLock();
private volatile long agentJsapiTicketExpiresTime;
private volatile File tmpDirFile;
- private volatile ApacheHttpClientBuilder apacheHttpClientBuilder;
+ private transient volatile ApacheHttpClientBuilder apacheHttpClientBuilder;
private volatile String baseApiUrl;
@@ -297,4 +297,9 @@ public class WxCpDefaultConfigImpl implements WxCpConfigStorage, Serializable {
public void setApacheHttpClientBuilder(ApacheHttpClientBuilder apacheHttpClientBuilder) {
this.apacheHttpClientBuilder = apacheHttpClientBuilder;
}
+
+ public WxCpDefaultConfigImpl setWebhookKey(String webhookKey) {
+ this.webhookKey = webhookKey;
+ return this;
+ }
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java
index 00e7616d1..1f435303c 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpApiPathConsts.java
@@ -14,7 +14,6 @@ public final class WxCpApiPathConsts {
public static final String GET_JSAPI_TICKET = "/cgi-bin/get_jsapi_ticket";
public static final String GET_AGENT_CONFIG_TICKET = "/cgi-bin/ticket/get?&type=agent_config";
- public static final String MESSAGE_SEND = "/cgi-bin/message/send";
public static final String GET_CALLBACK_IP = "/cgi-bin/getcallbackip";
public static final String BATCH_REPLACE_PARTY = "/cgi-bin/batch/replaceparty";
public static final String BATCH_REPLACE_USER = "/cgi-bin/batch/replaceuser";
@@ -23,6 +22,22 @@ public final class WxCpApiPathConsts {
public static final String GET_TOKEN = "/cgi-bin/gettoken?corpid=%s&corpsecret=%s";
public static final String WEBHOOK_SEND = "/cgi-bin/webhook/send?key=";
+ /**
+ * 消息推送相关接口
+ * https://work.weixin.qq.com/api/doc/90000/90135/90235
+ */
+ public static class Message {
+ /**
+ * 发送应用消息
+ */
+ public static final String MESSAGE_SEND = "/cgi-bin/message/send";
+
+ /**
+ * 互联企业发送应用消息
+ */
+ public static final String LINKEDCORP_MESSAGE_SEND = "/cgi-bin/linkedcorp/message/send";
+ }
+
public static class Agent {
public static final String AGENT_GET = "/cgi-bin/agent/get?agentid=%d";
public static final String AGENT_SET = "/cgi-bin/agent/set";
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpConsts.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpConsts.java
index a69b8ea2e..5e536efa9 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpConsts.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/constant/WxCpConsts.java
@@ -166,6 +166,75 @@ public class WxCpConsts {
}
+ /**
+ * 互联企业发送应用消息的消息类型.
+ */
+ public static class LinkedCorpMsgType {
+ /**
+ * 文本消息.
+ */
+ public static final String TEXT = "text";
+ /**
+ * 图片消息.
+ */
+ public static final String IMAGE = "image";
+ /**
+ * 视频消息.
+ */
+ public static final String VIDEO = "video";
+ /**
+ * 图文消息(点击跳转到外链).
+ */
+ public static final String NEWS = "news";
+ /**
+ * 图文消息(点击跳转到图文消息页面).
+ */
+ public static final String MPNEWS = "mpnews";
+ /**
+ * markdown消息.
+ * (目前仅支持markdown语法的子集,微工作台(原企业号)不支持展示markdown消息)
+ */
+ public static final String MARKDOWN = "markdown";
+ /**
+ * 发送文件.
+ */
+ public static final String FILE = "file";
+ /**
+ * 文本卡片消息.
+ */
+ public static final String TEXTCARD = "textcard";
+
+ /**
+ * 小程序通知消息.
+ */
+ public static final String MINIPROGRAM_NOTICE = "miniprogram_notice";
+ }
+
+ /**
+ * 群机器人的消息类型.
+ */
+ public static class GroupRobotMsgType {
+ /**
+ * 文本消息.
+ */
+ public static final String TEXT = "text";
+
+ /**
+ * 图片消息.
+ */
+ public static final String IMAGE = "image";
+
+ /**
+ * markdown消息.
+ */
+ public static final String MARKDOWN = "markdown";
+
+ /**
+ * 图文消息(点击跳转到外链).
+ */
+ public static final String NEWS = "news";
+ }
+
/**
* 应用推送消息的消息类型.
*/
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageHandler.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageHandler.java
index 22074d6e7..68e38d3bb 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageHandler.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageHandler.java
@@ -3,8 +3,8 @@ package me.chanjar.weixin.cp.message;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.cp.api.WxCpService;
-import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
import java.util.Map;
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageInterceptor.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageInterceptor.java
index ab4c658e4..5bcca55ee 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageInterceptor.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageInterceptor.java
@@ -3,7 +3,7 @@ package me.chanjar.weixin.cp.message;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.cp.api.WxCpService;
-import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
import java.util.Map;
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageMatcher.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageMatcher.java
index 1bf36705b..42db8f5dd 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageMatcher.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageMatcher.java
@@ -1,6 +1,6 @@
package me.chanjar.weixin.cp.message;
-import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
/**
* 消息匹配器,用在消息路由的时候
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageRouter.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageRouter.java
index b5424be03..bf1ad6e5f 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageRouter.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageRouter.java
@@ -18,8 +18,8 @@ import me.chanjar.weixin.common.session.InternalSessionManager;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.common.util.LogExceptionHandler;
import me.chanjar.weixin.cp.api.WxCpService;
-import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
/**
*
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageRouterRule.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageRouterRule.java
index 8f3766a16..3c7b5c66f 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageRouterRule.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageRouterRule.java
@@ -4,8 +4,8 @@ import me.chanjar.weixin.common.api.WxErrorExceptionHandler;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.cp.api.WxCpService;
-import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XStreamTransformer.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XStreamTransformer.java
index 3c6174c9d..ea9023111 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XStreamTransformer.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XStreamTransformer.java
@@ -1,135 +1,135 @@
-package me.chanjar.weixin.cp.util.xml;
-
-import java.io.InputStream;
-import java.util.HashMap;
-import java.util.Map;
-
-import com.thoughtworks.xstream.XStream;
-import me.chanjar.weixin.common.util.xml.XStreamInitializer;
-import me.chanjar.weixin.cp.bean.WxCpTpXmlMessage;
-import me.chanjar.weixin.cp.bean.WxCpTpXmlPackage;
-import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutImageMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutNewsMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutTextMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutVideoMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutVoiceMessage;
-
-public class XStreamTransformer {
-
- protected static final Map CLASS_2_XSTREAM_INSTANCE = configXStreamInstance();
-
- /**
- * xml -> pojo
- */
- @SuppressWarnings("unchecked")
- public static T fromXml(Class clazz, String xml) {
- T object = (T) CLASS_2_XSTREAM_INSTANCE.get(clazz).fromXML(xml);
- return object;
- }
-
- @SuppressWarnings("unchecked")
- public static T fromXml(Class clazz, InputStream is) {
- T object = (T) CLASS_2_XSTREAM_INSTANCE.get(clazz).fromXML(is);
- return object;
- }
-
- /**
- * 注册扩展消息的解析器.
- *
- * @param clz 类型
- * @param xStream xml解析器
- */
- public static void register(Class clz, XStream xStream) {
- CLASS_2_XSTREAM_INSTANCE.put(clz, xStream);
- }
-
- /**
- * pojo -> xml.
- */
- public static String toXml(Class clazz, T object) {
- return CLASS_2_XSTREAM_INSTANCE.get(clazz).toXML(object);
- }
-
- private static Map configXStreamInstance() {
- Map map = new HashMap<>();
- map.put(WxCpXmlMessage.class, configWxCpXmlMessage());
- map.put(WxCpXmlOutNewsMessage.class, configWxCpXmlOutNewsMessage());
- map.put(WxCpXmlOutTextMessage.class, configWxCpXmlOutTextMessage());
- map.put(WxCpXmlOutImageMessage.class, configWxCpXmlOutImageMessage());
- map.put(WxCpXmlOutVideoMessage.class, configWxCpXmlOutVideoMessage());
- map.put(WxCpXmlOutVoiceMessage.class, configWxCpXmlOutVoiceMessage());
- map.put(WxCpTpXmlPackage.class, configWxCpTpXmlPackage());
- map.put(WxCpTpXmlMessage.class, configWxCpTpXmlMessage());
- return map;
- }
-
- private static XStream configWxCpXmlMessage() {
- XStream xstream = XStreamInitializer.getInstance();
-
- xstream.processAnnotations(WxCpXmlMessage.class);
- xstream.processAnnotations(WxCpXmlMessage.ScanCodeInfo.class);
- xstream.processAnnotations(WxCpXmlMessage.SendPicsInfo.class);
- xstream.processAnnotations(WxCpXmlMessage.SendPicsInfo.Item.class);
- xstream.processAnnotations(WxCpXmlMessage.SendLocationInfo.class);
- return xstream;
- }
-
- private static XStream configWxCpXmlOutImageMessage() {
- XStream xstream = XStreamInitializer.getInstance();
-
- xstream.processAnnotations(WxCpXmlOutMessage.class);
- xstream.processAnnotations(WxCpXmlOutImageMessage.class);
- return xstream;
- }
-
- private static XStream configWxCpXmlOutNewsMessage() {
- XStream xstream = XStreamInitializer.getInstance();
-
- xstream.processAnnotations(WxCpXmlOutMessage.class);
- xstream.processAnnotations(WxCpXmlOutNewsMessage.class);
- xstream.processAnnotations(WxCpXmlOutNewsMessage.Item.class);
- return xstream;
- }
-
- private static XStream configWxCpXmlOutTextMessage() {
- XStream xstream = XStreamInitializer.getInstance();
-
- xstream.processAnnotations(WxCpXmlOutMessage.class);
- xstream.processAnnotations(WxCpXmlOutTextMessage.class);
- return xstream;
- }
-
- private static XStream configWxCpXmlOutVideoMessage() {
- XStream xstream = XStreamInitializer.getInstance();
-
- xstream.processAnnotations(WxCpXmlOutMessage.class);
- xstream.processAnnotations(WxCpXmlOutVideoMessage.class);
- xstream.processAnnotations(WxCpXmlOutVideoMessage.Video.class);
- return xstream;
- }
-
- private static XStream configWxCpXmlOutVoiceMessage() {
- XStream xstream = XStreamInitializer.getInstance();
-
- xstream.processAnnotations(WxCpXmlOutMessage.class);
- xstream.processAnnotations(WxCpXmlOutVoiceMessage.class);
- return xstream;
- }
-
- private static XStream configWxCpTpXmlPackage() {
- XStream xstream = XStreamInitializer.getInstance();
- xstream.processAnnotations(WxCpTpXmlPackage.class);
-
- return xstream;
- }
-
- private static XStream configWxCpTpXmlMessage() {
- XStream xstream = XStreamInitializer.getInstance();
- xstream.processAnnotations(WxCpTpXmlMessage.class);
-
- return xstream;
- }
-
-}
+package me.chanjar.weixin.cp.util.xml;
+
+import java.io.InputStream;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.thoughtworks.xstream.XStream;
+import me.chanjar.weixin.common.util.xml.XStreamInitializer;
+import me.chanjar.weixin.cp.bean.message.WxCpTpXmlMessage;
+import me.chanjar.weixin.cp.bean.WxCpTpXmlPackage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutImageMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutNewsMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutTextMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutVideoMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutVoiceMessage;
+
+public class XStreamTransformer {
+
+ protected static final Map CLASS_2_XSTREAM_INSTANCE = configXStreamInstance();
+
+ /**
+ * xml -> pojo
+ */
+ @SuppressWarnings("unchecked")
+ public static T fromXml(Class clazz, String xml) {
+ T object = (T) CLASS_2_XSTREAM_INSTANCE.get(clazz).fromXML(xml);
+ return object;
+ }
+
+ @SuppressWarnings("unchecked")
+ public static T fromXml(Class clazz, InputStream is) {
+ T object = (T) CLASS_2_XSTREAM_INSTANCE.get(clazz).fromXML(is);
+ return object;
+ }
+
+ /**
+ * 注册扩展消息的解析器.
+ *
+ * @param clz 类型
+ * @param xStream xml解析器
+ */
+ public static void register(Class clz, XStream xStream) {
+ CLASS_2_XSTREAM_INSTANCE.put(clz, xStream);
+ }
+
+ /**
+ * pojo -> xml.
+ */
+ public static String toXml(Class clazz, T object) {
+ return CLASS_2_XSTREAM_INSTANCE.get(clazz).toXML(object);
+ }
+
+ private static Map configXStreamInstance() {
+ Map map = new HashMap<>();
+ map.put(WxCpXmlMessage.class, configWxCpXmlMessage());
+ map.put(WxCpXmlOutNewsMessage.class, configWxCpXmlOutNewsMessage());
+ map.put(WxCpXmlOutTextMessage.class, configWxCpXmlOutTextMessage());
+ map.put(WxCpXmlOutImageMessage.class, configWxCpXmlOutImageMessage());
+ map.put(WxCpXmlOutVideoMessage.class, configWxCpXmlOutVideoMessage());
+ map.put(WxCpXmlOutVoiceMessage.class, configWxCpXmlOutVoiceMessage());
+ map.put(WxCpTpXmlPackage.class, configWxCpTpXmlPackage());
+ map.put(WxCpTpXmlMessage.class, configWxCpTpXmlMessage());
+ return map;
+ }
+
+ private static XStream configWxCpXmlMessage() {
+ XStream xstream = XStreamInitializer.getInstance();
+
+ xstream.processAnnotations(WxCpXmlMessage.class);
+ xstream.processAnnotations(WxCpXmlMessage.ScanCodeInfo.class);
+ xstream.processAnnotations(WxCpXmlMessage.SendPicsInfo.class);
+ xstream.processAnnotations(WxCpXmlMessage.SendPicsInfo.Item.class);
+ xstream.processAnnotations(WxCpXmlMessage.SendLocationInfo.class);
+ return xstream;
+ }
+
+ private static XStream configWxCpXmlOutImageMessage() {
+ XStream xstream = XStreamInitializer.getInstance();
+
+ xstream.processAnnotations(WxCpXmlOutMessage.class);
+ xstream.processAnnotations(WxCpXmlOutImageMessage.class);
+ return xstream;
+ }
+
+ private static XStream configWxCpXmlOutNewsMessage() {
+ XStream xstream = XStreamInitializer.getInstance();
+
+ xstream.processAnnotations(WxCpXmlOutMessage.class);
+ xstream.processAnnotations(WxCpXmlOutNewsMessage.class);
+ xstream.processAnnotations(WxCpXmlOutNewsMessage.Item.class);
+ return xstream;
+ }
+
+ private static XStream configWxCpXmlOutTextMessage() {
+ XStream xstream = XStreamInitializer.getInstance();
+
+ xstream.processAnnotations(WxCpXmlOutMessage.class);
+ xstream.processAnnotations(WxCpXmlOutTextMessage.class);
+ return xstream;
+ }
+
+ private static XStream configWxCpXmlOutVideoMessage() {
+ XStream xstream = XStreamInitializer.getInstance();
+
+ xstream.processAnnotations(WxCpXmlOutMessage.class);
+ xstream.processAnnotations(WxCpXmlOutVideoMessage.class);
+ xstream.processAnnotations(WxCpXmlOutVideoMessage.Video.class);
+ return xstream;
+ }
+
+ private static XStream configWxCpXmlOutVoiceMessage() {
+ XStream xstream = XStreamInitializer.getInstance();
+
+ xstream.processAnnotations(WxCpXmlOutMessage.class);
+ xstream.processAnnotations(WxCpXmlOutVoiceMessage.class);
+ return xstream;
+ }
+
+ private static XStream configWxCpTpXmlPackage() {
+ XStream xstream = XStreamInitializer.getInstance();
+ xstream.processAnnotations(WxCpTpXmlPackage.class);
+
+ return xstream;
+ }
+
+ private static XStream configWxCpTpXmlMessage() {
+ XStream xstream = XStreamInitializer.getInstance();
+ xstream.processAnnotations(WxCpTpXmlMessage.class);
+
+ return xstream;
+ }
+
+}
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/ApiTestModule.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/ApiTestModule.java
index c15e3af4d..e5aa15193 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/ApiTestModule.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/ApiTestModule.java
@@ -1,22 +1,23 @@
package me.chanjar.weixin.cp.api;
-import java.io.IOException;
-import java.io.InputStream;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
import com.google.inject.Binder;
import com.google.inject.Module;
import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.util.xml.XStreamInitializer;
import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl;
import me.chanjar.weixin.cp.config.impl.WxCpDefaultConfigImpl;
+import java.io.IOException;
+import java.io.InputStream;
+
+@Slf4j
public class ApiTestModule implements Module {
- private final Logger log = LoggerFactory.getLogger(this.getClass());
private static final String TEST_CONFIG_XML = "test-config.xml";
+ protected WxXmlCpInMemoryConfigStorage config;
private static T fromXml(Class clazz, InputStream is) {
XStream xstream = XStreamInitializer.getInstance();
@@ -32,70 +33,27 @@ public class ApiTestModule implements Module {
throw new RuntimeException("测试配置文件【" + TEST_CONFIG_XML + "】未找到,请参照test-config-sample.xml文件生成");
}
- WxXmlCpInMemoryConfigStorage config = fromXml(WxXmlCpInMemoryConfigStorage.class, inputStream);
+ config = fromXml(WxXmlCpInMemoryConfigStorage.class, inputStream);
WxCpService wxService = new WxCpServiceImpl();
wxService.setWxCpConfigStorage(config);
binder.bind(WxCpService.class).toInstance(wxService);
binder.bind(WxXmlCpInMemoryConfigStorage.class).toInstance(config);
} catch (IOException e) {
- this.log.error(e.getMessage(), e);
+ log.error(e.getMessage(), e);
}
}
+ @Data
+ @EqualsAndHashCode(callSuper = true)
@XStreamAlias("xml")
public static class WxXmlCpInMemoryConfigStorage extends WxCpDefaultConfigImpl {
+ private static final long serialVersionUID = -4521839921547374822L;
protected String userId;
-
protected String departmentId;
-
protected String tagId;
-
protected String externalUserId;
-
- public String getUserId() {
- return this.userId;
- }
-
- public void setUserId(String userId) {
- this.userId = userId;
- }
-
- public String getDepartmentId() {
- return this.departmentId;
- }
-
- public void setDepartmentId(String departmentId) {
- this.departmentId = departmentId;
- }
-
- public String getTagId() {
- return this.tagId;
- }
-
- public void setTagId(String tagId) {
- this.tagId = tagId;
- }
-
- public String getExternalUserId() {
- return externalUserId;
- }
-
- public void setExternalUserId(String externalUserId) {
- this.externalUserId = externalUserId;
- }
-
- @Override
- public String toString() {
- return super.toString() + " > WxXmlCpConfigStorage{" +
- "userId='" + this.userId + '\'' +
- ", departmentId='" + this.departmentId + '\'' +
- ", tagId='" + this.tagId + '\'' +
- ", externalUserId='" + this.externalUserId + '\'' +
-
- '}';
- }
}
}
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/ApiTestModuleWithMockServer.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/ApiTestModuleWithMockServer.java
new file mode 100644
index 000000000..83f38612d
--- /dev/null
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/ApiTestModuleWithMockServer.java
@@ -0,0 +1,19 @@
+package me.chanjar.weixin.cp.api;
+
+import com.google.inject.Binder;
+
+/**
+ * 带mock server 的test module.
+ *
+ * @author Binary Wang
+ * @date 2020-08-30
+ */
+public class ApiTestModuleWithMockServer extends ApiTestModule {
+ public static final int mockServerPort = 8080;
+
+ @Override
+ public void configure(Binder binder) {
+ super.configure(binder);
+ super.config.setBaseApiUrl("http://localhost:" + mockServerPort);
+ }
+}
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 a21348895..112e9f8c3 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
@@ -6,8 +6,8 @@ import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.cp.message.WxCpMessageHandler;
import me.chanjar.weixin.cp.message.WxCpMessageMatcher;
import me.chanjar.weixin.cp.message.WxCpMessageRouter;
-import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
import org.testng.Assert;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImplTest.java
index 0056b88f7..56df47e36 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImplTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpChatServiceImplTest.java
@@ -11,7 +11,7 @@ import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.constant.WxCpConsts.AppChatMsgType;
import me.chanjar.weixin.cp.api.ApiTestModule;
import me.chanjar.weixin.cp.api.WxCpService;
-import me.chanjar.weixin.cp.bean.WxCpAppChatMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpAppChatMessage;
import me.chanjar.weixin.cp.bean.WxCpChat;
import me.chanjar.weixin.cp.bean.article.MpnewsArticle;
import me.chanjar.weixin.cp.bean.article.NewArticle;
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpGroupRobotServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpGroupRobotServiceImplTest.java
index b697efd53..40597fa24 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpGroupRobotServiceImplTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpGroupRobotServiceImplTest.java
@@ -16,8 +16,6 @@ import java.io.InputStream;
import java.util.stream.Collectors;
import java.util.stream.Stream;
-import static org.testng.Assert.*;
-
/**
* 微信群机器人消息发送api 单元测试
*
@@ -62,7 +60,8 @@ public class WxCpGroupRobotServiceImplTest {
@Test
public void testSendNews() throws WxErrorException {
- NewArticle article = new NewArticle("图文消息测试","hello world","http://www.baidu.com","http://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png");
+ NewArticle article = new NewArticle("图文消息测试", "hello world", "http://www.baidu.com",
+ "http://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png", null);
robotService.sendNews(Stream.of(article).collect(Collectors.toList()));
}
}
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/impl/WxCpMessageServiceImplTest.java
similarity index 59%
rename from weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageAPITest.java
rename to weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpMessageServiceImplTest.java
index d0984565a..8f02df1fc 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/impl/WxCpMessageServiceImplTest.java
@@ -1,33 +1,54 @@
-package me.chanjar.weixin.cp.api;
+package me.chanjar.weixin.cp.api.impl;
+import com.github.dreamhead.moco.HttpServer;
+import com.github.dreamhead.moco.Runner;
import com.google.common.collect.ImmutableMap;
-import org.testng.annotations.*;
-
import com.google.inject.Inject;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.error.WxErrorException;
-import me.chanjar.weixin.cp.bean.WxCpMessage;
-import me.chanjar.weixin.cp.bean.WxCpMessageSendResult;
+import me.chanjar.weixin.cp.api.ApiTestModule;
+import me.chanjar.weixin.cp.api.ApiTestModuleWithMockServer;
+import me.chanjar.weixin.cp.api.WxCpService;
+import me.chanjar.weixin.cp.bean.message.WxCpLinkedCorpMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpMessageSendResult;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Guice;
+import org.testng.annotations.Test;
-import static org.testng.Assert.*;
+import static com.github.dreamhead.moco.Moco.file;
+import static com.github.dreamhead.moco.MocoJsonRunner.jsonHttpServer;
+import static me.chanjar.weixin.cp.api.ApiTestModuleWithMockServer.mockServerPort;
+import static org.testng.Assert.assertNotNull;
-/***
- * 测试发送消息
- * @author Daniel Qian
+/**
+ * 测试类.
*
+ * @author Binary Wang
+ * @date 2020-08-30
*/
@Test
-@Guice(modules = ApiTestModule.class)
-public class WxCpMessageAPITest {
-
+@Guice(modules = ApiTestModuleWithMockServer.class)
+//@Guice(modules = ApiTestModule.class)
+public class WxCpMessageServiceImplTest {
@Inject
protected WxCpService wxService;
+ private Runner mockRunner;
private ApiTestModule.WxXmlCpInMemoryConfigStorage configStorage;
@BeforeTest
public void setup() {
- configStorage = (ApiTestModule.WxXmlCpInMemoryConfigStorage) this.wxService.getWxCpConfigStorage();
+ HttpServer mockServer = jsonHttpServer(mockServerPort, file("src/test/resources/moco/message.json"));
+ this.mockRunner = Runner.runner(mockServer);
+ this.mockRunner.start();
+ this.configStorage = (ApiTestModule.WxXmlCpInMemoryConfigStorage) this.wxService.getWxCpConfigStorage();
+ }
+
+ @AfterTest
+ public void stopMockServer() {
+ this.mockRunner.stop();
}
public void testSendMessage() throws WxErrorException {
@@ -37,7 +58,7 @@ public class WxCpMessageAPITest {
message.setToUser(configStorage.getUserId());
message.setContent("欢迎欢迎,热烈欢迎\n换行测试\n超链接:Hello World");
- WxCpMessageSendResult messageSendResult = this.wxService.messageSend(message);
+ WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().send(message);
assertNotNull(messageSendResult);
System.out.println(messageSendResult);
System.out.println(messageSendResult.getInvalidPartyList());
@@ -54,7 +75,7 @@ public class WxCpMessageAPITest {
.content("欢迎欢迎,热烈欢迎\n换行测试\n超链接:Hello World")
.build();
- WxCpMessageSendResult messageSendResult = this.wxService.messageSend(message);
+ WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().send(message);
assertNotNull(messageSendResult);
System.out.println(messageSendResult);
System.out.println(messageSendResult.getInvalidPartyList());
@@ -82,7 +103,7 @@ public class WxCpMessageAPITest {
" >如需修改会议信息,请点击:[修改会议信息](https://work.weixin.qq.com)")
.build();
- WxCpMessageSendResult messageSendResult = this.wxService.messageSend(message);
+ WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().send(message);
assertNotNull(messageSendResult);
System.out.println(messageSendResult);
System.out.println(messageSendResult.getInvalidPartyList());
@@ -96,12 +117,12 @@ public class WxCpMessageAPITest {
.TEXTCARD()
.toUser(configStorage.getUserId())
.btnTxt("更多")
- .description( "2016年9月26日
恭喜你抽中iPhone 7一台,领奖码:xxxx
请于2016年10月10日前联系行政同事领取
")
+ .description("2016年9月26日
恭喜你抽中iPhone 7一台,领奖码:xxxx
请于2016年10月10日前联系行政同事领取
")
.url("URL")
.title("领奖通知")
.build();
- WxCpMessageSendResult messageSendResult = this.wxService.messageSend(message);
+ WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().send(message);
assertNotNull(messageSendResult);
System.out.println(messageSendResult);
System.out.println(messageSendResult.getInvalidPartyList());
@@ -110,7 +131,7 @@ public class WxCpMessageAPITest {
}
@Test
- public void testSendMessage_miniprogram_notice() throws WxErrorException {
+ public void testSendMessage_miniProgram_notice() throws WxErrorException {
WxCpMessage message = WxCpMessage
.newMiniProgramNoticeBuilder()
.toUser(configStorage.getUserId())
@@ -119,16 +140,25 @@ public class WxCpMessageAPITest {
.title("会议室预订成功通知")
.description("4月27日 16:16")
.emphasisFirstItem(true)
- .contentItems(ImmutableMap.of("会议室","402",
- "会议地点","广州TIT-402会议室",
- "会议时间","2018年8月1日 09:00-09:30"))
+ .contentItems(ImmutableMap.of("会议室", "402",
+ "会议地点", "广州TIT-402会议室",
+ "会议时间", "2018年8月1日 09:00-09:30"))
.build();
- WxCpMessageSendResult messageSendResult = this.wxService.messageSend(message);
+ WxCpMessageSendResult messageSendResult = this.wxService.getMessageService().send(message);
assertNotNull(messageSendResult);
System.out.println(messageSendResult);
System.out.println(messageSendResult.getInvalidPartyList());
System.out.println(messageSendResult.getInvalidUserList());
System.out.println(messageSendResult.getInvalidTagList());
}
+
+ @Test
+ public void testLinkedCorpMessageSend() throws WxErrorException {
+ this.wxService.getMessageService().sendLinkedCorpMessage(WxCpLinkedCorpMessage.builder()
+ .msgType(WxConsts.KefuMsgType.TEXT)
+ .toUsers(new String[]{configStorage.getUserId()})
+ .content("欢迎欢迎,热烈欢迎\n换行测试\n超链接:Hello World")
+ .build());
+ }
}
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImplTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImplTest.java
index be387548b..1bdcb9e24 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImplTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpTaskCardServiceImplTest.java
@@ -4,8 +4,8 @@ import com.google.inject.Inject;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.cp.api.ApiTestModule;
import me.chanjar.weixin.cp.api.WxCpService;
-import me.chanjar.weixin.cp.bean.WxCpMessage;
-import me.chanjar.weixin.cp.bean.WxCpMessageSendResult;
+import me.chanjar.weixin.cp.bean.message.WxCpMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpMessageSendResult;
import me.chanjar.weixin.cp.bean.taskcard.TaskCardButton;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
@@ -49,7 +49,7 @@ public class WxCpTaskCardServiceImplTest {
.buttons(Arrays.asList(btn1, btn2))
.build();
- WxCpMessageSendResult messageSendResult = this.wxCpService.messageSend(message);
+ WxCpMessageSendResult messageSendResult = this.wxCpService.getMessageService().send(message);
assertNotNull(messageSendResult);
System.out.println(messageSendResult);
System.out.println(messageSendResult.getInvalidPartyList());
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpLinkedCorpMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpLinkedCorpMessageTest.java
new file mode 100644
index 000000000..d692d0fc9
--- /dev/null
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpLinkedCorpMessageTest.java
@@ -0,0 +1,374 @@
+package me.chanjar.weixin.cp.bean.message;
+
+import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Lists;
+import me.chanjar.weixin.common.api.WxConsts;
+import me.chanjar.weixin.common.util.json.GsonParser;
+import me.chanjar.weixin.cp.bean.article.MpnewsArticle;
+import me.chanjar.weixin.cp.bean.article.NewArticle;
+import org.testng.annotations.Test;
+
+import static me.chanjar.weixin.common.api.WxConsts.*;
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * 测试用例中的json参考 https://work.weixin.qq.com/api/doc/90000/90135/90250
+ *
+ * @author Binary Wang
+ * @date 2020-08-30
+ */
+public class WxCpLinkedCorpMessageTest {
+
+ @Test
+ public void testToJson_text() {
+ WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder()
+ .msgType(KefuMsgType.TEXT)
+ .toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"})
+ .toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"})
+ .toTags(new String[]{"tagid1", "tagid2"})
+ .agentId(1)
+ .isToAll(false)
+ .isSafe(false)
+ .content("你的快递已到,请携带工卡前往邮件中心领取。\n出发前可查看邮件中心视频实况,聪明避开排队。")
+ .build();
+
+ final String json = message.toJson();
+ String expectedJson = "{\n" +
+ " \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" +
+ " \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" +
+ " \"totag\" : [\"tagid1\",\"tagid2\"],\n" +
+ " \"toall\" : 0,\n" +
+ " \"msgtype\" : \"text\",\n" +
+ " \"agentid\" : 1,\n" +
+ " \"text\" : {\n" +
+ " \"content\" : \"你的快递已到,请携带工卡前往邮件中心领取。\\n出发前可查看邮件中心视频实况,聪明避开排队。\"\n" +
+ " },\n" +
+ " \"safe\":0\n" +
+ "}";
+
+ assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString());
+ }
+
+ @Test
+ public void testToJson_image() {
+ WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder()
+ .msgType(KefuMsgType.IMAGE)
+ .toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"})
+ .toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"})
+ .toTags(new String[]{"tagid1", "tagid2"})
+ .agentId(1)
+ .isToAll(false)
+ .isSafe(false)
+ .mediaId("MEDIA_ID")
+ .build();
+
+ final String json = message.toJson();
+ String expectedJson = "{\n" +
+ " \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" +
+ " \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" +
+ " \"totag\" : [\"tagid1\",\"tagid2\"],\n" +
+ " \"toall\" : 0,\n" +
+ " \"msgtype\" : \"image\",\n" +
+ " \"agentid\" : 1,\n" +
+ " \"image\" : {\n" +
+ " \"media_id\" : \"MEDIA_ID\"\n" +
+ " },\n" +
+ " \"safe\":0\n" +
+ "}";
+
+ assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString());
+ }
+
+ @Test
+ public void testToJson_video() {
+ WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder()
+ .msgType(KefuMsgType.VIDEO)
+ .toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"})
+ .toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"})
+ .toTags(new String[]{"tagid1", "tagid2"})
+ .agentId(1)
+ .isToAll(false)
+ .isSafe(false)
+ .mediaId("MEDIA_ID")
+ .title("Title")
+ .description("Description")
+ .build();
+
+ final String json = message.toJson();
+ String expectedJson = "{\n" +
+ " \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" +
+ " \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" +
+ " \"totag\" : [\"tagid1\",\"tagid2\"],\n" +
+ " \"toall\" : 0,\n" +
+ " \"msgtype\" : \"video\",\n" +
+ " \"agentid\" : 1,\n" +
+ " \"video\" : {\n" +
+ " \"media_id\" : \"MEDIA_ID\",\n" +
+ " \"title\" : \"Title\",\n" +
+ " \"description\" : \"Description\"\n" +
+ " },\n" +
+ " \"safe\":0\n" +
+ "}\n";
+
+ assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString());
+ }
+
+ @Test
+ public void testToJson_file() {
+ WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder()
+ .msgType(KefuMsgType.FILE)
+ .toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"})
+ .toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"})
+ .toTags(new String[]{"tagid1", "tagid2"})
+ .agentId(1)
+ .isToAll(false)
+ .isSafe(false)
+ .mediaId("1Yv-zXfHjSjU-7LH-GwtYqDGS-zz6w22KmWAT5COgP7o")
+ .build();
+
+ final String json = message.toJson();
+ String expectedJson = "{\n" +
+ " \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" +
+ " \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" +
+ " \"totag\" : [\"tagid1\",\"tagid2\"],\n" +
+ " \"toall\" : 0,\n" +
+ " \"msgtype\" : \"file\",\n" +
+ " \"agentid\" : 1,\n" +
+ " \"file\" : {\n" +
+ " \"media_id\" : \"1Yv-zXfHjSjU-7LH-GwtYqDGS-zz6w22KmWAT5COgP7o\"\n" +
+ " },\n" +
+ " \"safe\":0\n" +
+ "}\n";
+
+ assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString());
+ }
+
+ @Test
+ public void testToJson_textCard() {
+ WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder()
+ .msgType(KefuMsgType.TEXTCARD)
+ .toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"})
+ .toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"})
+ .toTags(new String[]{"tagid1", "tagid2"})
+ .agentId(1)
+ .isToAll(false)
+ .title("领奖通知")
+ .description("2016年9月26日
恭喜你抽中iPhone 7一台,领奖码:xxxx
请于2016年10月10日前联系行政同事领取
")
+ .url("URL")
+ .btnTxt("更多")
+ .build();
+
+ final String json = message.toJson();
+ String expectedJson = "{\n" +
+ " \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" +
+ " \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" +
+ " \"totag\" : [\"tagid1\",\"tagid2\"],\n" +
+ " \"toall\" : 0,\n" +
+ " \"msgtype\" : \"textcard\",\n" +
+ " \"agentid\" : 1,\n" +
+ " \"textcard\" : {\n" +
+ " \"title\" : \"领奖通知\",\n" +
+ " \"description\" : \"2016年9月26日
恭喜你抽中iPhone 7一台,领奖码:xxxx
请于2016年10月10日前联系行政同事领取
\",\n" +
+ " \"url\" : \"URL\",\n" +
+ " \"btntxt\":\"更多\"\n" +
+ " }\n" +
+ "}\n";
+
+ assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString());
+ }
+
+ @Test
+ public void testToJson_news() {
+ WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder()
+ .msgType(KefuMsgType.NEWS)
+ .toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"})
+ .toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"})
+ .toTags(new String[]{"tagid1", "tagid2"})
+ .agentId(1)
+ .isToAll(false)
+ .articles(Lists.newArrayList(NewArticle.builder()
+ .title("中秋节礼品领取")
+ .description("今年中秋节公司有豪礼相送")
+ .url("URL")
+ .picUrl("http://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png")
+ .btnText("更多")
+ .build()))
+ .build();
+
+ final String json = message.toJson();
+ String expectedJson = "{\n" +
+ " \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" +
+ " \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" +
+ " \"totag\" : [\"tagid1\",\"tagid2\"],\n" +
+ " \"toall\" : 0,\n" +
+ " \"msgtype\" : \"news\",\n" +
+ " \"agentid\" : 1,\n" +
+ " \"news\" : {\n" +
+ " \"articles\" : [\n" +
+ " {\n" +
+ " \"title\" : \"中秋节礼品领取\",\n" +
+ " \"description\" : \"今年中秋节公司有豪礼相送\",\n" +
+ " \"url\" : \"URL\",\n" +
+ " \"picurl\" : \"http://res.mail.qq.com/node/ww/wwopenmng/images/independent/doc/test_pic_msg1.png\",\n" +
+ " \"btntxt\":\"更多\"\n" +
+ " }\n" +
+ " ]\n" +
+ " }\n" +
+ "}\n";
+
+ assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString());
+ }
+
+
+ @Test
+ public void testToJson_mpnews() {
+ WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder()
+ .msgType(KefuMsgType.MPNEWS)
+ .toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"})
+ .toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"})
+ .toTags(new String[]{"tagid1", "tagid2"})
+ .agentId(1)
+ .isToAll(false)
+ .isSafe(false)
+ .mpNewsArticles(Lists.newArrayList(MpnewsArticle.newBuilder()
+ .title("Title")
+ .thumbMediaId("MEDIA_ID")
+ .author("Author")
+ .contentSourceUrl("URL")
+ .content("Content")
+ .digest("Digest description")
+ .build()))
+ .build();
+
+ final String json = message.toJson();
+ String expectedJson = "{\n" +
+ " \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" +
+ " \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" +
+ " \"totag\" : [\"tagid1\",\"tagid2\"],\n" +
+ " \"toall\" : 0,\n" +
+ " \"msgtype\" : \"mpnews\",\n" +
+ " \"agentid\" : 1,\n" +
+ " \"mpnews\" : {\n" +
+ " \"articles\":[\n" +
+ " {\n" +
+ " \"title\": \"Title\", \n" +
+ " \"thumb_media_id\": \"MEDIA_ID\",\n" +
+ " \"author\": \"Author\",\n" +
+ " \"content_source_url\": \"URL\",\n" +
+ " \"content\": \"Content\",\n" +
+ " \"digest\": \"Digest description\"\n" +
+ " }\n" +
+ " ]\n" +
+ " },\n" +
+ " \"safe\":0\n" +
+ "}\n";
+
+ assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString());
+ }
+
+ @Test
+ public void testToJson_markdown() {
+ WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder()
+ .msgType(KefuMsgType.MARKDOWN)
+ .toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"})
+ .toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"})
+ .toTags(new String[]{"tagid1", "tagid2"})
+ .agentId(1)
+ .isToAll(false)
+ .content("您的会议室已经预定,稍后会同步到`邮箱`\n" +
+ " >**事项详情**\n" +
+ " >事 项:开会\n" +
+ " >组织者:@miglioguan\n" +
+ " >参与者:@miglioguan、@kunliu、@jamdeezhou、@kanexiong、@kisonwang\n" +
+ " >\n" +
+ " >会议室:广州TIT 1楼 301\n" +
+ " >日 期:2018年5月18日\n" +
+ " >时 间:上午9:00-11:00\n" +
+ " >\n" +
+ " >请准时参加会议。\n" +
+ " >\n" +
+ " >如需修改会议信息,请点击:[修改会议信息](https://work.weixin.qq.com)")
+ .build();
+
+ final String json = message.toJson();
+ String expectedJson = "{\n" +
+ " \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" +
+ " \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" +
+ " \"totag\" : [\"tagid1\",\"tagid2\"],\n" +
+ " \"toall\" : 0,\n" +
+ " \"msgtype\" : \"markdown\",\n" +
+ " \"agentid\" : 1,\n" +
+ " \"markdown\": {\n" +
+ " \"content\": \"您的会议室已经预定,稍后会同步到`邮箱`\n" +
+ " >**事项详情**\n" +
+ " >事 项:开会\n" +
+ " >组织者:@miglioguan\n" +
+ " >参与者:@miglioguan、@kunliu、@jamdeezhou、@kanexiong、@kisonwang\n" +
+ " >\n" +
+ " >会议室:广州TIT 1楼 301\n" +
+ " >日 期:2018年5月18日\n" +
+ " >时 间:上午9:00-11:00\n" +
+ " >\n" +
+ " >请准时参加会议。\n" +
+ " >\n" +
+ " >如需修改会议信息,请点击:[修改会议信息](https://work.weixin.qq.com)\"\n" +
+ " }\n" +
+ "}\n";
+
+ assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString());
+ }
+
+ @Test
+ public void testToJson_miniProgramNotice() {
+ WxCpLinkedCorpMessage message = WxCpLinkedCorpMessage.builder()
+ .msgType(KefuMsgType.MINIPROGRAM_NOTICE)
+ .toUsers(new String[]{"userid1", "userid2", "CorpId1/userid1", "CorpId2/userid2"})
+ .toParties(new String[]{"partyid1", "partyid2", "LinkedId1/partyid1", "LinkedId2/partyid2"})
+ .toTags(new String[]{"tagid1", "tagid2"})
+ .emphasisFirstItem(true)
+ .description("4月27日 16:16")
+ .title("会议室预订成功通知")
+ .appId("wx123123123123123")
+ .page("pages/index?userid=zhangsan&orderid=123123123")
+ .contentItems(ImmutableMap.of("会议室","402",
+ "会议地点","广州TIT-402会议室",
+ "会议时间","2018年8月1日 09:00-09:30",
+ "参与人员","周剑轩"))
+ .build();
+
+ final String json = message.toJson();
+ String expectedJson = "{\n" +
+ " \"touser\" : [\"userid1\",\"userid2\",\"CorpId1/userid1\",\"CorpId2/userid2\"],\n" +
+ " \"toparty\" : [\"partyid1\",\"partyid2\",\"LinkedId1/partyid1\",\"LinkedId2/partyid2\"],\n" +
+ " \"totag\" : [\"tagid1\",\"tagid2\"],\n" +
+ " \"msgtype\" : \"miniprogram_notice\",\n" +
+ " \"miniprogram_notice\" : {\n" +
+ " \"appid\": \"wx123123123123123\",\n" +
+ " \"page\": \"pages/index?userid=zhangsan&orderid=123123123\",\n" +
+ " \"title\": \"会议室预订成功通知\",\n" +
+ " \"description\": \"4月27日 16:16\",\n" +
+ " \"emphasis_first_item\": true,\n" +
+ " \"content_item\": [\n" +
+ " {\n" +
+ " \"key\": \"会议室\",\n" +
+ " \"value\": \"402\"\n" +
+ " },\n" +
+ " {\n" +
+ " \"key\": \"会议地点\",\n" +
+ " \"value\": \"广州TIT-402会议室\"\n" +
+ " },\n" +
+ " {\n" +
+ " \"key\": \"会议时间\",\n" +
+ " \"value\": \"2018年8月1日 09:00-09:30\"\n" +
+ " },\n" +
+ " {\n" +
+ " \"key\": \"参与人员\",\n" +
+ " \"value\": \"周剑轩\"\n" +
+ " }\n" +
+ " ]\n" +
+ " }\n" +
+ "}\n";
+
+ assertThat(json).isEqualTo(GsonParser.parse(expectedJson).toString());
+ }
+}
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpMessageTest.java
similarity index 98%
rename from weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java
rename to weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpMessageTest.java
index c54211758..3f7859116 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpMessageTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpMessageTest.java
@@ -1,7 +1,8 @@
-package me.chanjar.weixin.cp.bean;
+package me.chanjar.weixin.cp.bean.message;
import me.chanjar.weixin.cp.bean.article.MpnewsArticle;
import me.chanjar.weixin.cp.bean.article.NewArticle;
+import me.chanjar.weixin.cp.bean.message.WxCpMessage;
import me.chanjar.weixin.cp.bean.taskcard.TaskCardButton;
import org.testng.annotations.Test;
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlMessageTest.java
similarity index 99%
rename from weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlMessageTest.java
rename to weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlMessageTest.java
index 0a9f17a62..044e364b6 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlMessageTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlMessageTest.java
@@ -1,6 +1,7 @@
-package me.chanjar.weixin.cp.bean;
+package me.chanjar.weixin.cp.bean.message;
import me.chanjar.weixin.common.api.WxConsts;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
import me.chanjar.weixin.cp.constant.WxCpConsts;
import me.chanjar.weixin.cp.util.xml.XStreamTransformer;
import org.testng.annotations.Test;
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutImageMessageTest.java
similarity index 89%
rename from weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessageTest.java
rename to weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutImageMessageTest.java
index 87c9454c9..0ecbec67d 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessageTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutImageMessageTest.java
@@ -1,5 +1,7 @@
-package me.chanjar.weixin.cp.bean;
+package me.chanjar.weixin.cp.bean.message;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutImageMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
import org.testng.Assert;
import org.testng.annotations.Test;
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutNewsMessageTest.java
similarity index 95%
rename from weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessageTest.java
rename to weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutNewsMessageTest.java
index 128bc9a4c..b0d3efabd 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessageTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutNewsMessageTest.java
@@ -1,5 +1,7 @@
-package me.chanjar.weixin.cp.bean;
+package me.chanjar.weixin.cp.bean.message;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutNewsMessage;
import org.testng.Assert;
import org.testng.annotations.Test;
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutTextMessageTest.java
similarity index 89%
rename from weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessageTest.java
rename to weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutTextMessageTest.java
index fd09ed6b9..68945f826 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessageTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutTextMessageTest.java
@@ -1,5 +1,7 @@
-package me.chanjar.weixin.cp.bean;
+package me.chanjar.weixin.cp.bean.message;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutTextMessage;
import org.testng.Assert;
import org.testng.annotations.Test;
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutVideoMessageTest.java
similarity index 91%
rename from weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessageTest.java
rename to weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutVideoMessageTest.java
index c5551dec0..7077ceeed 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessageTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutVideoMessageTest.java
@@ -1,5 +1,7 @@
-package me.chanjar.weixin.cp.bean;
+package me.chanjar.weixin.cp.bean.message;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutVideoMessage;
import org.testng.Assert;
import org.testng.annotations.Test;
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessageTest.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutVoiceMessageTest.java
similarity index 89%
rename from weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessageTest.java
rename to weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutVoiceMessageTest.java
index a3c9688c4..9c0348600 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessageTest.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/message/WxCpXmlOutVoiceMessageTest.java
@@ -1,5 +1,7 @@
-package me.chanjar.weixin.cp.bean;
+package me.chanjar.weixin.cp.bean.message;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutVoiceMessage;
import org.testng.Assert;
import org.testng.annotations.Test;
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoServer.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoServer.java
index df656a68a..2067e03eb 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoServer.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoServer.java
@@ -13,9 +13,9 @@ import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.cp.constant.WxCpConsts;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl;
-import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutTextMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutTextMessage;
import me.chanjar.weixin.cp.config.WxCpConfigStorage;
import me.chanjar.weixin.cp.message.WxCpMessageHandler;
import me.chanjar.weixin.cp.message.WxCpMessageRouter;
diff --git a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpEndpointServlet.java b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpEndpointServlet.java
index 291cef403..3f48c3213 100644
--- a/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpEndpointServlet.java
+++ b/weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpEndpointServlet.java
@@ -3,8 +3,8 @@ package me.chanjar.weixin.cp.demo;
import me.chanjar.weixin.cp.config.WxCpConfigStorage;
import me.chanjar.weixin.cp.message.WxCpMessageRouter;
import me.chanjar.weixin.cp.api.WxCpService;
-import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
-import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlMessage;
+import me.chanjar.weixin.cp.bean.message.WxCpXmlOutMessage;
import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil;
import org.apache.commons.lang3.StringUtils;
diff --git a/weixin-java-cp/src/test/resources/moco/message.json b/weixin-java-cp/src/test/resources/moco/message.json
new file mode 100644
index 000000000..b6b333c11
--- /dev/null
+++ b/weixin-java-cp/src/test/resources/moco/message.json
@@ -0,0 +1,26 @@
+[
+ {
+ "request": {
+ "uri": "/cgi-bin/gettoken"
+ },
+ "response": {
+ "text": "{\"errcode\":0,\"errmsg\":\"ok\",\"access_token\":\"oG1MrhLSzGBl4YxM1W2EHJlL_5vAotNwQ6KBp98sP2fO8XGPPRUlWS9w98CKjxSgPx4YnTy0DU_DvmNXAwt3mSDJ1Uhg_WCFrxX8GWbbCRlzrj2csK-1Y3tzI6dBCMa2YmblBo2sX7qkkzc9pnjP38GzO7Yuo_Bbpyi4doilNWZme0z9ovwiBCkAtV7DXYuh14EsnNrODG454kstOxsqWA\",\"expires_in\":7200}"
+ }
+ },
+ {
+ "request": {
+ "uri": "/cgi-bin/message/send"
+ },
+ "response": {
+ "text": "{\"errcode\":0,\"errmsg\":\"ok\",\"invaliduser\":\"\"}"
+ }
+ },
+ {
+ "request": {
+ "uri": "/cgi-bin/linkedcorp/message/send"
+ },
+ "response": {
+ "text": "{\"errcode\":0,\"errmsg\":\"ok\",\"invaliduser\":\"\"}"
+ }
+ }
+]
diff --git a/weixin-java-cp/src/test/resources/testng.xml b/weixin-java-cp/src/test/resources/testng.xml
index 563928bdf..cfccea89b 100644
--- a/weixin-java-cp/src/test/resources/testng.xml
+++ b/weixin-java-cp/src/test/resources/testng.xml
@@ -12,13 +12,13 @@
-
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendRedpackRequest.zip b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendRedpackRequest.zip
deleted file mode 100644
index b02696333..000000000
Binary files a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/request/WxPaySendRedpackRequest.zip and /dev/null differ