diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/WxMessageDuplicateChecker.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/WxMessageDuplicateChecker.java
index 21f21c5d4..1abe588b0 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/WxMessageDuplicateChecker.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/WxMessageDuplicateChecker.java
@@ -9,10 +9,19 @@ package me.chanjar.weixin.common.util;
public interface WxMessageDuplicateChecker {
/**
- * 检查消息ID是否重复
- * @param wxMsgId
+ *
公众号的排重方式
+ *
+ * 普通消息:关于重试的消息排重,推荐使用msgid排重。文档参考。
+ * 事件消息:关于重试的消息排重,推荐使用FromUserName + CreateTime 排重。文档参考
+ *
+ * 企业号的排重方式
+ *
+ * 官方文档完全没有写,参照公众号的方式排重。
+ *
+ * 或者可以采取更简单的方式,如果有MsgId就用MsgId排重,如果没有就用FromUserName+CreateTime排重
+ * @param messageId messageId需要根据上面讲的方式构造
* @return 如果是重复消息,返回true,否则返回false
*/
- public boolean isDuplicate(Long wxMsgId);
+ public boolean isDuplicate(String messageId);
}
diff --git a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/WxMessageInMemoryDuplicateChecker.java b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/WxMessageInMemoryDuplicateChecker.java
index f132ca541..ae0e06231 100644
--- a/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/WxMessageInMemoryDuplicateChecker.java
+++ b/weixin-java-common/src/main/java/me/chanjar/weixin/common/util/WxMessageInMemoryDuplicateChecker.java
@@ -25,7 +25,7 @@ public class WxMessageInMemoryDuplicateChecker implements WxMessageDuplicateChec
/**
* 消息id->消息时间戳的map
*/
- private final ConcurrentHashMap msgId2Timestamp = new ConcurrentHashMap();
+ private final ConcurrentHashMap msgId2Timestamp = new ConcurrentHashMap();
/**
* 后台清理线程是否已经开启
@@ -65,7 +65,7 @@ public class WxMessageInMemoryDuplicateChecker implements WxMessageDuplicateChec
while (true) {
Thread.sleep(clearPeriod);
Long now = System.currentTimeMillis();
- for (Map.Entry entry : msgId2Timestamp.entrySet()) {
+ for (Map.Entry entry : msgId2Timestamp.entrySet()) {
if (now - entry.getValue() > timeToLive) {
msgId2Timestamp.entrySet().remove(entry);
}
@@ -81,12 +81,12 @@ public class WxMessageInMemoryDuplicateChecker implements WxMessageDuplicateChec
}
@Override
- public boolean isDuplicate(Long wxMsgId) {
- if (wxMsgId == null) {
+ public boolean isDuplicate(String messageId) {
+ if (messageId == null) {
return false;
}
checkBackgroundProcessStarted();
- Long timestamp = msgId2Timestamp.putIfAbsent(wxMsgId, System.currentTimeMillis());
+ Long timestamp = msgId2Timestamp.putIfAbsent(messageId, System.currentTimeMillis());
if (timestamp == null) {
// 第一次接收到这个消息
return false;
diff --git a/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/WxMessageInMemoryDuplicateCheckerTest.java b/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/WxMessageInMemoryDuplicateCheckerTest.java
index 55e990701..28642c44d 100644
--- a/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/WxMessageInMemoryDuplicateCheckerTest.java
+++ b/weixin-java-common/src/test/java/me/chanjar/weixin/common/util/WxMessageInMemoryDuplicateCheckerTest.java
@@ -12,21 +12,21 @@ public class WxMessageInMemoryDuplicateCheckerTest {
// 第一次检查
for (Long msgId : msgIds) {
- boolean result = checker.isDuplicate(msgId);
+ boolean result = checker.isDuplicate(String.valueOf(msgId));
Assert.assertFalse(result);
}
// 过1秒再检查
Thread.sleep(1000l);
for (Long msgId : msgIds) {
- boolean result = checker.isDuplicate(msgId);
+ boolean result = checker.isDuplicate(String.valueOf(msgId));
Assert.assertTrue(result);
}
// 过1.5秒再检查
Thread.sleep(1500l);
for (Long msgId : msgIds) {
- boolean result = checker.isDuplicate(msgId);
+ boolean result = checker.isDuplicate(String.valueOf(msgId));
Assert.assertFalse(result);
}
diff --git a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageRouter.java b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageRouter.java
index 7ae9d4444..34b36ec31 100644
--- a/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageRouter.java
+++ b/weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageRouter.java
@@ -115,7 +115,7 @@ public class WxCpMessageRouter {
* @param wxMessage
*/
public WxCpXmlOutMessage route(final WxCpXmlMessage wxMessage) {
- if (messageDuplicateChecker.isDuplicate(wxMessage.getMsgId())) {
+ if (isDuplicateMessage(wxMessage)) {
// 如果是重复消息,那么就不做处理
return null;
}
@@ -177,6 +177,22 @@ public class WxCpMessageRouter {
return res;
}
+ protected boolean isDuplicateMessage(WxCpXmlMessage wxMessage) {
+
+ String messageId = "";
+ if (wxMessage.getMsgId() == null) {
+ messageId = wxMessage.getFromUserName() + "-" + String.valueOf(wxMessage.getCreateTime());
+ } else {
+ messageId = String.valueOf(wxMessage.getMsgId());
+ }
+
+ if (messageDuplicateChecker.isDuplicate(messageId)) {
+ return true;
+ }
+ return false;
+
+ }
+
/**
* 对session的访问结束
* @param wxMessage
diff --git a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java
index 5c09b48f5..afd8d3fb4 100644
--- a/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java
+++ b/weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java
@@ -1,5 +1,6 @@
package me.chanjar.weixin.mp.api;
+import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.session.*;
import me.chanjar.weixin.common.util.WxMessageDuplicateChecker;
import me.chanjar.weixin.common.util.WxMessageInMemoryDuplicateChecker;
@@ -113,7 +114,7 @@ public class WxMpMessageRouter {
* @param wxMessage
*/
public WxMpXmlOutMessage route(final WxMpXmlMessage wxMessage) {
- if (messageDuplicateChecker.isDuplicate(wxMessage.getMsgId())) {
+ if (isDuplicateMessage(wxMessage)) {
// 如果是重复消息,那么就不做处理
return null;
}
@@ -175,6 +176,22 @@ public class WxMpMessageRouter {
return res;
}
+ protected boolean isDuplicateMessage(WxMpXmlMessage wxMessage) {
+
+ String messageId = "";
+ if (wxMessage.getMsgId() == null) {
+ messageId = wxMessage.getFromUserName() + "-" + String.valueOf(wxMessage.getCreateTime());
+ } else {
+ messageId = String.valueOf(wxMessage.getMsgId());
+ }
+
+ if (messageDuplicateChecker.isDuplicate(messageId)) {
+ return true;
+ }
+ return false;
+
+ }
+
/**
* 对session的访问结束
* @param wxMessage