Bläddra i källkod

Merge pull request #391 from Wechat-Group/develop

合并 Develop
master
Binary Wang 7 år sedan
committed by GitHub
förälder
incheckning
3b1645df62
Ingen känd nyckel hittad för denna signaturen i databasen GPG-nyckel ID: 4AEE18F83AFDEB23
100 ändrade filer med 889 tillägg och 2578 borttagningar
  1. +13
    -1
      pom.xml
  2. +7
    -4
      quality-checks/google_checks.xml
  3. +5
    -1
      weixin-java-common/pom.xml
  4. +216
    -155
      weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java
  5. +1
    -1
      weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxErrorExceptionHandler.java
  6. +5
    -6
      weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxMessageDuplicateChecker.java
  7. +11
    -10
      weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxMessageInMemoryDuplicateChecker.java
  8. +2
    -16
      weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxAccessToken.java
  9. +3
    -73
      weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxCardApiSignature.java
  10. +4
    -40
      weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxJsapiSignature.java
  11. +5
    -19
      weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenu.java
  12. +10
    -70
      weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuButton.java
  13. +7
    -56
      weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuRule.java
  14. +5
    -51
      weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxError.java
  15. +4
    -35
      weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxMediaUploadResult.java
  16. +16
    -6
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java
  17. +2
    -1
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/ToStringUtils.java
  18. +26
    -26
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/ByteGroup.java
  19. +68
    -68
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/PKCS7Encoder.java
  20. +8
    -23
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/fs/FileUtils.java
  21. +3
    -3
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/BaseMediaDownloadRequestExecutor.java
  22. +7
    -5
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/HttpResponseProxy.java
  23. +7
    -17
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheHttpClientBuilder.java
  24. +26
    -16
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheHttpDnsClientBuilder.java
  25. +2
    -2
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheMediaDownloadRequestExecutor.java
  26. +1
    -3
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheSimplePostRequestExecutor.java
  27. +2
    -2
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpMediaDownloadRequestExecutor.java
  28. +2
    -4
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpSimplePostRequestExecutor.java
  29. +2
    -2
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/okhttp/OkHttpMediaDownloadRequestExecutor.java
  30. +10
    -7
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxErrorAdapter.java
  31. +1
    -0
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxMenuGsonAdapter.java
  32. +0
    -1
      weixin-java-common/src/test/java/me/chanjar/weixin/common/bean/WxErrorTest.java
  33. +1
    -1
      weixin-java-common/src/test/java/me/chanjar/weixin/common/util/crypto/SHA1Test.java
  34. +1
    -1
      weixin-java-cp/pom.xml
  35. +2
    -2
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMediaServiceImpl.java
  36. +1
    -1
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceAbstractImpl.java
  37. +2
    -1
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceImpl.java
  38. +13
    -14
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceOkHttpImpl.java
  39. +4
    -43
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpDepart.java
  40. +20
    -139
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java
  41. +9
    -44
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessageSendResult.java
  42. +7
    -27
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTag.java
  43. +9
    -37
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTagAddOrRemoveUsersResult.java
  44. +8
    -142
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUser.java
  45. +37
    -404
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java
  46. +3
    -9
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessage.java
  47. +8
    -39
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutMessage.java
  48. +9
    -46
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessage.java
  49. +3
    -10
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessage.java
  50. +4
    -26
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessage.java
  51. +3
    -9
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessage.java
  52. +5
    -121
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/MpnewsArticle.java
  53. +3
    -32
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/NewArticle.java
  54. +1
    -1
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/BaseBuilder.java
  55. +1
    -1
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/FileBuilder.java
  56. +1
    -1
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/ImageBuilder.java
  57. +1
    -1
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MpnewsBuilder.java
  58. +1
    -1
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/NewsBuilder.java
  59. +1
    -1
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TextBuilder.java
  60. +1
    -1
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TextCardBuilder.java
  61. +1
    -1
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VideoBuilder.java
  62. +1
    -1
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VoiceBuilder.java
  63. +5
    -1
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpJedisConfigStorage.java
  64. +9
    -6
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageRouter.java
  65. +1
    -1
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpDepartGsonAdapter.java
  66. +8
    -8
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpMessageGsonAdapter.java
  67. +25
    -13
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XStreamTransformer.java
  68. +1
    -3
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBusyRetryTest.java
  69. +1
    -2
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageAPITest.java
  70. +15
    -15
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageRouterTest.java
  71. +2
    -4
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpDepartmentServiceImplTest.java
  72. +5
    -5
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpMediaServiceImplTest.java
  73. +5
    -5
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpMenuServiceImplTest.java
  74. +3
    -3
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlMessageTest.java
  75. +1
    -1
      weixin-java-miniapp/pom.xml
  76. +6
    -44
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaQrcodeService.java
  77. +4
    -10
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMediaServiceImpl.java
  78. +2
    -1
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImpl.java
  79. +6
    -8
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaQrcodeServiceImpl.java
  80. +6
    -5
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImpl.java
  81. +2
    -2
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaUserServiceImpl.java
  82. +4
    -3
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/AbstractWxMaQrcodeWrapper.java
  83. +18
    -0
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaCodeLineColor.java
  84. +9
    -33
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaJscode2SessionResult.java
  85. +4
    -58
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaKefuMessage.java
  86. +2
    -87
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMessage.java
  87. +5
    -17
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaQrcode.java
  88. +7
    -146
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateMessage.java
  89. +8
    -104
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaUserInfo.java
  90. +10
    -41
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaWxcode.java
  91. +9
    -43
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaWxcodeLimit.java
  92. +3
    -0
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/builder/BaseBuilder.java
  93. +2
    -2
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/builder/ImageBuilder.java
  94. +1
    -0
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/WxMaInMemoryConfig.java
  95. +34
    -3
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaConstants.java
  96. +6
    -6
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/message/WxMaMessageRouter.java
  97. +1
    -1
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/message/WxMaMessageRouterRule.java
  98. +8
    -9
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/http/QrCodeRequestExecutor.java
  99. +6
    -4
      weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/xml/XStreamTransformer.java
  100. +3
    -3
      weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImplTest.java

+ 13
- 1
pom.xml Visa fil

@@ -6,7 +6,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-parent</artifactId>
<version>2.8.0</version>
<version>2.9.0</version>
<packaging>pom</packaging>
<name>WeiXin Java Tools - Parent</name>
<description>微信公众号、企业号上级POM</description>
@@ -80,6 +80,11 @@
<email>crskyp@gmail.com</email>
<url>https://github.com/crskyp</url>
</developer>
<developer>
<name>007</name>
<email>007gzs@gmail.com</email>
<url>https://github.com/007gzs</url>
</developer>
</developers>

<scm>
@@ -94,6 +99,7 @@
<module>weixin-java-mp</module>
<module>weixin-java-pay</module>
<module>weixin-java-miniapp</module>
<module>weixin-java-open</module>
<!--module>weixin-java-osgi</module-->
</modules>

@@ -225,6 +231,12 @@
<version>2.9.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
<scope>compile</scope>
</dependency>
</dependencies>
</dependencyManagement>



+ 7
- 4
quality-checks/google_checks.xml Visa fil

@@ -40,7 +40,7 @@
<property name="allowNonPrintableEscapes" value="true"/>
</module>
<module name="LineLength">
<property name="max" value="100"/>
<property name="max" value="120"/>
<property name="ignorePattern" value="^package.*|^import.*|a href|href|http://|https://|ftp://"/>
</module>
<module name="AvoidStarImport"/>
@@ -52,7 +52,7 @@
</module>
<module name="NeedBraces"/>
<module name="LeftCurly">
<property name="maxLineLength" value="100"/>
<property name="maxLineLength" value="120"/>
</module>
<module name="RightCurly">
<property name="id" value="RightCurlySame"/>
@@ -163,9 +163,12 @@
<module name="OverloadMethodsDeclarationOrder"/>
<module name="VariableDeclarationUsageDistance"/>
<module name="CustomImportOrder">
<property name="customImportOrderRules"
value="THIRD_PARTY_PACKAGE###SPECIAL_IMPORTS###STANDARD_JAVA_PACKAGE###STATIC"/>
<property name="specialImportsRegExp" value="^javax\."/>
<property name="standardPackageRegExp" value="^java\."/>
<property name="sortImportsInGroupAlphabetically" value="true"/>
<property name="separateLineBetweenGroups" value="true"/>
<property name="customImportOrderRules" value="STATIC###THIRD_PARTY_PACKAGE"/>
<property name="separateLineBetweenGroups" value="false"/>
</module>
<module name="MethodParamPad"/>
<module name="ParenPad"/>


+ 5
- 1
weixin-java-common/pom.xml Visa fil

@@ -7,7 +7,7 @@
<parent>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-parent</artifactId>
<version>2.8.0</version>
<version>2.9.0</version>
</parent>

<artifactId>weixin-java-common</artifactId>
@@ -74,6 +74,10 @@
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>

<dependency>
<groupId>ch.qos.logback</groupId>


+ 216
- 155
weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java Visa fil

@@ -3,187 +3,248 @@ package me.chanjar.weixin.common.api;
import java.util.HashMap;
import java.util.Map;

/**
* 微信开发所使用到的常量类.
*
* @author chanjarster & binarywang
*/
public class WxConsts {

///////////////////////
// 微信推送过来的消息的类型,和发送给微信xml格式消息的消息类型
///////////////////////
public static final String XML_MSG_TEXT = "text";
public static final String XML_MSG_IMAGE = "image";
public static final String XML_MSG_VOICE = "voice";
public static final String XML_MSG_SHORTVIDEO = "shortvideo";
public static final String XML_MSG_VIDEO = "video";
public static final String XML_MSG_NEWS = "news";
public static final String XML_MSG_MUSIC = "music";
public static final String XML_MSG_LOCATION = "location";
public static final String XML_MSG_LINK = "link";
public static final String XML_MSG_EVENT = "event";
public static final String XML_MSG_DEVICE_TEXT = "device_text";
public static final String XML_MSG_DEVICE_EVENT = "device_event";
public static final String XML_MSG_DEVICE_STATUS = "device_status";
public static final String XML_MSG_HARDWARE = "hardware";
public static final String XML_TRANSFER_CUSTOMER_SERVICE = "transfer_customer_service";

///////////////////////
// 主动发送消息(即客服消息)的消息类型
///////////////////////
public static final String CUSTOM_MSG_TEXT = "text";//文本消息
public static final String CUSTOM_MSG_IMAGE = "image";//图片消息
public static final String CUSTOM_MSG_VOICE = "voice";//语音消息
public static final String CUSTOM_MSG_VIDEO = "video";//视频消息
public static final String CUSTOM_MSG_MUSIC = "music";//音乐消息
public static final String CUSTOM_MSG_NEWS = "news";//图文消息(点击跳转到外链)
public static final String CUSTOM_MSG_MPNEWS = "mpnews";//图文消息(点击跳转到图文消息页面)
public static final String CUSTOM_MSG_FILE = "file";//发送文件(CP专用)
public static final String CUSTOM_MSG_TEXTCARD = "textcard";//文本卡片消息(CP专用)
public static final String CUSTOM_MSG_WXCARD = "wxcard";//卡券消息
public static final String CUSTOM_MSG_TRANSFER_CUSTOMER_SERVICE = "transfer_customer_service";
public static final String CUSTOM_MSG_SAFE_NO = "0";
public static final String CUSTOM_MSG_SAFE_YES = "1";

///////////////////////
// 群发消息的消息类型
///////////////////////
public static final String MASS_MSG_NEWS = "mpnews";
public static final String MASS_MSG_TEXT = "text";
public static final String MASS_MSG_VOICE = "voice";
public static final String MASS_MSG_IMAGE = "image";
public static final String MASS_MSG_VIDEO = "mpvideo";

///////////////////////
// 群发消息后微信端推送给服务器的反馈消息
///////////////////////
public static final String MASS_ST_SUCCESS = "send success";
public static final String MASS_ST_FAIL = "send fail";
public static final String MASS_ST_10001 = "err(10001)";
public static final String MASS_ST_20001 = "err(20001)";
public static final String MASS_ST_20004 = "err(20004)";
public static final String MASS_ST_20002 = "err(20002)";
public static final String MASS_ST_20006 = "err(20006)";
public static final String MASS_ST_20008 = "err(20008)";
public static final String MASS_ST_20013 = "err(20013)";
public static final String MASS_ST_22000 = "err(22000)";
public static final String MASS_ST_21000 = "err(21000)";

/**
* 群发反馈消息代码所对应的文字描述
* 微信推送过来的消息的类型,和发送给微信xml格式消息的消息类型.
*/
public static final Map<String, String> MASS_ST_2_DESC = new HashMap<>();

///////////////////////
// 微信端推送过来的事件类型
///////////////////////
public static final String EVT_SUBSCRIBE = "subscribe";
public static final String EVT_UNSUBSCRIBE = "unsubscribe";
public static final String EVT_SCAN = "SCAN";
public static final String EVT_LOCATION = "LOCATION";
public static final String EVT_CLICK = "CLICK";
public static final String EVT_VIEW = "VIEW";
public static final String EVT_MASS_SEND_JOB_FINISH = "MASSSENDJOBFINISH";
public static final String EVT_SCANCODE_PUSH = "scancode_push";
public static final String EVT_SCANCODE_WAITMSG = "scancode_waitmsg";
public static final String EVT_PIC_SYSPHOTO = "pic_sysphoto";
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";
public static final String EVT_ENTER_AGENT = "enter_agent";

///////////////////////
// 上传多媒体文件的类型
///////////////////////
public static final String MEDIA_IMAGE = "image";
public static final String MEDIA_VOICE = "voice";
public static final String MEDIA_VIDEO = "video";
public static final String MEDIA_THUMB = "thumb";
public static final String MEDIA_FILE = "file";

public static class XmlMsgType {
public static final String TEXT = "text";
public static final String IMAGE = "image";
public static final String VOICE = "voice";
public static final String SHORTVIDEO = "shortvideo";
public static final String VIDEO = "video";
public static final String NEWS = "news";
public static final String MUSIC = "music";
public static final String LOCATION = "location";
public static final String LINK = "link";
public static final String EVENT = "event";
public static final String DEVICE_TEXT = "device_text";
public static final String DEVICE_EVENT = "device_event";
public static final String DEVICE_STATUS = "device_status";
public static final String HARDWARE = "hardware";
public static final String TRANSFER_CUSTOMER_SERVICE = "transfer_customer_service";
}

///////////////////////
// 自定义菜单的按钮类型
///////////////////////
/**
* 点击推事件
*/
public static final String BUTTON_CLICK = "click";
/**
* 跳转URL
*/
public static final String BUTTON_VIEW = "view";
/**
* 跳转到小程序
*/
public static final String BUTTON_MINIPROGRAM = "miniprogram";
/**
* 扫码推事件
*/
public static final String BUTTON_SCANCODE_PUSH = "scancode_push";
/**
* 扫码推事件且弹出“消息接收中”提示框
* 主动发送消息(即客服消息)的消息类型.
*/
public static final String BUTTON_SCANCODE_WAITMSG = "scancode_waitmsg";
public static class KefuMsgType {
/**
* 文本消息.
*/
public static final String TEXT = "text";
/**
* 图片消息.
*/
public static final String IMAGE = "image";
/**
* 语音消息.
*/
public static final String VOICE = "voice";
/**
* 视频消息.
*/
public static final String VIDEO = "video";
/**
* 音乐消息.
*/
public static final String MUSIC = "music";
/**
* 图文消息(点击跳转到外链).
*/
public static final String NEWS = "news";
/**
* 图文消息(点击跳转到图文消息页面).
*/
public static final String MPNEWS = "mpnews";
/**
* 发送文件(CP专用).
*/
public static final String FILE = "file";
/**
* 文本卡片消息(CP专用).
*/
public static final String TEXTCARD = "textcard";
/**
* 卡券消息.
*/
public static final String WXCARD = "wxcard";
/**
* 转发到客服的消息.
*/
public static final String TRANSFER_CUSTOMER_SERVICE = "transfer_customer_service";
}

/**
* 弹出系统拍照发图
* 表示是否是保密消息,0表示否,1表示是,默认0.
*/
public static final String BUTTON_PIC_SYSPHOTO = "pic_sysphoto";
public static class KefuMsgSafe {
public static final String NO = "0";
public static final String YES = "1";
}

/**
* 弹出拍照或者相册发图
* 群发消息的消息类型.
*/
public static final String BUTTON_PIC_PHOTO_OR_ALBUM = "pic_photo_or_album";
public static class MassMsgType {
public static final String MPNEWS = "mpnews";
public static final String TEXT = "text";
public static final String VOICE = "voice";
public static final String IMAGE = "image";
public static final String MPVIDEO = "mpvideo";
}

/**
* 弹出微信相册发图器
* 群发消息后微信端推送给服务器的反馈消息.
*/
public static final String BUTTON_PIC_WEIXIN = "pic_weixin";
public static class MassMsgStatus {
public static final String SEND_SUCCESS = "send success";
public static final String SEND_FAIL = "send fail";
public static final String ERR_10001 = "err(10001)";
public static final String ERR_20001 = "err(20001)";
public static final String ERR_20004 = "err(20004)";
public static final String ERR_20002 = "err(20002)";
public static final String ERR_20006 = "err(20006)";
public static final String ERR_20008 = "err(20008)";
public static final String ERR_20013 = "err(20013)";
public static final String ERR_22000 = "err(22000)";
public static final String ERR_21000 = "err(21000)";

/**
* 群发反馈消息代码所对应的文字描述.
*/
public static final Map<String, String> STATUS_DESC = new HashMap<>();

static {
STATUS_DESC.put(SEND_SUCCESS, "发送成功");
STATUS_DESC.put(SEND_FAIL, "发送失败");
STATUS_DESC.put(ERR_10001, "涉嫌广告");
STATUS_DESC.put(ERR_20001, "涉嫌政治");
STATUS_DESC.put(ERR_20004, "涉嫌社会");
STATUS_DESC.put(ERR_20002, "涉嫌色情");
STATUS_DESC.put(ERR_20006, "涉嫌违法犯罪");
STATUS_DESC.put(ERR_20008, "涉嫌欺诈");
STATUS_DESC.put(ERR_20013, "涉嫌版权");
STATUS_DESC.put(ERR_22000, "涉嫌互推_互相宣传");
STATUS_DESC.put(ERR_21000, "涉嫌其他");
}
}

/**
* 弹出地理位置选择器
* 微信端推送过来的事件类型.
*/
public static final String BUTTON_LOCATION_SELECT = "location_select";
public static class EventType {
public static final String SUBSCRIBE = "subscribe";
public static final String UNSUBSCRIBE = "unsubscribe";
public static final String SCAN = "SCAN";
public static final String LOCATION = "LOCATION";
public static final String CLICK = "CLICK";
public static final String VIEW = "VIEW";
public static final String MASS_SEND_JOB_FINISH = "MASSSENDJOBFINISH";
public static final String SCANCODE_PUSH = "scancode_push";
public static final String SCANCODE_WAITMSG = "scancode_waitmsg";
public static final String PIC_SYSPHOTO = "pic_sysphoto";
public static final String PIC_PHOTO_OR_ALBUM = "pic_photo_or_album";
public static final String PIC_WEIXIN = "pic_weixin";
public static final String LOCATION_SELECT = "location_select";
public static final String TEMPLATE_SEND_JOB_FINISH = "TEMPLATESENDJOBFINISH";
public static final String ENTER_AGENT = "enter_agent";
}

/**
* 下发消息(除文本消息)
* 上传多媒体(临时素材)文件的类型.
*/
public static final String BUTTON_MEDIA_ID = "media_id";
public static class MediaFileType {
public static final String IMAGE = "image";
public static final String VOICE = "voice";
public static final String VIDEO = "video";
public static final String THUMB = "thumb";
public static final String FILE = "file";
}

/**
* 跳转图文消息URL
* 自定义菜单的按钮类型.
*/
public static final String BUTTON_VIEW_LIMITED = "view_limited";
public static class MenuButtonType {
/**
* 点击推事件.
*/
public static final String CLICK = "click";
/**
* 跳转URL.
*/
public static final String VIEW = "view";
/**
* 跳转到小程序.
*/
public static final String MINIPROGRAM = "miniprogram";
/**
* 扫码推事件.
*/
public static final String SCANCODE_PUSH = "scancode_push";
/**
* 扫码推事件且弹出“消息接收中”提示框.
*/
public static final String SCANCODE_WAITMSG = "scancode_waitmsg";
/**
* 弹出系统拍照发图.
*/
public static final String PIC_SYSPHOTO = "pic_sysphoto";
/**
* 弹出拍照或者相册发图.
*/
public static final String PIC_PHOTO_OR_ALBUM = "pic_photo_or_album";
/**
* 弹出微信相册发图器.
*/
public static final String PIC_WEIXIN = "pic_weixin";
/**
* 弹出地理位置选择器.
*/
public static final String LOCATION_SELECT = "location_select";
/**
* 下发消息(除文本消息).
*/
public static final String MEDIA_ID = "media_id";
/**
* 跳转图文消息URL.
*/
public static final String VIEW_LIMITED = "view_limited";
}

/**
* 不弹出授权页面,直接跳转,只能获取用户openid
* oauth2网页授权的scope.
*/
public static final String OAUTH2_SCOPE_BASE = "snsapi_base";
public static class OAuth2Scope {
/**
* 不弹出授权页面,直接跳转,只能获取用户openid.
*/
public static final String SNSAPI_BASE = "snsapi_base";
/**
* 弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息.
*/
public static final String SNSAPI_USERINFO = "snsapi_userinfo";
}

///////////////////////
// oauth2网页授权的scope
///////////////////////
/**
* 弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息
* 网页应用登录授权作用域.
*/
public static final String OAUTH2_SCOPE_USER_INFO = "snsapi_userinfo";
public static class QrConnectScope {
public static final String SNSAPI_LOGIN = "snsapi_login";
}

/**
* 网页应用登录授权作用域 snsapi_login
* 永久素材类型.
*/
public static final String QRCONNECT_SCOPE_SNSAPI_LOGIN = "snsapi_login";

///////////////////////
// 永久素材类型
///////////////////////
public static final String MATERIAL_NEWS = "news";
public static final String MATERIAL_VOICE = "voice";
public static final String MATERIAL_IMAGE = "image";
public static final String MATERIAL_VIDEO = "video";

static {
MASS_ST_2_DESC.put(MASS_ST_SUCCESS, "发送成功");
MASS_ST_2_DESC.put(MASS_ST_FAIL, "发送失败");
MASS_ST_2_DESC.put(MASS_ST_10001, "涉嫌广告");
MASS_ST_2_DESC.put(MASS_ST_20001, "涉嫌政治");
MASS_ST_2_DESC.put(MASS_ST_20004, "涉嫌社会");
MASS_ST_2_DESC.put(MASS_ST_20002, "涉嫌色情");
MASS_ST_2_DESC.put(MASS_ST_20006, "涉嫌违法犯罪");
MASS_ST_2_DESC.put(MASS_ST_20008, "涉嫌欺诈");
MASS_ST_2_DESC.put(MASS_ST_20013, "涉嫌版权");
MASS_ST_2_DESC.put(MASS_ST_22000, "涉嫌互推_互相宣传");
MASS_ST_2_DESC.put(MASS_ST_21000, "涉嫌其他");
public static class MaterialType {
public static final String NEWS = "news";
public static final String VOICE = "voice";
public static final String IMAGE = "image";
public static final String VIDEO = "video";
}
}

+ 1
- 1
weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxErrorExceptionHandler.java Visa fil

@@ -3,7 +3,7 @@ package me.chanjar.weixin.common.api;
import me.chanjar.weixin.common.exception.WxErrorException;

/**
* WxErrorException处理器
* WxErrorException处理器.
*/
public interface WxErrorExceptionHandler {



+ 5
- 6
weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxMessageDuplicateChecker.java Visa fil

@@ -2,22 +2,21 @@ package me.chanjar.weixin.common.api;

/**
* <pre>
* 消息重复检查器
* 消息重复检查器.
* 微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次
* </pre>
*/
public interface WxMessageDuplicateChecker {

/**
* 判断消息是否重复.
* <h2>公众号的排重方式</h2>
* <p>
*
* <p>普通消息:关于重试的消息排重,推荐使用msgid排重。<a href="http://mp.weixin.qq.com/wiki/10/79502792eef98d6e0c6e1739da387346.html">文档参考</a>。</p>
* <p>事件消息:关于重试的消息排重,推荐使用FromUserName + CreateTime 排重。<a href="http://mp.weixin.qq.com/wiki/2/5baf56ce4947d35003b86a9805634b1e.html">文档参考</a></p>
* <p>
*
* <h2>企业号的排重方式</h2>
* <p>
* 官方文档完全没有写,参照公众号的方式排重。
* <p>
* <p>官方文档完全没有写,参照公众号的方式排重。</p>
* <p>或者可以采取更简单的方式,如果有MsgId就用MsgId排重,如果没有就用FromUserName+CreateTime排重</p>
*
* @param messageId messageId需要根据上面讲的方式构造


+ 11
- 10
weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxMessageInMemoryDuplicateChecker.java Visa fil

@@ -6,46 +6,46 @@ import java.util.concurrent.atomic.AtomicBoolean;

/**
* <pre>
* 默认消息重复检查器
* 默认消息重复检查器.
* 将每个消息id保存在内存里,每隔5秒清理已经过期的消息id,每个消息id的过期时间是15秒
* </pre>
*/
public class WxMessageInMemoryDuplicateChecker implements WxMessageDuplicateChecker {

/**
* 一个消息ID在内存的过期时间:15秒
* 一个消息ID在内存的过期时间:15秒.
*/
private final Long timeToLive;

/**
* 每隔多少周期检查消息ID是否过期:5秒
* 每隔多少周期检查消息ID是否过期:5秒.
*/
private final Long clearPeriod;

/**
* 消息id->消息时间戳的map
* 消息id->消息时间戳的map.
*/
private final ConcurrentHashMap<String, Long> msgId2Timestamp = new ConcurrentHashMap<>();

/**
* 后台清理线程是否已经开启
* 后台清理线程是否已经开启.
*/
private final AtomicBoolean backgroundProcessStarted = new AtomicBoolean(false);

/**
* WxMsgIdInMemoryDuplicateChecker构造函数
* 无参构造方法.
* <pre>
* 一个消息ID在内存的过期时间:15秒
* 每隔多少周期检查消息ID是否过期:5秒
* </pre>
*/
public WxMessageInMemoryDuplicateChecker() {
this.timeToLive = 15 * 1000l;
this.clearPeriod = 5 * 1000l;
this.timeToLive = 15 * 1000L;
this.clearPeriod = 5 * 1000L;
}

/**
* WxMsgIdInMemoryDuplicateChecker构造函数
* 构造方法.
*
* @param timeToLive 一个消息ID在内存的过期时间:毫秒
* @param clearPeriod 每隔多少周期检查消息ID是否过期:毫秒
@@ -66,7 +66,8 @@ public class WxMessageInMemoryDuplicateChecker implements WxMessageDuplicateChec
while (true) {
Thread.sleep(WxMessageInMemoryDuplicateChecker.this.clearPeriod);
Long now = System.currentTimeMillis();
for (Map.Entry<String, Long> entry : WxMessageInMemoryDuplicateChecker.this.msgId2Timestamp.entrySet()) {
for (Map.Entry<String, Long> entry :
WxMessageInMemoryDuplicateChecker.this.msgId2Timestamp.entrySet()) {
if (now - entry.getValue() > WxMessageInMemoryDuplicateChecker.this.timeToLive) {
WxMessageInMemoryDuplicateChecker.this.msgId2Timestamp.entrySet().remove(entry);
}


+ 2
- 16
weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxAccessToken.java Visa fil

@@ -1,9 +1,11 @@
package me.chanjar.weixin.common.bean;

import lombok.Data;
import me.chanjar.weixin.common.util.json.WxGsonBuilder;

import java.io.Serializable;

@Data
public class WxAccessToken implements Serializable {
private static final long serialVersionUID = 8709719312922168909L;

@@ -15,20 +17,4 @@ public class WxAccessToken implements Serializable {
return WxGsonBuilder.create().fromJson(json, WxAccessToken.class);
}

public String getAccessToken() {
return this.accessToken;
}

public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}

public int getExpiresIn() {
return this.expiresIn;
}

public void setExpiresIn(int expiresIn) {
this.expiresIn = expiresIn;
}

}

+ 3
- 73
weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxCardApiSignature.java Visa fil

@@ -1,17 +1,18 @@
package me.chanjar.weixin.common.bean;

import lombok.Data;
import me.chanjar.weixin.common.util.ToStringUtils;

import java.io.Serializable;

/**
* 卡券Api签名
* 卡券Api签名.
*
* @author YuJian
* @version 15/11/8
*/
@Data
public class WxCardApiSignature implements Serializable {

private static final long serialVersionUID = 158176707226975979L;

private String appId;
@@ -37,75 +38,4 @@ public class WxCardApiSignature implements Serializable {
return ToStringUtils.toSimpleString(this);
}

public String getAppId() {
return this.appId;
}

public void setAppId(String appId) {
this.appId = appId;
}

public String getCardId() {
return this.cardId;
}

public void setCardId(String cardId) {
this.cardId = cardId;
}

public String getCardType() {
return this.cardType;
}

public void setCardType(String cardType) {
this.cardType = cardType;
}

public String getLocationId() {
return this.locationId;
}

public void setLocationId(String locationId) {
this.locationId = locationId;
}

public String getCode() {
return this.code;
}

public void setCode(String code) {
this.code = code;
}

public String getOpenId() {
return this.openId;
}

public void setOpenId(String openId) {
this.openId = openId;
}

public Long getTimestamp() {
return this.timestamp;
}

public void setTimestamp(Long timestamp) {
this.timestamp = timestamp;
}

public String getNonceStr() {
return this.nonceStr;
}

public void setNonceStr(String nonceStr) {
this.nonceStr = nonceStr;
}

public String getSignature() {
return this.signature;
}

public void setSignature(String signature) {
this.signature = signature;
}
}

+ 4
- 40
weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxJsapiSignature.java Visa fil

@@ -1,10 +1,13 @@
package me.chanjar.weixin.common.bean;

import lombok.Data;

import java.io.Serializable;

/**
* jspai signature
* jspai signature.
*/
@Data
public class WxJsapiSignature implements Serializable {
private static final long serialVersionUID = -1116808193154384804L;

@@ -18,43 +21,4 @@ public class WxJsapiSignature implements Serializable {

private String signature;

public String getSignature() {
return this.signature;
}

public void setSignature(String signature) {
this.signature = signature;
}

public String getNonceStr() {
return nonceStr;
}

public void setNonceStr(String nonceStr) {
this.nonceStr = nonceStr;
}

public long getTimestamp() {
return this.timestamp;
}

public void setTimestamp(long timestamp) {
this.timestamp = timestamp;
}

public String getUrl() {
return this.url;
}

public void setUrl(String url) {
this.url = url;
}

public String getAppId() {
return appId;
}

public void setAppId(String appId) {
this.appId = appId;
}
}

+ 5
- 19
weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenu.java Visa fil

@@ -1,5 +1,6 @@
package me.chanjar.weixin.common.bean.menu;

import lombok.Data;
import me.chanjar.weixin.common.util.ToStringUtils;
import me.chanjar.weixin.common.util.json.WxGsonBuilder;

@@ -11,12 +12,12 @@ import java.util.ArrayList;
import java.util.List;

/**
* 菜单(公众号和企业号共用的)
* 菜单(公众号和企业号共用的).
*
* @author Daniel Qian
*/
@Data
public class WxMenu implements Serializable {

private static final long serialVersionUID = -7083914585539687746L;

private List<WxMenuButton> buttons = new ArrayList<>();
@@ -36,23 +37,8 @@ public class WxMenu implements Serializable {
* 相比 http://mp.weixin.qq.com/wiki/13/43de8269be54a0a6f64413e4dfa94f39.html 的格式,外层多套了一个menu
*/
public static WxMenu fromJson(InputStream is) {
return WxGsonBuilder.create().fromJson(new InputStreamReader(is, StandardCharsets.UTF_8), WxMenu.class);
}

public List<WxMenuButton> getButtons() {
return this.buttons;
}

public void setButtons(List<WxMenuButton> buttons) {
this.buttons = buttons;
}

public WxMenuRule getMatchRule() {
return this.matchRule;
}

public void setMatchRule(WxMenuRule matchRule) {
this.matchRule = matchRule;
return WxGsonBuilder.create()
.fromJson(new InputStreamReader(is, StandardCharsets.UTF_8), WxMenu.class);
}

public String toJson() {


+ 10
- 70
weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuButton.java Visa fil

@@ -1,18 +1,20 @@
package me.chanjar.weixin.common.bean.menu;

import com.google.gson.annotations.SerializedName;
import lombok.Data;
import me.chanjar.weixin.common.util.ToStringUtils;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

@Data
public class WxMenuButton implements Serializable {
private static final long serialVersionUID = -1070939403109776555L;

/**
* <pre>
* 菜单的响应动作类型
* 菜单的响应动作类型.
* view表示网页类型,
* click表示点击类型,
* miniprogram表示小程序类型
@@ -21,13 +23,13 @@ public class WxMenuButton implements Serializable {
private String type;

/**
* 菜单标题,不超过16个字节,子菜单不超过60个字节
* 菜单标题,不超过16个字节,子菜单不超过60个字节.
*/
private String name;

/**
* <pre>
* 菜单KEY值,用于消息接口推送,不超过128字节
* 菜单KEY值,用于消息接口推送,不超过128字节.
* click等点击类型必须
* </pre>
*/
@@ -35,7 +37,8 @@ public class WxMenuButton implements Serializable {

/**
* <pre>
* 网页链接,用户点击菜单可打开链接,不超过1024字节。type为miniprogram时,不支持小程序的老版本客户端将打开本url。
* 网页链接.
* 用户点击菜单可打开链接,不超过1024字节。type为miniprogram时,不支持小程序的老版本客户端将打开本url。
* view、miniprogram类型必须
* </pre>
*/
@@ -43,7 +46,7 @@ public class WxMenuButton implements Serializable {

/**
* <pre>
* 调用新增永久素材接口返回的合法media_id
* 调用新增永久素材接口返回的合法media_id.
* media_id类型和view_limited类型必须
* </pre>
*/
@@ -52,7 +55,7 @@ public class WxMenuButton implements Serializable {

/**
* <pre>
* 小程序的appid
* 小程序的appid.
* miniprogram类型必须
* </pre>
*/
@@ -61,7 +64,7 @@ public class WxMenuButton implements Serializable {

/**
* <pre>
* 小程序的页面路径
* 小程序的页面路径.
* miniprogram类型必须
* </pre>
*/
@@ -76,67 +79,4 @@ public class WxMenuButton implements Serializable {
return ToStringUtils.toSimpleString(this);
}

public String getType() {
return this.type;
}

public void setType(String type) {
this.type = type;
}

public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}

public String getKey() {
return this.key;
}

public void setKey(String key) {
this.key = key;
}

public String getUrl() {
return this.url;
}

public void setUrl(String url) {
this.url = url;
}

public List<WxMenuButton> getSubButtons() {
return this.subButtons;
}

public void setSubButtons(List<WxMenuButton> subButtons) {
this.subButtons = subButtons;
}

public String getMediaId() {
return this.mediaId;
}

public void setMediaId(String mediaId) {
this.mediaId = mediaId;
}

public String getAppId() {
return appId;
}

public void setAppId(String appId) {
this.appId = appId;
}

public String getPagePath() {
return pagePath;
}

public void setPagePath(String pagePath) {
this.pagePath = pagePath;
}
}

+ 7
- 56
weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuRule.java Visa fil

@@ -1,12 +1,19 @@
package me.chanjar.weixin.common.bean.menu;

import com.google.gson.annotations.SerializedName;
import lombok.Data;
import me.chanjar.weixin.common.util.ToStringUtils;

import java.io.Serializable;

@Data
public class WxMenuRule implements Serializable {
private static final long serialVersionUID = -4587181819499286670L;

/**
* 变态的微信接口,反序列化时这里反人类的使用和序列化时不一样的名字.
*/
@SerializedName(value = "tag_id", alternate = "group_id")
private String tagId;
private String sex;
private String country;
@@ -15,62 +22,6 @@ public class WxMenuRule implements Serializable {
private String clientPlatformType;
private String language;

public String getTagId() {
return this.tagId;
}

public void setTagId(String tagId) {
this.tagId = tagId;
}

public String getSex() {
return this.sex;
}

public void setSex(String sex) {
this.sex = sex;
}

public String getCountry() {
return this.country;
}

public void setCountry(String country) {
this.country = country;
}

public String getProvince() {
return this.province;
}

public void setProvince(String province) {
this.province = province;
}

public String getCity() {
return this.city;
}

public void setCity(String city) {
this.city = city;
}

public String getClientPlatformType() {
return this.clientPlatformType;
}

public void setClientPlatformType(String clientPlatformType) {
this.clientPlatformType = clientPlatformType;
}

public String getLanguage() {
return this.language;
}

public void setLanguage(String language) {
this.language = language;
}

@Override
public String toString() {
return ToStringUtils.toSimpleString(this);


+ 5
- 51
weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxError.java Visa fil

@@ -1,14 +1,18 @@
package me.chanjar.weixin.common.bean.result;

import lombok.Builder;
import lombok.Data;
import me.chanjar.weixin.common.util.json.WxGsonBuilder;

import java.io.Serializable;

/**
* 微信错误码说明,请阅读: <a href="http://mp.weixin.qq.com/wiki/10/6380dc743053a91c544ffd2b7c959166.html">全局返回码说明</a>
* 微信错误码说明,请阅读: <a href="http://mp.weixin.qq.com/wiki/10/6380dc743053a91c544ffd2b7c959166.html">全局返回码说明</a>.
*
* @author Daniel Qian
*/
@Data
@Builder
public class WxError implements Serializable {

private static final long serialVersionUID = 7869786563361406291L;
@@ -23,34 +27,6 @@ public class WxError implements Serializable {
return WxGsonBuilder.create().fromJson(json, WxError.class);
}

public static Builder newBuilder() {
return new Builder();
}

public int getErrorCode() {
return this.errorCode;
}

public void setErrorCode(int errorCode) {
this.errorCode = errorCode;
}

public String getErrorMsg() {
return this.errorMsg;
}

public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}

public String getJson() {
return this.json;
}

public void setJson(String json) {
this.json = json;
}

@Override
public String toString() {
if (this.json != null) {
@@ -59,26 +35,4 @@ public class WxError implements Serializable {
return "错误: Code=" + this.errorCode + ", Msg=" + this.errorMsg;
}

public static class Builder {
private int errorCode;
private String errorMsg;

public Builder setErrorCode(int errorCode) {
this.errorCode = errorCode;
return this;
}

public Builder setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
return this;
}

public WxError build() {
WxError wxError = new WxError();
wxError.setErrorCode(this.errorCode);
wxError.setErrorMsg(this.errorMsg);
return wxError;
}

}
}

+ 4
- 35
weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxMediaUploadResult.java Visa fil

@@ -1,11 +1,12 @@
package me.chanjar.weixin.common.bean.result;

import lombok.Data;
import me.chanjar.weixin.common.util.ToStringUtils;
import me.chanjar.weixin.common.util.json.WxGsonBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import java.io.Serializable;

@Data
public class WxMediaUploadResult implements Serializable {
private static final long serialVersionUID = 330834334738622341L;

@@ -18,41 +19,9 @@ public class WxMediaUploadResult implements Serializable {
return WxGsonBuilder.create().fromJson(json, WxMediaUploadResult.class);
}

public String getType() {
return this.type;
}

public void setType(String type) {
this.type = type;
}

public String getMediaId() {
return this.mediaId;
}

public void setMediaId(String mediaId) {
this.mediaId = mediaId;
}

public long getCreatedAt() {
return this.createdAt;
}

public void setCreatedAt(long createdAt) {
this.createdAt = createdAt;
}

public String getThumbMediaId() {
return this.thumbMediaId;
}

public void setThumbMediaId(String thumbMediaId) {
this.thumbMediaId = thumbMediaId;
}

@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
return ToStringUtils.toSimpleString(this);
}

}

+ 16
- 6
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/BeanUtils.java Visa fil

@@ -11,6 +11,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -20,8 +21,9 @@ import java.util.Map;
* <pre>
* bean操作的一些工具类
* Created by Binary Wang on 2016-10-21.
* @author <a href="https://github.com/binarywang">binarywang(Binary Wang)</a>
* </pre>
*
* @author <a href="https://github.com/binarywang">binarywang(Binary Wang)</a>
*/
public class BeanUtils {
private static Logger log = LoggerFactory.getLogger(BeanUtils.class);
@@ -42,22 +44,27 @@ public class BeanUtils {
boolean isAccessible = field.isAccessible();
field.setAccessible(true);
if (field.isAnnotationPresent(Required.class)) {
if (field.get(bean) == null || (field.get(bean) instanceof String && StringUtils.isBlank(field.get(bean).toString()))) {
//两种情况,一种是值为null,另外一种情况是类型为字符串,但是字符串内容为空的,都认为是没有提供值
// 两种情况,一种是值为null,
// 另外一种情况是类型为字符串,但是字符串内容为空的,都认为是没有提供值
boolean isRequiredMissing = field.get(bean) == null
|| (field.get(bean) instanceof String
&& StringUtils.isBlank(field.get(bean).toString())
);
if (isRequiredMissing) {
requiredFields.add(field.getName());
}
}
field.setAccessible(isAccessible);
} catch (SecurityException | IllegalArgumentException
| IllegalAccessException e) {
e.printStackTrace();
log.error(e.getMessage(), e);
}
}

if (!requiredFields.isEmpty()) {
String msg = "必填字段 " + requiredFields + " 必须提供值";
log.debug(msg);
throw new WxErrorException(WxError.newBuilder().setErrorMsg(msg).build());
throw new WxErrorException(WxError.builder().errorMsg(msg).build());
}
}

@@ -82,11 +89,14 @@ public class BeanUtils {

if (field.isAnnotationPresent(XStreamAlias.class)) {
result.put(field.getAnnotation(XStreamAlias.class).value(), field.get(bean).toString());
} else if (!Modifier.isStatic(field.getModifiers())) {
//忽略掉静态成员变量
result.put(field.getName(), field.get(bean).toString());
}

field.setAccessible(isAccessible);
} catch (SecurityException | IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
log.error(e.getMessage(), e);
}

}


+ 2
- 1
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/ToStringUtils.java Visa fil

@@ -8,8 +8,9 @@ import org.apache.commons.lang3.builder.ToStringStyle;
* <pre>
* 自定义的ToString方法,用于产生去掉空值属性的字符串
* Created by Binary Wang on 2016-10-27.
* @author <a href="https://github.com/binarywang">binarywang(Binary Wang)</a>
* </pre>
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
public class ToStringUtils {
public static final ToStringStyle THE_STYLE = new SimpleMultiLineToStringStyle();


+ 26
- 26
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/ByteGroup.java Visa fil

@@ -1,26 +1,26 @@
package me.chanjar.weixin.common.util.crypto;
import java.util.ArrayList;
public class ByteGroup {
ArrayList<Byte> byteContainer = new ArrayList<>();
public byte[] toBytes() {
byte[] bytes = new byte[this.byteContainer.size()];
for (int i = 0; i < this.byteContainer.size(); i++) {
bytes[i] = this.byteContainer.get(i);
}
return bytes;
}
public ByteGroup addBytes(byte[] bytes) {
for (byte b : bytes) {
this.byteContainer.add(b);
}
return this;
}
public int size() {
return this.byteContainer.size();
}
}
package me.chanjar.weixin.common.util.crypto;
import java.util.ArrayList;
public class ByteGroup {
ArrayList<Byte> byteContainer = new ArrayList<>();
public byte[] toBytes() {
byte[] bytes = new byte[this.byteContainer.size()];
for (int i = 0; i < this.byteContainer.size(); i++) {
bytes[i] = this.byteContainer.get(i);
}
return bytes;
}
public ByteGroup addBytes(byte[] bytes) {
for (byte b : bytes) {
this.byteContainer.add(b);
}
return this;
}
public int size() {
return this.byteContainer.size();
}
}

+ 68
- 68
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/PKCS7Encoder.java Visa fil

@@ -1,68 +1,68 @@
/**
* 对公众平台发送给公众账号的消息加解密示例代码.
*
* @copyright Copyright (c) 1998-2014 Tencent Inc.
*/
// ------------------------------------------------------------------------
package me.chanjar.weixin.common.util.crypto;
import java.nio.charset.Charset;
import java.util.Arrays;
/**
* 提供基于PKCS7算法的加解
*/
public class PKCS7Encoder {
private static final Charset CHARSET = Charset.forName("utf-8");
private static final int BLOCK_SIZE = 32;
/**
* 获得对明文进行补位填充的字节.
*
* @param count 需要进行填充补位操作的明文字节个数
* @return 补齐用的字节数组
*/
public static byte[] encode(int count) {
// 计算需要填充的位数
int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE);
if (amountToPad == 0) {
amountToPad = BLOCK_SIZE;
}
// 获得补位所用的字符
char padChr = chr(amountToPad);
String tmp = new String();
for (int index = 0; index < amountToPad; index++) {
tmp += padChr;
}
return tmp.getBytes(CHARSET);
}
/**
* 删除解密后明文的补位字符
*
* @param decrypted 解密后的明文
* @return 删除补位字符后的明文
*/
public static byte[] decode(byte[] decrypted) {
int pad = decrypted[decrypted.length - 1];
if (pad < 1 || pad > 32) {
pad = 0;
}
return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
}
/**
* 将数字转化成ASCII码对应的字符,用于对明文进行补码
*
* @param a 需要转化的数字
* @return 转化得到的字符
*/
public static char chr(int a) {
byte target = (byte) (a & 0xFF);
return (char) target;
}
}
/**
* 对公众平台发送给公众账号的消息加解密示例代码.
*
* @copyright Copyright (c) 1998-2014 Tencent Inc.
*/
// ------------------------------------------------------------------------
package me.chanjar.weixin.common.util.crypto;
import java.nio.charset.Charset;
import java.util.Arrays;
/**
* 提供基于PKCS7算法的加解
*/
public class PKCS7Encoder {
private static final Charset CHARSET = Charset.forName("utf-8");
private static final int BLOCK_SIZE = 32;
/**
* 获得对明文进行补位填充的字节.
*
* @param count 需要进行填充补位操作的明文字节个数
* @return 补齐用的字节数组
*/
public static byte[] encode(int count) {
// 计算需要填充的位数
int amountToPad = BLOCK_SIZE - (count % BLOCK_SIZE);
if (amountToPad == 0) {
amountToPad = BLOCK_SIZE;
}
// 获得补位所用的字符
char padChr = chr(amountToPad);
String tmp = new String();
for (int index = 0; index < amountToPad; index++) {
tmp += padChr;
}
return tmp.getBytes(CHARSET);
}
/**
* 删除解密后明文的补位字符
*
* @param decrypted 解密后的明文
* @return 删除补位字符后的明文
*/
public static byte[] decode(byte[] decrypted) {
int pad = decrypted[decrypted.length - 1];
if (pad < 1 || pad > 32) {
pad = 0;
}
return Arrays.copyOfRange(decrypted, 0, decrypted.length - pad);
}
/**
* 将数字转化成ASCII码对应的字符,用于对明文进行补码
*
* @param a 需要转化的数字
* @return 转化得到的字符
*/
public static char chr(int a) {
byte target = (byte) (a & 0xFF);
return (char) target;
}
}

+ 8
- 23
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/fs/FileUtils.java Visa fil

@@ -1,52 +1,37 @@
package me.chanjar.weixin.common.util.fs;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;

public class FileUtils {


/**
* 创建临时文件
*
* @param inputStream
* @param inputStream 输入文件流
* @param name 文件名
* @param ext 扩展名
* @param tmpDirFile 临时文件夹目录
*/
public static File createTmpFile(InputStream inputStream, String name, String ext, File tmpDirFile) throws IOException {
File tmpFile;
if (tmpDirFile == null) {
tmpFile = File.createTempFile(name, '.' + ext);
} else {
tmpFile = File.createTempFile(name, '.' + ext, tmpDirFile);
}

tmpFile.deleteOnExit();

try (FileOutputStream fos = new FileOutputStream(tmpFile)) {
int read = 0;
byte[] bytes = new byte[1024 * 100];
while ((read = inputStream.read(bytes)) != -1) {
fos.write(bytes, 0, read);
}
File resultFile = File.createTempFile(name, '.' + ext, tmpDirFile);

fos.flush();
return tmpFile;
}
resultFile.deleteOnExit();
org.apache.commons.io.FileUtils.copyInputStreamToFile(inputStream, resultFile);
return resultFile;
}

/**
* 创建临时文件
*
* @param inputStream
* @param inputStream 输入文件流
* @param name 文件名
* @param ext 扩展名
*/
public static File createTmpFile(InputStream inputStream, String name, String ext) throws IOException {
return createTmpFile(inputStream, name, ext, null);
return createTmpFile(inputStream, name, ext, Files.createTempDirectory("weixin-java-tools-temp").toFile());
}

}

weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/MediaDownloadRequestExecutor.java → weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/BaseMediaDownloadRequestExecutor.java Visa fil

@@ -12,11 +12,11 @@ import java.io.File;
*
* @author Daniel Qian
*/
public abstract class MediaDownloadRequestExecutor<H, P> implements RequestExecutor<File, String> {

public abstract class BaseMediaDownloadRequestExecutor<H, P> implements RequestExecutor<File, String> {
protected RequestHttp<H, P> requestHttp;
protected File tmpDirFile;
public MediaDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) {

public BaseMediaDownloadRequestExecutor(RequestHttp<H, P> requestHttp, File tmpDirFile) {
this.requestHttp = requestHttp;
this.tmpDirFile = tmpDirFile;
}

+ 7
- 5
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/HttpResponseProxy.java Visa fil

@@ -19,6 +19,8 @@ import java.util.regex.Pattern;
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
public class HttpResponseProxy {
private static final Pattern PATTERN = Pattern.compile(".*filename=\"(.*)\"");

private CloseableHttpResponse apacheHttpResponse;
private HttpResponse joddHttpResponse;
private Response okHttpResponse;
@@ -56,7 +58,7 @@ public class HttpResponseProxy {
private String getFileName(CloseableHttpResponse response) throws WxErrorException {
Header[] contentDispositionHeader = response.getHeaders("Content-disposition");
if (contentDispositionHeader == null || contentDispositionHeader.length == 0) {
throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build());
throw new WxErrorException(WxError.builder().errorMsg("无法获取到文件名").build());
}

return this.extractFileNameFromContentString(contentDispositionHeader[0].getValue());
@@ -74,15 +76,15 @@ public class HttpResponseProxy {

private String extractFileNameFromContentString(String content) throws WxErrorException {
if (content == null || content.length() == 0) {
throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build());
throw new WxErrorException(WxError.builder().errorMsg("无法获取到文件名").build());
}

Pattern p = Pattern.compile(".*filename=\"(.*)\"");
Matcher m = p.matcher(content);
Matcher m = PATTERN.matcher(content);
if (m.matches()) {
return m.group(1);
}
throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build());

throw new WxErrorException(WxError.builder().errorMsg("无法获取到文件名").build());
}

}

+ 7
- 17
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheHttpClientBuilder.java Visa fil

@@ -4,51 +4,41 @@ import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;

/**
* httpclient build interface
* httpclient build interface.
*
* @author kakotor
*/
public interface ApacheHttpClientBuilder {

/**
* 构建httpclient实例
* 构建httpclient实例.
*
* @return new instance of CloseableHttpClient
*/
CloseableHttpClient build();

/**
* 代理服务器地址
*
* @param httpProxyHost
* 代理服务器地址.
*/
ApacheHttpClientBuilder httpProxyHost(String httpProxyHost);

/**
* 代理服务器端口
*
* @param httpProxyPort
* 代理服务器端口.
*/
ApacheHttpClientBuilder httpProxyPort(int httpProxyPort);

/**
* 代理服务器用户名
*
* @param httpProxyUsername
* 代理服务器用户名.
*/
ApacheHttpClientBuilder httpProxyUsername(String httpProxyUsername);

/**
* 代理服务器密码
*
* @param httpProxyPassword
* 代理服务器密码.
*/
ApacheHttpClientBuilder httpProxyPassword(String httpProxyPassword);

/**
* ssl连接socket工厂
*
* @param sslConnectionSocketFactory
* ssl连接socket工厂.
*/
ApacheHttpClientBuilder sslConnectionSocketFactory(SSLConnectionSocketFactory sslConnectionSocketFactory);
}

+ 26
- 16
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheHttpDnsClientBuilder.java Visa fil

@@ -29,9 +29,8 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;

/**
* httpclient 连接管理器 自带DNS解析
* <p>
* 大部分代码拷贝自:DefaultApacheHttpClientBuilder
* httpclient 连接管理器 自带DNS解析.
* <p>大部分代码拷贝自:DefaultApacheHttpClientBuilder</p>
*
* @author Andy.Huo
*/
@@ -64,7 +63,7 @@ public class ApacheHttpDnsClientBuilder implements ApacheHttpClientBuilder {
private String httpProxyPassword;

/**
* 闲置连接监控线程
* 闲置连接监控线程.
*/
private IdleConnectionMonitorThread idleConnectionMonitorThread;
private HttpClientBuilder httpClientBuilder;
@@ -162,7 +161,7 @@ public class ApacheHttpDnsClientBuilder implements ApacheHttpClientBuilder {
}

/**
* 每路的最大链接数,默认10
* 每路的最大链接数,默认10.
*
* @param maxConnPerHost 每路的最大链接数,默认10
*/
@@ -171,7 +170,7 @@ public class ApacheHttpDnsClientBuilder implements ApacheHttpClientBuilder {
}

/**
* 最大总连接数,默认50
* 最大总连接数,默认50.
*
* @param maxTotalConn 最大总连接数,默认50
*/
@@ -180,7 +179,7 @@ public class ApacheHttpDnsClientBuilder implements ApacheHttpClientBuilder {
}

/**
* 自定义httpclient的User Agent
* 自定义httpclient的User Agent.
*
* @param userAgent User Agent
*/
@@ -196,9 +195,12 @@ public class ApacheHttpDnsClientBuilder implements ApacheHttpClientBuilder {
if (prepared.get()) {
return;
}
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", this.plainConnectionSocketFactory).register("https", this.sslConnectionSocketFactory)
.build();

Registry<ConnectionSocketFactory> registry =
RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", this.plainConnectionSocketFactory)
.register("https", this.sslConnectionSocketFactory)
.build();

@SuppressWarnings("resource")
PoolingHttpClientConnectionManager connectionManager;
@@ -219,8 +221,8 @@ public class ApacheHttpDnsClientBuilder implements ApacheHttpClientBuilder {
connectionManager
.setDefaultSocketConfig(SocketConfig.copy(SocketConfig.DEFAULT).setSoTimeout(this.soTimeout).build());

this.idleConnectionMonitorThread = new IdleConnectionMonitorThread(connectionManager, this.idleConnTimeout,
this.checkWaitTime);
this.idleConnectionMonitorThread = new IdleConnectionMonitorThread(
connectionManager, this.idleConnTimeout, this.checkWaitTime);
this.idleConnectionMonitorThread.setDaemon(true);
this.idleConnectionMonitorThread.start();

@@ -234,8 +236,8 @@ public class ApacheHttpDnsClientBuilder implements ApacheHttpClientBuilder {
if (StringUtils.isNotBlank(this.httpProxyHost) && StringUtils.isNotBlank(this.httpProxyUsername)) {
// 使用代理服务器 需要用户认证的代理服务器
CredentialsProvider provider = new BasicCredentialsProvider();
provider.setCredentials(new AuthScope(this.httpProxyHost, this.httpProxyPort),
new UsernamePasswordCredentials(this.httpProxyUsername, this.httpProxyPassword));
provider.setCredentials(new AuthScope(this.httpProxyHost, this.httpProxyPort)
, new UsernamePasswordCredentials(this.httpProxyUsername, this.httpProxyPassword));
this.httpClientBuilder.setDefaultCredentialsProvider(provider);
}

@@ -267,8 +269,10 @@ public class ApacheHttpDnsClientBuilder implements ApacheHttpClientBuilder {
private final int checkWaitTime;
private volatile boolean shutdown;

public IdleConnectionMonitorThread(HttpClientConnectionManager connMgr, int idleConnTimeout,
int checkWaitTime) {
/**
* 构造方法.
*/
public IdleConnectionMonitorThread(HttpClientConnectionManager connMgr, int idleConnTimeout, int checkWaitTime) {
super("IdleConnectionMonitorThread");
this.connMgr = connMgr;
this.idleConnTimeout = idleConnTimeout;
@@ -289,12 +293,18 @@ public class ApacheHttpDnsClientBuilder implements ApacheHttpClientBuilder {
}
}

/**
* 触发.
*/
public void trigger() {
synchronized (this) {
notifyAll();
}
}

/**
* 关闭.
*/
public void shutdown() {
this.shutdown = true;
synchronized (this) {


+ 2
- 2
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheMediaDownloadRequestExecutor.java Visa fil

@@ -4,7 +4,7 @@ import me.chanjar.weixin.common.bean.result.WxError;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.fs.FileUtils;
import me.chanjar.weixin.common.util.http.HttpResponseProxy;
import me.chanjar.weixin.common.util.http.MediaDownloadRequestExecutor;
import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor;
import me.chanjar.weixin.common.util.http.RequestHttp;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
@@ -23,7 +23,7 @@ import java.io.InputStream;
/**
* Created by ecoolper on 2017/5/5.
*/
public class ApacheMediaDownloadRequestExecutor extends MediaDownloadRequestExecutor<CloseableHttpClient, HttpHost> {
public class ApacheMediaDownloadRequestExecutor extends BaseMediaDownloadRequestExecutor<CloseableHttpClient, HttpHost> {

public ApacheMediaDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) {
super(requestHttp, tmpDirFile);


+ 1
- 3
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/apache/ApacheSimplePostRequestExecutor.java Visa fil

@@ -39,9 +39,7 @@ public class ApacheSimplePostRequestExecutor extends SimplePostRequestExecutor<C
try (CloseableHttpResponse response = requestHttp.getRequestHttpClient().execute(httpPost)) {
String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response);
if (responseContent.isEmpty()) {
throw new WxErrorException(
WxError.newBuilder().setErrorCode(9999).setErrorMsg("无响应内容")
.build());
throw new WxErrorException(WxError.builder().errorCode(9999).errorMsg("无响应内容").build());
}

if (responseContent.startsWith("<xml>")) {


+ 2
- 2
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpMediaDownloadRequestExecutor.java Visa fil

@@ -9,7 +9,7 @@ import me.chanjar.weixin.common.bean.result.WxError;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.fs.FileUtils;
import me.chanjar.weixin.common.util.http.HttpResponseProxy;
import me.chanjar.weixin.common.util.http.MediaDownloadRequestExecutor;
import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor;
import me.chanjar.weixin.common.util.http.RequestHttp;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
@@ -22,7 +22,7 @@ import java.io.InputStream;
/**
* Created by ecoolper on 2017/5/5.
*/
public class JoddHttpMediaDownloadRequestExecutor extends MediaDownloadRequestExecutor<HttpConnectionProvider, ProxyInfo> {
public class JoddHttpMediaDownloadRequestExecutor extends BaseMediaDownloadRequestExecutor<HttpConnectionProvider, ProxyInfo> {

public JoddHttpMediaDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) {
super(requestHttp, tmpDirFile);


+ 2
- 4
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/jodd/JoddHttpSimplePostRequestExecutor.java Visa fil

@@ -5,7 +5,6 @@ import jodd.http.HttpRequest;
import jodd.http.HttpResponse;
import jodd.http.ProxyInfo;
import jodd.util.StringPool;

import me.chanjar.weixin.common.bean.result.WxError;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.http.RequestHttp;
@@ -40,9 +39,8 @@ public class JoddHttpSimplePostRequestExecutor extends SimplePostRequestExecutor

String responseContent = response.bodyText();
if (responseContent.isEmpty()) {
throw new WxErrorException(
WxError.newBuilder().setErrorCode(9999).setErrorMsg("无响应内容")
.build());
throw new WxErrorException(WxError.builder().errorCode(9999).errorMsg("无响应内容")
.build());
}

if (responseContent.startsWith("<xml>")) {


+ 2
- 2
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/okhttp/OkHttpMediaDownloadRequestExecutor.java Visa fil

@@ -2,8 +2,8 @@ package me.chanjar.weixin.common.util.http.okhttp;

import me.chanjar.weixin.common.bean.result.WxError;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor;
import me.chanjar.weixin.common.util.http.HttpResponseProxy;
import me.chanjar.weixin.common.util.http.MediaDownloadRequestExecutor;
import me.chanjar.weixin.common.util.http.RequestHttp;
import okhttp3.OkHttpClient;
import okhttp3.Request;
@@ -21,7 +21,7 @@ import java.io.IOException;
/**
* Created by ecoolper on 2017/5/5.
*/
public class OkHttpMediaDownloadRequestExecutor extends MediaDownloadRequestExecutor<OkHttpClient, OkHttpProxyInfo> {
public class OkHttpMediaDownloadRequestExecutor extends BaseMediaDownloadRequestExecutor<OkHttpClient, OkHttpProxyInfo> {
private final Logger logger = LoggerFactory.getLogger(this.getClass());

public OkHttpMediaDownloadRequestExecutor(RequestHttp requestHttp, File tmpDirFile) {


+ 10
- 7
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxErrorAdapter.java Visa fil

@@ -14,23 +14,26 @@ import me.chanjar.weixin.common.bean.result.WxError;
import java.lang.reflect.Type;

/**
* @author Daniel Qian
* @author Daniel Qian.
*/
public class WxErrorAdapter implements JsonDeserializer<WxError> {

@Override
public WxError deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
WxError wxError = new WxError();
public WxError deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
WxError.WxErrorBuilder errorBuilder = WxError.builder();
JsonObject wxErrorJsonObject = json.getAsJsonObject();

if (wxErrorJsonObject.get("errcode") != null && !wxErrorJsonObject.get("errcode").isJsonNull()) {
wxError.setErrorCode(GsonHelper.getAsPrimitiveInt(wxErrorJsonObject.get("errcode")));
errorBuilder.errorCode(GsonHelper.getAsPrimitiveInt(wxErrorJsonObject.get("errcode")));
}
if (wxErrorJsonObject.get("errmsg") != null && !wxErrorJsonObject.get("errmsg").isJsonNull()) {
wxError.setErrorMsg(GsonHelper.getAsString(wxErrorJsonObject.get("errmsg")));
errorBuilder.errorMsg(GsonHelper.getAsString(wxErrorJsonObject.get("errmsg")));
}
wxError.setJson(json.toString());
return wxError;

errorBuilder.json(json.toString());

return errorBuilder.build();
}

}

+ 1
- 0
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxMenuGsonAdapter.java Visa fil

@@ -70,6 +70,7 @@ public class WxMenuGsonAdapter implements JsonSerializer<WxMenu>, JsonDeserializ
return matchRule;
}

@Deprecated
private WxMenuRule convertToRule(JsonObject json) {
WxMenuRule menuRule = new WxMenuRule();
//变态的微信接口,这里居然反人类的使用和序列化时不一样的名字


+ 0
- 1
weixin-java-common/src/test/java/me/chanjar/weixin/common/bean/WxErrorTest.java Visa fil

@@ -8,7 +8,6 @@ import org.testng.annotations.*;
public class WxErrorTest {

public void testFromJson() {

String json = "{ \"errcode\": 40003, \"errmsg\": \"invalid openid\" }";
WxError wxError = WxError.fromJson(json);
Assert.assertTrue(wxError.getErrorCode() == 40003);


+ 1
- 1
weixin-java-common/src/test/java/me/chanjar/weixin/common/util/crypto/SHA1Test.java Visa fil

@@ -10,7 +10,7 @@ import static org.testng.Assert.assertNotNull;
* Created by BinaryWang on 2017/6/10.
* </pre>
*
* @author <a href="https://github.com/binarywang">binarywang(Binary Wang)</a>
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
public class SHA1Test {
@Test


+ 1
- 1
weixin-java-cp/pom.xml Visa fil

@@ -7,7 +7,7 @@
<parent>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-parent</artifactId>
<version>2.8.0</version>
<version>2.9.0</version>
</parent>

<artifactId>weixin-java-cp</artifactId>


+ 2
- 2
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpMediaServiceImpl.java Visa fil

@@ -3,7 +3,7 @@ package me.chanjar.weixin.cp.api.impl;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.fs.FileUtils;
import me.chanjar.weixin.common.util.http.MediaDownloadRequestExecutor;
import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor;
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor;
import me.chanjar.weixin.cp.api.WxCpMediaService;
import me.chanjar.weixin.cp.api.WxCpService;
@@ -43,7 +43,7 @@ public class WxCpMediaServiceImpl implements WxCpMediaService {
public File download(String mediaId) throws WxErrorException {
String url = "https://qyapi.weixin.qq.com/cgi-bin/media/get";
return this.mainService.execute(
MediaDownloadRequestExecutor.create(this.mainService.getRequestHttp(),
BaseMediaDownloadRequestExecutor.create(this.mainService.getRequestHttp(),
this.mainService.getWxCpConfigStorage().getTmpDirFile()),
url, "media_id=" + mediaId);
}


+ 1
- 1
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceAbstractImpl.java Visa fil

@@ -381,7 +381,7 @@ public abstract class WxCpServiceAbstractImpl<H, P> implements WxCpService, Requ
throw new RuntimeException("微信服务端异常,超出重试次数");
}

protected synchronized <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException {
protected <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException {
if (uri.contains("access_token=")) {
throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri);
}


+ 2
- 1
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceImpl.java Visa fil

@@ -4,8 +4,9 @@ package me.chanjar.weixin.cp.api.impl;
* <pre>
* 默认接口实现类,使用apache httpclient实现
* Created by Binary Wang on 2017-5-27.
* @author <a href="https://github.com/binarywang">binarywang(Binary Wang)</a>
* </pre>
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
public class WxCpServiceImpl extends WxCpServiceApacheHttpClientImpl {
}

+ 13
- 14
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/impl/WxCpServiceOkHttpImpl.java Visa fil

@@ -7,14 +7,10 @@ import me.chanjar.weixin.common.util.http.HttpType;
import me.chanjar.weixin.common.util.http.okhttp.OkHttpProxyInfo;
import me.chanjar.weixin.cp.config.WxCpConfigStorage;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

public class WxCpServiceOkHttpImpl extends WxCpServiceAbstractImpl<OkHttpClient, OkHttpProxyInfo> {
private final Logger logger = LoggerFactory.getLogger(this.getClass());

protected OkHttpClient httpClient;
protected OkHttpProxyInfo httpProxy;

@@ -36,7 +32,7 @@ public class WxCpServiceOkHttpImpl extends WxCpServiceAbstractImpl<OkHttpClient,

@Override
public String getAccessToken(boolean forceRefresh) throws WxErrorException {
logger.debug("WxCpServiceOkHttpImpl is running");
this.log.debug("WxCpServiceOkHttpImpl is running");
if (this.configStorage.isAccessTokenExpired() || forceRefresh) {
synchronized (this.globalAccessTokenRefreshLock) {
if (this.configStorage.isAccessTokenExpired()) {
@@ -47,18 +43,14 @@ public class WxCpServiceOkHttpImpl extends WxCpServiceAbstractImpl<OkHttpClient,
OkHttpClient client = getRequestHttpClient();
//请求的request
Request request = new Request.Builder().url(url).get().build();
Response response = null;
try {
response = client.newCall(request).execute();
} catch (IOException e) {
e.printStackTrace();
}
String resultContent = null;
try {
Response response = client.newCall(request).execute();
resultContent = response.body().string();
} catch (IOException e) {
e.printStackTrace();
this.log.error(e.getMessage(), e);
}

WxError error = WxError.fromJson(resultContent);
if (error.getErrorCode() != 0) {
throw new WxErrorException(error);
@@ -74,9 +66,16 @@ public class WxCpServiceOkHttpImpl extends WxCpServiceAbstractImpl<OkHttpClient,

@Override
public void initHttp() {
logger.debug("WxCpServiceOkHttpImpl initHttp");
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
this.log.debug("WxCpServiceOkHttpImpl initHttp");
//设置代理
if (configStorage.getHttpProxyHost() != null && configStorage.getHttpProxyPort() > 0) {
httpProxy = OkHttpProxyInfo.httpProxy(configStorage.getHttpProxyHost(),
configStorage.getHttpProxyPort(),
configStorage.getHttpProxyUsername(),
configStorage.getHttpProxyPassword());
}

OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
if (httpProxy != null) {
clientBuilder.proxy(getRequestHttpProxy().getProxy());



+ 4
- 43
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpDepart.java Visa fil

@@ -1,69 +1,30 @@
package me.chanjar.weixin.cp.bean;

import lombok.Data;
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;

import java.io.Serializable;

/**
* 微信部门
* 微信部门.
*
* @author Daniel Qian
*/
@Data
public class WxCpDepart implements Serializable {

private static final long serialVersionUID = -5028321625140879571L;
private Integer id;
private String name;
private Integer parentId;
private Integer order;
private Long order;

public static WxCpDepart fromJson(String json) {
return WxCpGsonBuilder.create().fromJson(json, WxCpDepart.class);
}

public Integer getId() {
return this.id;
}

public void setId(Integer id) {
this.id = id;
}

public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}

public Integer getParentId() {
return this.parentId;
}

public void setParentId(Integer parentId) {
this.parentId = parentId;
}

public Integer getOrder() {
return this.order;
}

public void setOrder(Integer order) {
this.order = order;
}

public String toJson() {
return WxCpGsonBuilder.create().toJson(this);
}

@Override
public String toString() {
return "WxCpDepart{" +
"id=" + this.id +
", name='" + this.name + '\'' +
", parentId=" + this.parentId +
", order=" + this.order +
'}';
}
}

+ 20
- 139
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java Visa fil

@@ -1,5 +1,7 @@
package me.chanjar.weixin.cp.bean;

import lombok.Data;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.cp.bean.article.MpnewsArticle;
import me.chanjar.weixin.cp.bean.article.NewArticle;
import me.chanjar.weixin.cp.bean.messagebuilder.*;
@@ -10,13 +12,14 @@ import java.util.ArrayList;
import java.util.List;

/**
* 消息
* 消息.
*
* @author Daniel Qian
*/
@Data
public class WxCpMessage implements Serializable {

private static final long serialVersionUID = -2082278303476631708L;

private String toUser;
private String toParty;
private String toTag;
@@ -35,115 +38,72 @@ public class WxCpMessage implements Serializable {
private List<MpnewsArticle> mpnewsArticles = new ArrayList<>();

/**
* 获得文本消息builder
* 获得文本消息builder.
*/
public static TextBuilder TEXT() {
return new TextBuilder();
}

/**
* 获得文本卡片消息builder
* 获得文本卡片消息builder.
*/
public static TextCardBuilder TEXTCARD() {
return new TextCardBuilder();
}

/**
* 获得图片消息builder
* 获得图片消息builder.
*/
public static ImageBuilder IMAGE() {
return new ImageBuilder();
}

/**
* 获得语音消息builder
* 获得语音消息builder.
*/
public static VoiceBuilder VOICE() {
return new VoiceBuilder();
}

/**
* 获得视频消息builder
* 获得视频消息builder.
*/
public static VideoBuilder VIDEO() {
return new VideoBuilder();
}

/**
* 获得图文消息builder
* 获得图文消息builder.
*/
public static NewsBuilder NEWS() {
return new NewsBuilder();
}

/**
* 获得mpnews图文消息builder
* 获得mpnews图文消息builder.
*/
public static MpnewsBuilder MPNEWS() {
return new MpnewsBuilder();
}

/**
* 获得文件消息builder
* 获得文件消息builder.
*/
public static FileBuilder FILE() {
return new FileBuilder();
}

public List<MpnewsArticle> getMpnewsArticles() {
return mpnewsArticles;
}

public void setMpnewsArticles(List<MpnewsArticle> mpnewsArticles) {
this.mpnewsArticles = mpnewsArticles;
}

public String getToUser() {
return this.toUser;
}

public void setToUser(String toUser) {
this.toUser = toUser;
}

public String getToParty() {
return this.toParty;
}

public void setToParty(String toParty) {
this.toParty = toParty;
}

public String getToTag() {
return this.toTag;
}

public void setToTag(String toTag) {
this.toTag = toTag;
}

public Integer getAgentId() {
return this.agentId;
}

public void setAgentId(Integer agentId) {
this.agentId = agentId;
}

public String getMsgType() {
return this.msgType;
}

/**
* <pre>
* 请使用
* {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_TEXT}
* {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_IMAGE}
* {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_VOICE}
* {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_MUSIC}
* {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_VIDEO}
* {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_NEWS}
* {@link me.chanjar.weixin.common.api.WxConsts#CUSTOM_MSG_MPNEWS}
* {@link WxConsts.KefuMsgType#TEXT}
* {@link WxConsts.KefuMsgType#IMAGE}
* {@link WxConsts.KefuMsgType#VOICE}
* {@link WxConsts.KefuMsgType#MUSIC}
* {@link WxConsts.KefuMsgType#VIDEO}
* {@link WxConsts.KefuMsgType#NEWS}
* {@link WxConsts.KefuMsgType#MPNEWS}
* </pre>
*
* @param msgType 消息类型
@@ -152,87 +112,8 @@ public class WxCpMessage implements Serializable {
this.msgType = msgType;
}

public String getSafe() {
return this.safe;
}

public void setSafe(String safe) {
this.safe = safe;
}

public String getContent() {
return this.content;
}

public void setContent(String content) {
this.content = content;
}

public String getMediaId() {
return this.mediaId;
}

public void setMediaId(String mediaId) {
this.mediaId = mediaId;
}

public String getThumbMediaId() {
return this.thumbMediaId;
}

public void setThumbMediaId(String thumbMediaId) {
this.thumbMediaId = thumbMediaId;
}

public String getTitle() {
return this.title;
}

public void setTitle(String title) {
this.title = title;
}

public String getDescription() {
return this.description;
}

public void setDescription(String description) {
this.description = description;
}

public String getMusicUrl() {
return this.musicUrl;
}

public void setMusicUrl(String musicUrl) {
this.musicUrl = musicUrl;
}

public String getHqMusicUrl() {
return this.hqMusicUrl;
}

public void setHqMusicUrl(String hqMusicUrl) {
this.hqMusicUrl = hqMusicUrl;
}

public List<NewArticle> getArticles() {
return this.articles;
}

public void setArticles(List<NewArticle> articles) {
this.articles = articles;
}

public String toJson() {
return WxCpGsonBuilder.INSTANCE.create().toJson(this);
}

public String getUrl() {
return this.url;
}

public void setUrl(String url) {
this.url = url;
}
}

+ 9
- 44
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessageSendResult.java Visa fil

@@ -2,21 +2,25 @@ package me.chanjar.weixin.cp.bean;

import com.google.common.base.Splitter;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
import me.chanjar.weixin.common.util.ToStringUtils;
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.util.Collections;
import java.util.List;

/**
* <pre>
* 消息发送结果对象类
* 消息发送结果对象类.
* Created by Binary Wang on 2017-6-22.
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
* </pre>
*/
public class WxCpMessageSendResult {
@Data
public class WxCpMessageSendResult implements Serializable {
private static final long serialVersionUID = 916455987193190004L;

@Override
public String toString() {
return ToStringUtils.toSimpleString(this);
@@ -41,52 +45,13 @@ public class WxCpMessageSendResult {
@SerializedName("invalidtag")
private String invalidTag;

public Integer getErrCode() {
return this.errCode;
}

public void setErrCode(Integer errCode) {
this.errCode = errCode;
}

public String getErrMsg() {
return this.errMsg;
}

public void setErrMsg(String errMsg) {
this.errMsg = errMsg;
}

public String getInvalidUser() {
return this.invalidUser;
}

public void setInvalidUser(String invalidUser) {
this.invalidUser = invalidUser;
}

public String getInvalidParty() {
return this.invalidParty;
}

public void setInvalidParty(String invalidParty) {
this.invalidParty = invalidParty;
}

public String getInvalidTag() {
return this.invalidTag;
}

public void setInvalidTag(String invalidTag) {
this.invalidTag = invalidTag;
}

public List<String> getInvalidUserList() {
return this.content2List(this.invalidUser);
}

private List<String> content2List(String content) {
if(StringUtils.isBlank(content)){
if (StringUtils.isBlank(content)) {
return Collections.emptyList();
}



+ 7
- 27
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTag.java Visa fil

@@ -1,50 +1,30 @@
package me.chanjar.weixin.cp.bean;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;

import java.io.Serializable;

/**
* Created by Daniel Qian
* Created by Daniel Qian.
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class WxCpTag implements Serializable {

private static final long serialVersionUID = -7243320279646928402L;

private String id;

private String name;

public WxCpTag() {
super();
}

public WxCpTag(String id, String name) {
super();
this.id = id;
this.name = name;
}

public static WxCpTag fromJson(String json) {
return WxCpGsonBuilder.create().fromJson(json, WxCpTag.class);
}

public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}

public String getId() {
return this.id;
}

public void setId(String id) {
this.id = id;
}

public String toJson() {
return WxCpGsonBuilder.create().toJson(this);
}


+ 9
- 37
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTagAddOrRemoveUsersResult.java Visa fil

@@ -2,21 +2,25 @@ package me.chanjar.weixin.cp.bean;

import com.google.common.base.Splitter;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
import me.chanjar.weixin.common.util.ToStringUtils;
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
import org.apache.commons.lang3.StringUtils;

import java.io.Serializable;
import java.util.Collections;
import java.util.List;

/**
* <pre>
* 为标签添加或移除用户结果对象类
* 为标签添加或移除用户结果对象类.
* Created by Binary Wang on 2017-6-22.
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
* </pre>
*/
public class WxCpTagAddOrRemoveUsersResult {
@Data
public class WxCpTagAddOrRemoveUsersResult implements Serializable {
private static final long serialVersionUID = 1420065684270213578L;

@Override
public String toString() {
return ToStringUtils.toSimpleString(this);
@@ -38,44 +42,12 @@ public class WxCpTagAddOrRemoveUsersResult {
@SerializedName("invalidparty")
private String[] invalidParty;

public Integer getErrCode() {
return this.errCode;
}

public void setErrCode(Integer errCode) {
this.errCode = errCode;
}

public String getErrMsg() {
return this.errMsg;
}

public void setErrMsg(String errMsg) {
this.errMsg = errMsg;
}

public String getInvalidUser() {
return this.invalidUsers;
}

public void setInvalidUser(String invalidUser) {
this.invalidUsers = invalidUser;
}

public String[] getInvalidParty() {
return this.invalidParty;
}

public void setInvalidParty(String[] invalidParty) {
this.invalidParty = invalidParty;
}

public List<String> getInvalidUserList() {
return this.content2List(this.invalidUsers);
}

private List<String> content2List(String content) {
if(StringUtils.isBlank(content)){
if (StringUtils.isBlank(content)) {
return Collections.emptyList();
}



+ 8
- 142
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUser.java Visa fil

@@ -1,5 +1,7 @@
package me.chanjar.weixin.cp.bean;

import lombok.AllArgsConstructor;
import lombok.Data;
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;

import java.io.Serializable;
@@ -7,12 +9,12 @@ import java.util.ArrayList;
import java.util.List;

/**
* 微信用户信息
* 微信用户信息.
*
* @author Daniel Qian
*/
@Data
public class WxCpUser implements Serializable {

public enum Gender {
MALE("男", "1"),
FEMAIL("女", "2");
@@ -62,159 +64,23 @@ public class WxCpUser implements Serializable {
private String englishName;
private String telephone;

public static WxCpUser fromJson(String json) {
return WxCpGsonBuilder.INSTANCE.create().fromJson(json, WxCpUser.class);
}

public String getUserId() {
return this.userId;
}

public void setUserId(String userId) {
this.userId = userId;
}

public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}

public Integer[] getDepartIds() {
return this.departIds;
}

public void setDepartIds(Integer[] departIds) {
this.departIds = departIds;
}

public Gender getGender() {
return this.gender;
}

public void setGender(Gender gender) {
this.gender = gender;
}

public String getPosition() {
return this.position;
}

public void setPosition(String position) {
this.position = position;
}

public String getMobile() {
return this.mobile;
}

public void setMobile(String mobile) {
this.mobile = mobile;
}

public String getTelephone() {
return this.telephone;
}

public void setTelephone(String telephone) {
this.telephone = telephone;
}

public String getEmail() {
return this.email;
}

public void setEmail(String email) {
this.email = email;
}

public String getAvatar() {
return this.avatar;
}

public void setAvatar(String avatar) {
this.avatar = avatar;
}

public Integer getStatus() {
return this.status;
}

public void setStatus(Integer status) {
this.status = status;
}

public Integer getEnable() {
return this.enable;
}

public void setEnable(Integer enable) {
this.enable = enable;
}

public void addExtAttr(String name, String value) {
this.extAttrs.add(new Attr(name, value));
}

public List<Attr> getExtAttrs() {
return this.extAttrs;
}

public Integer getIsLeader() {
return isLeader;
}

public void setIsLeader(Integer isLeader) {
this.isLeader = isLeader;
}

public Integer getHideMobile() {
return hideMobile;
}

public void setHideMobile(Integer hideMobile) {
this.hideMobile = hideMobile;
}

public String getEnglishName() {
return englishName;
}

public void setEnglishName(String englishName) {
this.englishName = englishName;
public static WxCpUser fromJson(String json) {
return WxCpGsonBuilder.INSTANCE.create().fromJson(json, WxCpUser.class);
}

public String toJson() {
return WxCpGsonBuilder.INSTANCE.create().toJson(this);
}

@Data
@AllArgsConstructor
public static class Attr {
private String name;
private String value;

public Attr(String name, String value) {
this.name = name;
this.value = value;
}

public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}

public String getValue() {
return this.value;
}

public void setValue(String value) {
this.value = value;
}

}

}

+ 37
- 404
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java Visa fil

@@ -2,6 +2,9 @@ package me.chanjar.weixin.cp.bean;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamConverter;
import lombok.Data;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.util.ToStringUtils;
import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;
import me.chanjar.weixin.cp.config.WxCpConfigStorage;
import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil;
@@ -26,6 +29,7 @@ import java.util.List;
* @author Daniel Qian
*/
@XStreamAlias("xml")
@Data
public class WxCpXmlMessage implements Serializable {
private static final long serialVersionUID = -1042994982179476410L;

@@ -128,28 +132,29 @@ public class WxCpXmlMessage implements Serializable {
// 群发消息返回的结果
///////////////////////////////////////
/**
* 群发的结果
* 群发的结果.
*/
@XStreamAlias("Status")
@XStreamConverter(value = XStreamCDataConverter.class)
private String status;
/**
* group_id下粉丝数;或者openid_list中的粉丝数
* group_id下粉丝数;或者openid_list中的粉丝数.
*/
@XStreamAlias("TotalCount")
private Integer totalCount;
/**
* 过滤(过滤是指特定地区、性别的过滤、用户设置拒收的过滤,用户接收已超4条的过滤)后,准备发送的粉丝数,原则上,filterCount = sentCount + errorCount
* 过滤.
* (过滤是指特定地区、性别的过滤、用户设置拒收的过滤,用户接收已超4条的过滤)后,准备发送的粉丝数,原则上,filterCount = sentCount + errorCount
*/
@XStreamAlias("FilterCount")
private Integer filterCount;
/**
* 发送成功的粉丝数
* 发送成功的粉丝数.
*/
@XStreamAlias("SentCount")
private Integer sentCount;
/**
* 发送失败的粉丝数
* 发送失败的粉丝数.
*/
@XStreamAlias("ErrorCount")
private Integer errorCount;
@@ -174,13 +179,7 @@ public class WxCpXmlMessage implements Serializable {
}

/**
* 从加密字符串转换
*
* @param encryptedXml
* @param wxCpConfigStorage
* @param timestamp
* @param nonce
* @param msgSignature
* 从加密字符串转换.
*/
public static WxCpXmlMessage fromEncryptedXml(
String encryptedXml,
@@ -202,40 +201,16 @@ public class WxCpXmlMessage implements Serializable {
}
}

public Integer getAgentId() {
return this.agentId;
}

public void setAgentId(Integer agentId) {
this.agentId = agentId;
}

public String getToUserName() {
return this.toUserName;
}

public void setToUserName(String toUserName) {
this.toUserName = toUserName;
}

public Long getCreateTime() {
return this.createTime;
}

public void setCreateTime(Long createTime) {
this.createTime = createTime;
}

/**
* <pre>
* 当接受用户消息时,可能会获得以下值:
* {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_TEXT}
* {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_IMAGE}
* {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_VOICE}
* {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_VIDEO}
* {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_LOCATION}
* {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_LINK}
* {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_EVENT}
* {@link WxConsts.XmlMsgType#TEXT}
* {@link WxConsts.XmlMsgType#IMAGE}
* {@link WxConsts.XmlMsgType#VOICE}
* {@link WxConsts.XmlMsgType#VIDEO}
* {@link WxConsts.XmlMsgType#LOCATION}
* {@link WxConsts.XmlMsgType#LINK}
* {@link WxConsts.XmlMsgType#EVENT}
* </pre>
*/
public String getMsgType() {
@@ -245,363 +220,60 @@ public class WxCpXmlMessage implements Serializable {
/**
* <pre>
* 当发送消息的时候使用:
* {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_TEXT}
* {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_IMAGE}
* {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_VOICE}
* {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_VIDEO}
* {@link me.chanjar.weixin.common.api.WxConsts#XML_MSG_NEWS}
* {@link WxConsts.XmlMsgType#TEXT}
* {@link WxConsts.XmlMsgType#IMAGE}
* {@link WxConsts.XmlMsgType#VOICE}
* {@link WxConsts.XmlMsgType#VIDEO}
* {@link WxConsts.XmlMsgType#NEWS}
* </pre>
*
* @param msgType
*/
public void setMsgType(String msgType) {
this.msgType = msgType;
}

public String getContent() {
return this.content;
}

public void setContent(String content) {
this.content = content;
}

public Long getMsgId() {
return this.msgId;
}

public void setMsgId(Long msgId) {
this.msgId = msgId;
}

public String getPicUrl() {
return this.picUrl;
}

public void setPicUrl(String picUrl) {
this.picUrl = picUrl;
}

public String getMediaId() {
return this.mediaId;
}

public void setMediaId(String mediaId) {
this.mediaId = mediaId;
}

public String getFormat() {
return this.format;
}

public void setFormat(String format) {
this.format = format;
}

public String getThumbMediaId() {
return this.thumbMediaId;
}

public void setThumbMediaId(String thumbMediaId) {
this.thumbMediaId = thumbMediaId;
}

public Double getLocationX() {
return this.locationX;
}

public void setLocationX(Double locationX) {
this.locationX = locationX;
}

public Double getLocationY() {
return this.locationY;
}

public void setLocationY(Double locationY) {
this.locationY = locationY;
}

public Double getScale() {
return this.scale;
}

public void setScale(Double scale) {
this.scale = scale;
}

public String getLabel() {
return this.label;
}

public void setLabel(String label) {
this.label = label;
}

public String getTitle() {
return this.title;
}

public void setTitle(String title) {
this.title = title;
}

public String getDescription() {
return this.description;
}

public void setDescription(String description) {
this.description = description;
}

public String getUrl() {
return this.url;
}

public void setUrl(String url) {
this.url = url;
}

public String getEvent() {
return this.event;
}

public void setEvent(String event) {
this.event = event;
}

public String getEventKey() {
return this.eventKey;
}

public void setEventKey(String eventKey) {
this.eventKey = eventKey;
}

public String getTicket() {
return this.ticket;
}

public void setTicket(String ticket) {
this.ticket = ticket;
}

public Double getLatitude() {
return this.latitude;
}

public void setLatitude(Double latitude) {
this.latitude = latitude;
}

public Double getLongitude() {
return this.longitude;
}

public void setLongitude(Double longitude) {
this.longitude = longitude;
}

public Double getPrecision() {
return this.precision;
}

public void setPrecision(Double precision) {
this.precision = precision;
}

public String getRecognition() {
return this.recognition;
}

public void setRecognition(String recognition) {
this.recognition = recognition;
}

public String getFromUserName() {
return this.fromUserName;
}

public void setFromUserName(String fromUserName) {
this.fromUserName = fromUserName;
}

public String getStatus() {
return this.status;
}

public void setStatus(String status) {
this.status = status;
}

public Integer getTotalCount() {
return this.totalCount;
}

public void setTotalCount(Integer totalCount) {
this.totalCount = totalCount;
}

public Integer getFilterCount() {
return this.filterCount;
}

public void setFilterCount(Integer filterCount) {
this.filterCount = filterCount;
}

public Integer getSentCount() {
return this.sentCount;
}

public void setSentCount(Integer sentCount) {
this.sentCount = sentCount;
}

public Integer getErrorCount() {
return this.errorCount;
}

public void setErrorCount(Integer errorCount) {
this.errorCount = errorCount;
}

public WxCpXmlMessage.ScanCodeInfo getScanCodeInfo() {
return this.scanCodeInfo;
}

public void setScanCodeInfo(WxCpXmlMessage.ScanCodeInfo scanCodeInfo) {
this.scanCodeInfo = scanCodeInfo;
}

public WxCpXmlMessage.SendPicsInfo getSendPicsInfo() {
return this.sendPicsInfo;
}

public void setSendPicsInfo(WxCpXmlMessage.SendPicsInfo sendPicsInfo) {
this.sendPicsInfo = sendPicsInfo;
}

public WxCpXmlMessage.SendLocationInfo getSendLocationInfo() {
return this.sendLocationInfo;
}

public void setSendLocationInfo(WxCpXmlMessage.SendLocationInfo sendLocationInfo) {
this.sendLocationInfo = sendLocationInfo;
}

@Override
public String toString() {
return "WxCpXmlMessage{" +
"agentId=" + this.agentId +
", toUserName='" + this.toUserName + '\'' +
", fromUserName='" + this.fromUserName + '\'' +
", createTime=" + this.createTime +
", msgType='" + this.msgType + '\'' +
", content='" + this.content + '\'' +
", msgId=" + this.msgId +
", picUrl='" + this.picUrl + '\'' +
", mediaId='" + this.mediaId + '\'' +
", format='" + this.format + '\'' +
", thumbMediaId='" + this.thumbMediaId + '\'' +
", locationX=" + this.locationX +
", locationY=" + this.locationY +
", scale=" + this.scale +
", label='" + this.label + '\'' +
", title='" + this.title + '\'' +
", description='" + this.description + '\'' +
", url='" + this.url + '\'' +
", event='" + this.event + '\'' +
", eventKey='" + this.eventKey + '\'' +
", ticket='" + this.ticket + '\'' +
", latitude=" + this.latitude +
", longitude=" + this.longitude +
", precision=" + this.precision +
", recognition='" + this.recognition + '\'' +
", status='" + this.status + '\'' +
", totalCount=" + this.totalCount +
", filterCount=" + this.filterCount +
", sentCount=" + this.sentCount +
", errorCount=" + this.errorCount +
", scanCodeInfo=" + this.scanCodeInfo +
", sendPicsInfo=" + this.sendPicsInfo +
", sendLocationInfo=" + this.sendLocationInfo +
'}';
return ToStringUtils.toSimpleString(this);
}

@Data
@XStreamAlias("ScanCodeInfo")
public static class ScanCodeInfo {

/**
* 扫描类型,一般是qrcode.
*/
@XStreamAlias("ScanType")
@XStreamConverter(value = XStreamCDataConverter.class)
private String scanType;

/**
* 扫描结果,即二维码对应的字符串信息.
*/
@XStreamAlias("ScanResult")
@XStreamConverter(value = XStreamCDataConverter.class)
private String scanResult;

/**
* 扫描类型,一般是qrcode
*/
public String getScanType() {

return this.scanType;
}

public void setScanType(String scanType) {
this.scanType = scanType;
}

/**
* 扫描结果,即二维码对应的字符串信息
*/
public String getScanResult() {
return this.scanResult;
}

public void setScanResult(String scanResult) {
this.scanResult = scanResult;
}

}

@Data
@XStreamAlias("SendPicsInfo")
public static class SendPicsInfo {

@XStreamAlias("PicList")
protected final List<Item> picList = new ArrayList<>();

@XStreamAlias("Count")
private Long count;

public Long getCount() {
return this.count;
}

public void setCount(Long count) {
this.count = count;
}

public List<Item> getPicList() {
return this.picList;
}

@XStreamAlias("item")
@Data
public static class Item {

@XStreamAlias("PicMd5Sum")
@XStreamConverter(value = XStreamCDataConverter.class)
private String PicMd5Sum;

public String getPicMd5Sum() {
return this.PicMd5Sum;
}

public void setPicMd5Sum(String picMd5Sum) {
this.PicMd5Sum = picMd5Sum;
}
private String picMd5Sum;
}
}

@Data
@XStreamAlias("SendLocationInfo")
public static class SendLocationInfo {

@@ -623,47 +295,8 @@ public class WxCpXmlMessage implements Serializable {

@XStreamAlias("Poiname")
@XStreamConverter(value = XStreamCDataConverter.class)
private String poiname;

public String getLocationX() {
return this.locationX;
}

public void setLocationX(String locationX) {
this.locationX = locationX;
}

public String getLocationY() {
return this.locationY;
}

public void setLocationY(String locationY) {
this.locationY = locationY;
}
private String poiName;

public String getScale() {
return this.scale;
}

public void setScale(String scale) {
this.scale = scale;
}

public String getLabel() {
return this.label;
}

public void setLabel(String label) {
this.label = label;
}

public String getPoiname() {
return this.poiname;
}

public void setPoiname(String poiname) {
this.poiname = poiname;
}
}

}

+ 3
- 9
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessage.java Visa fil

@@ -2,10 +2,12 @@ package me.chanjar.weixin.cp.bean;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamConverter;
import lombok.Data;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter;

@XStreamAlias("xml")
@Data
public class WxCpXmlOutImageMessage extends WxCpXmlOutMessage {
private static final long serialVersionUID = -1099446240667237313L;

@@ -14,15 +16,7 @@ public class WxCpXmlOutImageMessage extends WxCpXmlOutMessage {
private String mediaId;

public WxCpXmlOutImageMessage() {
this.msgType = WxConsts.XML_MSG_IMAGE;
}

public String getMediaId() {
return this.mediaId;
}

public void setMediaId(String mediaId) {
this.mediaId = mediaId;
this.msgType = WxConsts.XmlMsgType.IMAGE;
}

}

+ 8
- 39
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutMessage.java Visa fil

@@ -2,6 +2,7 @@ package me.chanjar.weixin.cp.bean;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamConverter;
import lombok.Data;
import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;
import me.chanjar.weixin.cp.config.WxCpConfigStorage;
import me.chanjar.weixin.cp.bean.outxmlbuilder.*;
@@ -11,8 +12,8 @@ import me.chanjar.weixin.cp.util.xml.XStreamTransformer;
import java.io.Serializable;

@XStreamAlias("xml")
@Data
public abstract class WxCpXmlOutMessage implements Serializable {

private static final long serialVersionUID = 1418629839964153110L;

@XStreamAlias("ToUserName")
@@ -31,78 +32,46 @@ public abstract class WxCpXmlOutMessage implements Serializable {
protected String msgType;

/**
* 获得文本消息builder
* 获得文本消息builder.
*/
public static TextBuilder TEXT() {
return new TextBuilder();
}

/**
* 获得图片消息builder
* 获得图片消息builder.
*/
public static ImageBuilder IMAGE() {
return new ImageBuilder();
}

/**
* 获得语音消息builder
* 获得语音消息builder.
*/
public static VoiceBuilder VOICE() {
return new VoiceBuilder();
}

/**
* 获得视频消息builder
* 获得视频消息builder.
*/
public static VideoBuilder VIDEO() {
return new VideoBuilder();
}

/**
* 获得图文消息builder
* 获得图文消息builder.
*/
public static NewsBuilder NEWS() {
return new NewsBuilder();
}

public String getToUserName() {
return this.toUserName;
}

public void setToUserName(String toUserName) {
this.toUserName = toUserName;
}

public String getFromUserName() {
return this.fromUserName;
}

public void setFromUserName(String fromUserName) {
this.fromUserName = fromUserName;
}

public Long getCreateTime() {
return this.createTime;
}

public void setCreateTime(Long createTime) {
this.createTime = createTime;
}

public String getMsgType() {
return this.msgType;
}

public void setMsgType(String msgType) {
this.msgType = msgType;
}

protected String toXml() {
return XStreamTransformer.toXml((Class) this.getClass(), this);
}

/**
* 转换成加密的xml格式
* 转换成加密的xml格式.
*/
public String toEncryptedXml(WxCpConfigStorage wxCpConfigStorage) {
String plainXml = toXml();


+ 9
- 46
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessage.java Visa fil

@@ -2,6 +2,7 @@ package me.chanjar.weixin.cp.bean;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamConverter;
import lombok.Data;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;

@@ -9,84 +10,46 @@ import java.util.ArrayList;
import java.util.List;

@XStreamAlias("xml")
@Data
public class WxCpXmlOutNewsMessage extends WxCpXmlOutMessage {
private static final long serialVersionUID = -5796178637883178826L;

@XStreamAlias("Articles")
protected final List<Item> articles = new ArrayList<>();

@XStreamAlias("ArticleCount")
protected int articleCount;

public WxCpXmlOutNewsMessage() {
this.msgType = WxConsts.XML_MSG_NEWS;
this.msgType = WxConsts.XmlMsgType.NEWS;
}

public int getArticleCount() {
return this.articleCount;
}

public void addArticle(Item item) {
this.articles.add(item);
this.articleCount = this.articles.size();
}

public List<Item> getArticles() {
return this.articles;
}


@XStreamAlias("item")
@Data
public static class Item {

@XStreamAlias("Title")
@XStreamConverter(value = XStreamCDataConverter.class)
private String Title;
private String title;

@XStreamAlias("Description")
@XStreamConverter(value = XStreamCDataConverter.class)
private String Description;
private String description;

@XStreamAlias("PicUrl")
@XStreamConverter(value = XStreamCDataConverter.class)
private String PicUrl;
private String picUrl;

@XStreamAlias("Url")
@XStreamConverter(value = XStreamCDataConverter.class)
private String Url;

public String getTitle() {
return this.Title;
}

public void setTitle(String title) {
this.Title = title;
}

public String getDescription() {
return this.Description;
}

public void setDescription(String description) {
this.Description = description;
}

public String getPicUrl() {
return this.PicUrl;
}

public void setPicUrl(String picUrl) {
this.PicUrl = picUrl;
}

public String getUrl() {
return this.Url;
}

public void setUrl(String url) {
this.Url = url;
}
private String url;

}


}

+ 3
- 10
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessage.java Visa fil

@@ -2,10 +2,12 @@ package me.chanjar.weixin.cp.bean;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamConverter;
import lombok.Data;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;

@XStreamAlias("xml")
@Data
public class WxCpXmlOutTextMessage extends WxCpXmlOutMessage {
private static final long serialVersionUID = 2569239617185930232L;

@@ -14,16 +16,7 @@ public class WxCpXmlOutTextMessage extends WxCpXmlOutMessage {
private String content;

public WxCpXmlOutTextMessage() {
this.msgType = WxConsts.XML_MSG_TEXT;
this.msgType = WxConsts.XmlMsgType.TEXT;
}

public String getContent() {
return this.content;
}

public void setContent(String content) {
this.content = content;
}


}

+ 4
- 26
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessage.java Visa fil

@@ -2,10 +2,12 @@ package me.chanjar.weixin.cp.bean;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamConverter;
import lombok.Data;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;

@XStreamAlias("xml")
@Data
public class WxCpXmlOutVideoMessage extends WxCpXmlOutMessage {
private static final long serialVersionUID = -8672761162722733622L;

@@ -13,7 +15,7 @@ public class WxCpXmlOutVideoMessage extends WxCpXmlOutMessage {
protected final Video video = new Video();

public WxCpXmlOutVideoMessage() {
this.msgType = WxConsts.XML_MSG_VIDEO;
this.msgType = WxConsts.XmlMsgType.VIDEO;
}

public String getMediaId() {
@@ -40,7 +42,7 @@ public class WxCpXmlOutVideoMessage extends WxCpXmlOutMessage {
this.video.setDescription(description);
}

@Data
@XStreamAlias("Video")
public static class Video {

@@ -56,30 +58,6 @@ public class WxCpXmlOutVideoMessage extends WxCpXmlOutMessage {
@XStreamConverter(value = XStreamCDataConverter.class)
private String description;

public String getMediaId() {
return this.mediaId;
}

public void setMediaId(String mediaId) {
this.mediaId = mediaId;
}

public String getTitle() {
return this.title;
}

public void setTitle(String title) {
this.title = title;
}

public String getDescription() {
return this.description;
}

public void setDescription(String description) {
this.description = description;
}

}

}

+ 3
- 9
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessage.java Visa fil

@@ -2,10 +2,12 @@ package me.chanjar.weixin.cp.bean;

import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamConverter;
import lombok.Data;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.util.xml.XStreamMediaIdConverter;

@XStreamAlias("xml")
@Data
public class WxCpXmlOutVoiceMessage extends WxCpXmlOutMessage {
private static final long serialVersionUID = -7947384031546099340L;

@@ -14,15 +16,7 @@ public class WxCpXmlOutVoiceMessage extends WxCpXmlOutMessage {
private String mediaId;

public WxCpXmlOutVoiceMessage() {
this.msgType = WxConsts.XML_MSG_VOICE;
}

public String getMediaId() {
return this.mediaId;
}

public void setMediaId(String mediaId) {
this.mediaId = mediaId;
this.msgType = WxConsts.XmlMsgType.VOICE;
}

}

+ 5
- 121
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/MpnewsArticle.java Visa fil

@@ -1,5 +1,8 @@
package me.chanjar.weixin.cp.bean.article;

import lombok.Builder;
import lombok.Data;

import java.io.Serializable;

/**
@@ -9,6 +12,8 @@ import java.io.Serializable;
*
* @author Binary Wang
*/
@Data
@Builder(builderMethodName = "newBuilder")
public class MpnewsArticle implements Serializable {
private static final long serialVersionUID = 6985871812170756481L;

@@ -20,125 +25,4 @@ public class MpnewsArticle implements Serializable {
private String digest;
private String showCoverPic;

private MpnewsArticle(Builder builder) {
setTitle(builder.title);
setThumbMediaId(builder.thumbMediaId);
setAuthor(builder.author);
setContentSourceUrl(builder.contentSourceUrl);
setContent(builder.content);
setDigest(builder.digest);
setShowCoverPic(builder.showCoverPic);
}

public static Builder newBuilder() {
return new Builder();
}

public String getTitle() {
return title;
}

public void setTitle(String title) {
this.title = title;
}

public String getThumbMediaId() {
return thumbMediaId;
}

public void setThumbMediaId(String thumbMediaId) {
this.thumbMediaId = thumbMediaId;
}

public String getAuthor() {
return author;
}

public void setAuthor(String author) {
this.author = author;
}

public String getContentSourceUrl() {
return contentSourceUrl;
}

public void setContentSourceUrl(String contentSourceUrl) {
this.contentSourceUrl = contentSourceUrl;
}

public String getContent() {
return content;
}

public void setContent(String content) {
this.content = content;
}

public String getDigest() {
return digest;
}

public void setDigest(String digest) {
this.digest = digest;
}

public String getShowCoverPic() {
return showCoverPic;
}

public void setShowCoverPic(String showCoverPic) {
this.showCoverPic = showCoverPic;
}

public static final class Builder {
private String title;
private String thumbMediaId;
private String author;
private String contentSourceUrl;
private String content;
private String digest;
private String showCoverPic;

private Builder() {
}

public Builder title(String title) {
this.title = title;
return this;
}

public Builder thumbMediaId(String thumbMediaId) {
this.thumbMediaId = thumbMediaId;
return this;
}

public Builder author(String author) {
this.author = author;
return this;
}

public Builder contentSourceUrl(String contentSourceUrl) {
this.contentSourceUrl = contentSourceUrl;
return this;
}

public Builder content(String content) {
this.content = content;
return this;
}

public Builder digest(String digest) {
this.digest = digest;
return this;
}

public Builder showCoverPic(String showCoverPic) {
this.showCoverPic = showCoverPic;
return this;
}

public MpnewsArticle build() {
return new MpnewsArticle(this);
}
}
}

+ 3
- 32
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/article/NewArticle.java Visa fil

@@ -1,5 +1,7 @@
package me.chanjar.weixin.cp.bean.article;

import lombok.Data;

import java.io.Serializable;

/**
@@ -9,6 +11,7 @@ import java.io.Serializable;
*
* @author Binary Wang
*/
@Data
public class NewArticle implements Serializable {
private static final long serialVersionUID = 4087852055781140659L;

@@ -17,36 +20,4 @@ public class NewArticle implements Serializable {
private String url;
private String picUrl;

public String getTitle() {
return this.title;
}

public void setTitle(String title) {
this.title = title;
}

public String getDescription() {
return this.description;
}

public void setDescription(String description) {
this.description = description;
}

public String getUrl() {
return this.url;
}

public void setUrl(String url) {
this.url = url;
}

public String getPicUrl() {
return this.picUrl;
}

public void setPicUrl(String picUrl) {
this.picUrl = picUrl;
}

}

+ 1
- 1
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/BaseBuilder.java Visa fil

@@ -44,7 +44,7 @@ public class BaseBuilder<T> {
m.setToUser(this.toUser);
m.setToParty(this.toParty);
m.setToTag(this.toTag);
m.setSafe(StringUtils.defaultIfBlank(this.safe, WxConsts.CUSTOM_MSG_SAFE_NO));
m.setSafe(StringUtils.defaultIfBlank(this.safe, WxConsts.KefuMsgSafe.NO));
return m;
}



+ 1
- 1
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/FileBuilder.java Visa fil

@@ -15,7 +15,7 @@ public final class FileBuilder extends BaseBuilder<FileBuilder> {
private String mediaId;

public FileBuilder() {
this.msgType = WxConsts.CUSTOM_MSG_FILE;
this.msgType = WxConsts.KefuMsgType.FILE;
}

public FileBuilder mediaId(String media_id) {


+ 1
- 1
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/ImageBuilder.java Visa fil

@@ -15,7 +15,7 @@ public final class ImageBuilder extends BaseBuilder<ImageBuilder> {
private String mediaId;

public ImageBuilder() {
this.msgType = WxConsts.CUSTOM_MSG_IMAGE;
this.msgType = WxConsts.KefuMsgType.IMAGE;
}

public ImageBuilder mediaId(String media_id) {


+ 1
- 1
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/MpnewsBuilder.java Visa fil

@@ -23,7 +23,7 @@ public final class MpnewsBuilder extends BaseBuilder<MpnewsBuilder> {
private String mediaId;

public MpnewsBuilder() {
this.msgType = WxConsts.CUSTOM_MSG_MPNEWS;
this.msgType = WxConsts.KefuMsgType.MPNEWS;
}

public MpnewsBuilder mediaId(String mediaId) {


+ 1
- 1
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/NewsBuilder.java Visa fil

@@ -22,7 +22,7 @@ public final class NewsBuilder extends BaseBuilder<NewsBuilder> {
private List<NewArticle> articles = new ArrayList<>();

public NewsBuilder() {
this.msgType = WxConsts.CUSTOM_MSG_NEWS;
this.msgType = WxConsts.KefuMsgType.NEWS;
}

public NewsBuilder addArticle(NewArticle... articles) {


+ 1
- 1
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TextBuilder.java Visa fil

@@ -15,7 +15,7 @@ public final class TextBuilder extends BaseBuilder<TextBuilder> {
private String content;

public TextBuilder() {
this.msgType = WxConsts.CUSTOM_MSG_TEXT;
this.msgType = WxConsts.KefuMsgType.TEXT;
}

public TextBuilder content(String content) {


+ 1
- 1
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TextCardBuilder.java Visa fil

@@ -18,7 +18,7 @@ public class TextCardBuilder extends BaseBuilder<TextCardBuilder> {
private String url;

public TextCardBuilder() {
this.msgType = WxConsts.CUSTOM_MSG_TEXTCARD;
this.msgType = WxConsts.KefuMsgType.TEXTCARD;
}

public TextCardBuilder title(String title) {


+ 1
- 1
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VideoBuilder.java Visa fil

@@ -24,7 +24,7 @@ public final class VideoBuilder extends BaseBuilder<VideoBuilder> {
private String thumbMediaId;

public VideoBuilder() {
this.msgType = WxConsts.CUSTOM_MSG_VIDEO;
this.msgType = WxConsts.KefuMsgType.VIDEO;
}

public VideoBuilder mediaId(String mediaId) {


+ 1
- 1
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VoiceBuilder.java Visa fil

@@ -15,7 +15,7 @@ public final class VoiceBuilder extends BaseBuilder<VoiceBuilder> {
private String mediaId;

public VoiceBuilder() {
this.msgType = WxConsts.CUSTOM_MSG_VOICE;
this.msgType = WxConsts.KefuMsgType.VOICE;
}

public VoiceBuilder mediaId(String media_id) {


+ 5
- 1
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/config/WxCpJedisConfigStorage.java Visa fil

@@ -9,7 +9,11 @@ import redis.clients.jedis.JedisPoolConfig;
import java.io.File;

/**
* Jedis client implementor for wechat config storage
* Jedis client implementor for wechat config storage.
* <pre>
* 使用说明:本实现仅供参考,并不完整,
* 比如为减少项目依赖,未加入redis分布式锁的实现,如有需要请自行实现。
* </pre>
*
* @author gaigeshen
*/


+ 9
- 6
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/message/WxCpMessageRouter.java Visa fil

@@ -11,6 +11,7 @@ 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 org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@@ -215,17 +216,19 @@ public class WxCpMessageRouter {
}

protected boolean isDuplicateMessage(WxCpXmlMessage wxMessage) {

String messageId = "";
String messageId;
if (wxMessage.getMsgId() == null) {
messageId = String.valueOf(wxMessage.getCreateTime())
+ "-" + String.valueOf(wxMessage.getAgentId() == null ? "" : wxMessage.getAgentId())
+ "-" + StringUtils.trimToEmpty(String.valueOf(wxMessage.getAgentId()))
+ "-" + wxMessage.getFromUserName()
+ "-" + String.valueOf(wxMessage.getEventKey() == null ? "" : wxMessage.getEventKey())
+ "-" + String.valueOf(wxMessage.getEvent() == null ? "" : wxMessage.getEvent())
+ "-" + StringUtils.trimToEmpty(wxMessage.getEventKey())
+ "-" + StringUtils.trimToEmpty(wxMessage.getEvent())
;
} else {
messageId = String.valueOf(wxMessage.getMsgId());
messageId = new StringBuilder().append(wxMessage.getMsgId())
.append("-").append(wxMessage.getCreateTime())
.append("-").append(wxMessage.getFromUserName())
.toString();
}

return this.messageDuplicateChecker.isDuplicate(messageId);


+ 1
- 1
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpDepartGsonAdapter.java Visa fil

@@ -49,7 +49,7 @@ public class WxCpDepartGsonAdapter implements JsonSerializer<WxCpDepart>, JsonDe
depart.setName(GsonHelper.getAsString(departJson.get("name")));
}
if (departJson.get("order") != null && !departJson.get("order").isJsonNull()) {
depart.setOrder(GsonHelper.getAsInteger(departJson.get("order")));
depart.setOrder(GsonHelper.getAsLong(departJson.get("order")));
}
if (departJson.get("parentid") != null && !departJson.get("parentid").isJsonNull()) {
depart.setParentId(GsonHelper.getAsInteger(departJson.get("parentid")));


+ 8
- 8
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpMessageGsonAdapter.java Visa fil

@@ -37,13 +37,13 @@ public class WxCpMessageGsonAdapter implements JsonSerializer<WxCpMessage> {
if (StringUtils.isNotBlank(message.getToTag())) {
messageJson.addProperty("totag", message.getToTag());
}
if (WxConsts.CUSTOM_MSG_TEXT.equals(message.getMsgType())) {
if (WxConsts.KefuMsgType.TEXT.equals(message.getMsgType())) {
JsonObject text = new JsonObject();
text.addProperty("content", message.getContent());
messageJson.add("text", text);
}

if (WxConsts.CUSTOM_MSG_TEXTCARD.equals(message.getMsgType())) {
if (WxConsts.KefuMsgType.TEXTCARD.equals(message.getMsgType())) {
JsonObject text = new JsonObject();
text.addProperty("title", message.getTitle());
text.addProperty("description", message.getDescription());
@@ -51,19 +51,19 @@ public class WxCpMessageGsonAdapter implements JsonSerializer<WxCpMessage> {
messageJson.add("textcard", text);
}

if (WxConsts.CUSTOM_MSG_IMAGE.equals(message.getMsgType())) {
if (WxConsts.KefuMsgType.IMAGE.equals(message.getMsgType())) {
JsonObject image = new JsonObject();
image.addProperty("media_id", message.getMediaId());
messageJson.add("image", image);
}

if (WxConsts.CUSTOM_MSG_FILE.equals(message.getMsgType())) {
if (WxConsts.KefuMsgType.FILE.equals(message.getMsgType())) {
JsonObject image = new JsonObject();
image.addProperty("media_id", message.getMediaId());
messageJson.add("file", image);
}

if (WxConsts.CUSTOM_MSG_VOICE.equals(message.getMsgType())) {
if (WxConsts.KefuMsgType.VOICE.equals(message.getMsgType())) {
JsonObject voice = new JsonObject();
voice.addProperty("media_id", message.getMediaId());
messageJson.add("voice", voice);
@@ -73,7 +73,7 @@ public class WxCpMessageGsonAdapter implements JsonSerializer<WxCpMessage> {
messageJson.addProperty("safe", message.getSafe());
}

if (WxConsts.CUSTOM_MSG_VIDEO.equals(message.getMsgType())) {
if (WxConsts.KefuMsgType.VIDEO.equals(message.getMsgType())) {
JsonObject video = new JsonObject();
video.addProperty("media_id", message.getMediaId());
video.addProperty("thumb_media_id", message.getThumbMediaId());
@@ -82,7 +82,7 @@ public class WxCpMessageGsonAdapter implements JsonSerializer<WxCpMessage> {
messageJson.add("video", video);
}

if (WxConsts.CUSTOM_MSG_NEWS.equals(message.getMsgType())) {
if (WxConsts.KefuMsgType.NEWS.equals(message.getMsgType())) {
JsonObject newsJsonObject = new JsonObject();
JsonArray articleJsonArray = new JsonArray();
for (NewArticle article : message.getArticles()) {
@@ -97,7 +97,7 @@ public class WxCpMessageGsonAdapter implements JsonSerializer<WxCpMessage> {
messageJson.add("news", newsJsonObject);
}

if (WxConsts.CUSTOM_MSG_MPNEWS.equals(message.getMsgType())) {
if (WxConsts.KefuMsgType.MPNEWS.equals(message.getMsgType())) {
JsonObject newsJsonObject = new JsonObject();
if (message.getMediaId() != null) {
newsJsonObject.addProperty("media_id", message.getMediaId());


+ 25
- 13
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XStreamTransformer.java Visa fil

@@ -28,7 +28,7 @@ public class XStreamTransformer {
}

/**
* 注册扩展消息的解析器
* 注册扩展消息的解析器.
*
* @param clz 类型
* @param xStream xml解析器
@@ -46,17 +46,19 @@ public class XStreamTransformer {

private static Map<Class, XStream> configXStreamInstance() {
Map<Class, XStream> map = new HashMap<>();
map.put(WxCpXmlMessage.class, config_WxCpXmlMessage());
map.put(WxCpXmlOutNewsMessage.class, config_WxCpXmlOutNewsMessage());
map.put(WxCpXmlOutTextMessage.class, config_WxCpXmlOutTextMessage());
map.put(WxCpXmlOutImageMessage.class, config_WxCpXmlOutImageMessage());
map.put(WxCpXmlOutVideoMessage.class, config_WxCpXmlOutVideoMessage());
map.put(WxCpXmlOutVoiceMessage.class, config_WxCpXmlOutVoiceMessage());
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());
return map;
}

private static XStream config_WxCpXmlMessage() {
private static XStream configWxCpXmlMessage() {
XStream xstream = XStreamInitializer.getInstance();
xstream.setClassLoader(Thread.currentThread().getContextClassLoader());

xstream.processAnnotations(WxCpXmlMessage.class);
xstream.processAnnotations(WxCpXmlMessage.ScanCodeInfo.class);
xstream.processAnnotations(WxCpXmlMessage.SendPicsInfo.class);
@@ -65,38 +67,48 @@ public class XStreamTransformer {
return xstream;
}

private static XStream config_WxCpXmlOutImageMessage() {
private static XStream configWxCpXmlOutImageMessage() {
XStream xstream = XStreamInitializer.getInstance();
xstream.setClassLoader(Thread.currentThread().getContextClassLoader());

xstream.processAnnotations(WxCpXmlOutMessage.class);
xstream.processAnnotations(WxCpXmlOutImageMessage.class);
return xstream;
}

private static XStream config_WxCpXmlOutNewsMessage() {
private static XStream configWxCpXmlOutNewsMessage() {
XStream xstream = XStreamInitializer.getInstance();
xstream.setClassLoader(Thread.currentThread().getContextClassLoader());

xstream.processAnnotations(WxCpXmlOutMessage.class);
xstream.processAnnotations(WxCpXmlOutNewsMessage.class);
xstream.processAnnotations(WxCpXmlOutNewsMessage.Item.class);
return xstream;
}

private static XStream config_WxCpXmlOutTextMessage() {
private static XStream configWxCpXmlOutTextMessage() {
XStream xstream = XStreamInitializer.getInstance();
xstream.setClassLoader(Thread.currentThread().getContextClassLoader());

xstream.processAnnotations(WxCpXmlOutMessage.class);
xstream.processAnnotations(WxCpXmlOutTextMessage.class);
return xstream;
}

private static XStream config_WxCpXmlOutVideoMessage() {
private static XStream configWxCpXmlOutVideoMessage() {
XStream xstream = XStreamInitializer.getInstance();
xstream.setClassLoader(Thread.currentThread().getContextClassLoader());

xstream.processAnnotations(WxCpXmlOutMessage.class);
xstream.processAnnotations(WxCpXmlOutVideoMessage.class);
xstream.processAnnotations(WxCpXmlOutVideoMessage.Video.class);
return xstream;
}

private static XStream config_WxCpXmlOutVoiceMessage() {
private static XStream configWxCpXmlOutVoiceMessage() {
XStream xstream = XStreamInitializer.getInstance();
xstream.setClassLoader(Thread.currentThread().getContextClassLoader());

xstream.processAnnotations(WxCpXmlOutMessage.class);
xstream.processAnnotations(WxCpXmlOutVoiceMessage.class);
return xstream;


+ 1
- 3
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBusyRetryTest.java Visa fil

@@ -24,9 +24,7 @@ public class WxCpBusyRetryTest {
RequestExecutor<T, E> executor, String uri, E data)
throws WxErrorException {
this.log.info("Executed");
WxError error = new WxError();
error.setErrorCode(-1);
throw new WxErrorException(error);
throw new WxErrorException(WxError.builder().errorCode(-1).build());
}
};



+ 1
- 2
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageAPITest.java Visa fil

@@ -3,7 +3,6 @@ package me.chanjar.weixin.cp.api;
import com.google.inject.Inject;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.cp.api.impl.WxCpServiceImpl;
import me.chanjar.weixin.cp.bean.WxCpMessage;
import me.chanjar.weixin.cp.bean.WxCpMessageSendResult;
import org.testng.annotations.*;
@@ -32,7 +31,7 @@ public class WxCpMessageAPITest {
public void testSendMessage() throws WxErrorException {
WxCpMessage message = new WxCpMessage();
// message.setAgentId(configStorage.getAgentId());
message.setMsgType(WxConsts.CUSTOM_MSG_TEXT);
message.setMsgType(WxConsts.KefuMsgType.TEXT);
message.setToUser(configStorage.getUserId());
message.setContent("欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>");



+ 15
- 15
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageRouterTest.java Visa fil

@@ -27,21 +27,21 @@ public class WxCpMessageRouterTest {
router
.rule()
.async(async)
.msgType(WxConsts.XML_MSG_TEXT).event(WxConsts.EVT_CLICK).eventKey("KEY_1").content("CONTENT_1")
.msgType(WxConsts.XmlMsgType.TEXT).event(WxConsts.EventType.CLICK).eventKey("KEY_1").content("CONTENT_1")
.handler(new WxEchoCpMessageHandler(sb, "COMBINE_4"))
.end()
.rule()
.async(async)
.msgType(WxConsts.XML_MSG_TEXT).event(WxConsts.EVT_CLICK).eventKey("KEY_1")
.msgType(WxConsts.XmlMsgType.TEXT).event(WxConsts.EventType.CLICK).eventKey("KEY_1")
.handler(new WxEchoCpMessageHandler(sb, "COMBINE_3"))
.end()
.rule()
.async(async)
.msgType(WxConsts.XML_MSG_TEXT).event(WxConsts.EVT_CLICK)
.msgType(WxConsts.XmlMsgType.TEXT).event(WxConsts.EventType.CLICK)
.handler(new WxEchoCpMessageHandler(sb, "COMBINE_2"))
.end()
.rule().async(async).msgType(WxConsts.XML_MSG_TEXT).handler(new WxEchoCpMessageHandler(sb, WxConsts.XML_MSG_TEXT)).end()
.rule().async(async).event(WxConsts.EVT_CLICK).handler(new WxEchoCpMessageHandler(sb, WxConsts.EVT_CLICK)).end()
.rule().async(async).msgType(WxConsts.XmlMsgType.TEXT).handler(new WxEchoCpMessageHandler(sb, WxConsts.XmlMsgType.TEXT)).end()
.rule().async(async).event(WxConsts.EventType.CLICK).handler(new WxEchoCpMessageHandler(sb, WxConsts.EventType.CLICK)).end()
.rule().async(async).eventKey("KEY_1").handler(new WxEchoCpMessageHandler(sb, "KEY_1")).end()
.rule().async(async).content("CONTENT_1").handler(new WxEchoCpMessageHandler(sb, "CONTENT_1")).end()
.rule().async(async).rContent(".*bc.*").handler(new WxEchoCpMessageHandler(sb, "abcd")).end()
@@ -104,10 +104,10 @@ public class WxCpMessageRouterTest {
@DataProvider(name = "messages-1")
public Object[][] messages2() {
WxCpXmlMessage message1 = new WxCpXmlMessage();
message1.setMsgType(WxConsts.XML_MSG_TEXT);
message1.setMsgType(WxConsts.XmlMsgType.TEXT);

WxCpXmlMessage message2 = new WxCpXmlMessage();
message2.setEvent(WxConsts.EVT_CLICK);
message2.setEvent(WxConsts.EventType.CLICK);

WxCpXmlMessage message3 = new WxCpXmlMessage();
message3.setEventKey("KEY_1");
@@ -125,24 +125,24 @@ public class WxCpMessageRouterTest {
message7.setFormat("strangeformat");

WxCpXmlMessage c2 = new WxCpXmlMessage();
c2.setMsgType(WxConsts.XML_MSG_TEXT);
c2.setEvent(WxConsts.EVT_CLICK);
c2.setMsgType(WxConsts.XmlMsgType.TEXT);
c2.setEvent(WxConsts.EventType.CLICK);

WxCpXmlMessage c3 = new WxCpXmlMessage();
c3.setMsgType(WxConsts.XML_MSG_TEXT);
c3.setEvent(WxConsts.EVT_CLICK);
c3.setMsgType(WxConsts.XmlMsgType.TEXT);
c3.setEvent(WxConsts.EventType.CLICK);
c3.setEventKey("KEY_1");

WxCpXmlMessage c4 = new WxCpXmlMessage();
c4.setMsgType(WxConsts.XML_MSG_TEXT);
c4.setEvent(WxConsts.EVT_CLICK);
c4.setMsgType(WxConsts.XmlMsgType.TEXT);
c4.setEvent(WxConsts.EventType.CLICK);
c4.setEventKey("KEY_1");
c4.setContent("CONTENT_1");


return new Object[][]{
new Object[]{message1, WxConsts.XML_MSG_TEXT + ","},
new Object[]{message2, WxConsts.EVT_CLICK + ","},
new Object[]{message1, WxConsts.XmlMsgType.TEXT + ","},
new Object[]{message2, WxConsts.EventType.CLICK + ","},
new Object[]{message3, "KEY_1,"},
new Object[]{message4, "CONTENT_1,"},
new Object[]{message5, "ALL,"},


+ 2
- 4
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpDepartmentServiceImplTest.java Visa fil

@@ -1,12 +1,10 @@
package me.chanjar.weixin.cp.api.impl;

import com.google.inject.Inject;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.cp.api.ApiTestModule;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.bean.WxCpDepart;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;
import org.testng.annotations.*;

import java.util.List;

@@ -31,7 +29,7 @@ public class WxCpDepartmentServiceImplTest {
WxCpDepart cpDepart = new WxCpDepart();
cpDepart.setName("子部门" + System.currentTimeMillis());
cpDepart.setParentId(1);
cpDepart.setOrder(1);
cpDepart.setOrder(1L);
Integer departId = this.wxCpService.getDepartmentService().create(cpDepart);
System.out.println(departId);
}


+ 5
- 5
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpMediaServiceImplTest.java Visa fil

@@ -34,11 +34,11 @@ public class WxCpMediaServiceImplTest {
@DataProvider
public Object[][] mediaData() {
return new Object[][]{
new Object[]{WxConsts.MEDIA_IMAGE, TestConstants.FILE_JPG, "mm.jpeg"},
new Object[]{WxConsts.MEDIA_VOICE, TestConstants.FILE_MP3, "mm.mp3"},
new Object[]{WxConsts.MEDIA_VOICE, TestConstants.FILE_AMR, "mm.amr"},//{"errcode":301017,"errmsg":"voice file only support amr like myvoice.amr"}
new Object[]{WxConsts.MEDIA_VIDEO, TestConstants.FILE_MP4, "mm.mp4"},
new Object[]{WxConsts.MEDIA_FILE, TestConstants.FILE_JPG, "mm.jpeg"}
new Object[]{WxConsts.MediaFileType.IMAGE, TestConstants.FILE_JPG, "mm.jpeg"},
new Object[]{WxConsts.MediaFileType.VOICE, TestConstants.FILE_MP3, "mm.mp3"},
new Object[]{WxConsts.MediaFileType.VOICE, TestConstants.FILE_AMR, "mm.amr"},//{"errcode":301017,"errmsg":"voice file only support amr like myvoice.amr"}
new Object[]{WxConsts.MediaFileType.VIDEO, TestConstants.FILE_MP4, "mm.mp4"},
new Object[]{WxConsts.MediaFileType.FILE, TestConstants.FILE_JPG, "mm.jpeg"}
};
}



+ 5
- 5
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/impl/WxCpMenuServiceImplTest.java Visa fil

@@ -26,12 +26,12 @@ public class WxCpMenuServiceImplTest {
public Object[][] menuData() {
WxMenu menu = new WxMenu();
WxMenuButton button1 = new WxMenuButton();
button1.setType(WxConsts.BUTTON_CLICK);
button1.setType(WxConsts.MenuButtonType.CLICK);
button1.setName("今日歌曲");
button1.setKey("V1001_TODAY_MUSIC");

WxMenuButton button2 = new WxMenuButton();
button2.setType(WxConsts.BUTTON_CLICK);
button2.setType(WxConsts.MenuButtonType.CLICK);
button2.setName("歌手简介");
button2.setKey("V1001_TODAY_SINGER");

@@ -43,17 +43,17 @@ public class WxCpMenuServiceImplTest {
menu.getButtons().add(button3);

WxMenuButton button31 = new WxMenuButton();
button31.setType(WxConsts.BUTTON_VIEW);
button31.setType(WxConsts.MenuButtonType.VIEW);
button31.setName("搜索");
button31.setUrl("http://www.soso.com/");

WxMenuButton button32 = new WxMenuButton();
button32.setType(WxConsts.BUTTON_VIEW);
button32.setType(WxConsts.MenuButtonType.VIEW);
button32.setName("视频");
button32.setUrl("http://v.qq.com/");

WxMenuButton button33 = new WxMenuButton();
button33.setType(WxConsts.BUTTON_CLICK);
button33.setType(WxConsts.MenuButtonType.CLICK);
button33.setName("赞一下我们");
button33.setKey("V1001_GOOD");



+ 3
- 3
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/bean/WxCpXmlMessageTest.java Visa fil

@@ -58,7 +58,7 @@ public class WxCpXmlMessageTest {
assertEquals(wxMessage.getToUserName(), "toUser");
assertEquals(wxMessage.getFromUserName(), "fromUser");
assertEquals(wxMessage.getCreateTime(), new Long(1348831860l));
assertEquals(wxMessage.getMsgType(), WxConsts.XML_MSG_TEXT);
assertEquals(wxMessage.getMsgType(), WxConsts.XmlMsgType.TEXT);
assertEquals(wxMessage.getContent(), "this is a test");
assertEquals(wxMessage.getMsgId(), new Long(1234567890123456l));
assertEquals(wxMessage.getPicUrl(), "this is a url");
@@ -86,7 +86,7 @@ public class WxCpXmlMessageTest {
assertEquals(wxMessage.getSendLocationInfo().getLocationY(), "113");
assertEquals(wxMessage.getSendLocationInfo().getScale(), "15");
assertEquals(wxMessage.getSendLocationInfo().getLabel(), " 广州市海珠区客村艺苑路 106号");
assertEquals(wxMessage.getSendLocationInfo().getPoiname(), "wo de poi");
assertEquals(wxMessage.getSendLocationInfo().getPoiName(), "wo de poi");
}

public void testSendPicsInfo() {
@@ -108,7 +108,7 @@ public class WxCpXmlMessageTest {
assertEquals(wxMessage.getToUserName(), "wx45a0972125658be9");
assertEquals(wxMessage.getFromUserName(), "xiaohe");
assertEquals(wxMessage.getCreateTime(), new Long(1502012364L));
assertEquals(wxMessage.getMsgType(), WxConsts.XML_MSG_EVENT);
assertEquals(wxMessage.getMsgType(), WxConsts.XmlMsgType.EVENT);
assertEquals(wxMessage.getAgentId(), Integer.valueOf(1000004));
assertEquals(wxMessage.getEvent(), "pic_weixin");
assertEquals(wxMessage.getEventKey(), "faceSimilarity");


+ 1
- 1
weixin-java-miniapp/pom.xml Visa fil

@@ -7,7 +7,7 @@
<parent>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-parent</artifactId>
<version>2.8.0</version>
<version>2.9.0</version>
</parent>
<artifactId>weixin-java-miniapp</artifactId>
<name>WeiXin Java Tools - MiniApp</name>


+ 6
- 44
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/WxMaQrcodeService.java Visa fil

@@ -1,5 +1,6 @@
package cn.binarywang.wx.miniapp.api;

import cn.binarywang.wx.miniapp.bean.WxMaCodeLineColor;
import me.chanjar.weixin.common.exception.WxErrorException;

import java.io.File;
@@ -16,6 +17,9 @@ import java.io.File;
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
public interface WxMaQrcodeService {
String CREATE_QRCODE_URL = "https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode";
String GET_WXACODE_URL = "https://api.weixin.qq.com/wxa/getwxacode";
String GET_WXACODE_UNLIMIT_URL = "https://api.weixin.qq.com/wxa/getwxacodeunlimit";

/**
* 接口C
@@ -42,10 +46,8 @@ public interface WxMaQrcodeService {
* @param width 默认430 二维码的宽度
* @param autoColor 默认true 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调
* @param lineColor auth_color 为 false 时生效,使用 rgb 设置颜色 例如 {"r":"xxx","g":"xxx","b":"xxx"}
* @return
* @throws WxErrorException
*/
File createWxCode(String path, int width, boolean autoColor, LineColor lineColor) throws WxErrorException;
File createWxCode(String path, int width, boolean autoColor, WxMaCodeLineColor lineColor) throws WxErrorException;

File createWxCode(String path, int width) throws WxErrorException;

@@ -65,49 +67,9 @@ public interface WxMaQrcodeService {
* @param width 默认false 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调
* @param autoColor 默认true 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调
* @param lineColor auth_color 为 false 时生效,使用 rgb 设置颜色 例如 {"r":"xxx","g":"xxx","b":"xxx"}
* @return
* @throws WxErrorException
*/
File createWxCodeLimit(String scene, String page, int width, boolean autoColor, LineColor lineColor) throws WxErrorException;
File createWxCodeLimit(String scene, String page, int width, boolean autoColor, WxMaCodeLineColor lineColor) throws WxErrorException;

File createWxCodeLimit(String scene, String page) throws WxErrorException;

/**
* lineColor 包装类
* 用于描述二维码(小程序码)颜色(RGB参数值),详情请查看文档
*/
public static class LineColor {

private String r = "0", g = "0", b = "0";

public LineColor(String r, String g, String b) {
this.r = r;
this.g = g;
this.b = b;
}

public String getR() {
return r;
}

public void setR(String r) {
this.r = r;
}

public String getG() {
return g;
}

public void setG(String g) {
this.g = g;
}

public String getB() {
return b;
}

public void setB(String b) {
this.b = b;
}
}
}

+ 4
- 10
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMediaServiceImpl.java Visa fil

@@ -6,11 +6,9 @@ import me.chanjar.weixin.common.bean.result.WxError;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.fs.FileUtils;
import me.chanjar.weixin.common.util.http.MediaDownloadRequestExecutor;
import me.chanjar.weixin.common.util.http.BaseMediaDownloadRequestExecutor;
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor;
import me.chanjar.weixin.common.util.http.RequestExecutor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
@@ -22,8 +20,6 @@ import java.util.UUID;
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
public class WxMaMediaServiceImpl implements WxMaMediaService {
private final Logger log = LoggerFactory.getLogger(this.getClass());

private WxMaService wxMaService;

public WxMaMediaServiceImpl(WxMaService wxMaService) {
@@ -35,8 +31,7 @@ public class WxMaMediaServiceImpl implements WxMaMediaService {
try {
return this.uploadMedia(mediaType, FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType));
} catch (IOException e) {
e.printStackTrace();
throw new WxErrorException(WxError.newBuilder().setErrorMsg(e.getMessage()).build());
throw new WxErrorException(WxError.builder().errorMsg(e.getMessage()).build(), e);
}
}

@@ -49,12 +44,11 @@ public class WxMaMediaServiceImpl implements WxMaMediaService {
@Override
public File getMedia(String mediaId) throws WxErrorException {
try {
RequestExecutor<File, String> executor = MediaDownloadRequestExecutor
RequestExecutor<File, String> executor = BaseMediaDownloadRequestExecutor
.create(this.wxMaService.getRequestHttp(), Files.createTempDirectory("wxma").toFile());
return this.wxMaService.execute(executor, MEDIA_GET_URL, "media_id=" + mediaId);
} catch (IOException e) {
this.log.error(e.getMessage(), e);
throw new WxErrorException(WxError.newBuilder().setErrorMsg(e.getMessage()).build());
throw new WxErrorException(WxError.builder().errorMsg(e.getMessage()).build(), e);
}
}



+ 2
- 1
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImpl.java Visa fil

@@ -4,6 +4,7 @@ import cn.binarywang.wx.miniapp.api.WxMaMsgService;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaKefuMessage;
import cn.binarywang.wx.miniapp.bean.WxMaTemplateMessage;
import cn.binarywang.wx.miniapp.constant.WxMaConstants;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import me.chanjar.weixin.common.bean.result.WxError;
@@ -30,7 +31,7 @@ public class WxMaMsgServiceImpl implements WxMaMsgService {
public void sendTemplateMsg(WxMaTemplateMessage templateMessage) throws WxErrorException {
String responseContent = this.wxMaService.post(TEMPLATE_MSG_SEND_URL, templateMessage.toJson());
JsonObject jsonObject = JSON_PARSER.parse(responseContent).getAsJsonObject();
if (jsonObject.get("errcode").getAsInt() != 0) {
if (jsonObject.get(WxMaConstants.ERRCODE).getAsInt() != 0) {
throw new WxErrorException(WxError.fromJson(responseContent));
}
}


+ 6
- 8
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaQrcodeServiceImpl.java Visa fil

@@ -2,6 +2,7 @@ package cn.binarywang.wx.miniapp.api.impl;

import cn.binarywang.wx.miniapp.api.WxMaQrcodeService;
import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaCodeLineColor;
import cn.binarywang.wx.miniapp.bean.WxMaQrcode;
import cn.binarywang.wx.miniapp.bean.WxMaWxcode;
import cn.binarywang.wx.miniapp.bean.WxMaWxcodeLimit;
@@ -22,9 +23,8 @@ public class WxMaQrcodeServiceImpl implements WxMaQrcodeService {

@Override
public File createQrcode(String path, int width) throws WxErrorException {
String url = "https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode";
return this.wxMaService.execute(new QrCodeRequestExecutor(this.wxMaService.getRequestHttp()),
url, new WxMaQrcode(path, width));
CREATE_QRCODE_URL, new WxMaQrcode(path, width));
}

@Override
@@ -33,15 +33,14 @@ public class WxMaQrcodeServiceImpl implements WxMaQrcodeService {
}

@Override
public File createWxCode(String path, int width, boolean autoColor, LineColor lineColor) throws WxErrorException {
String url = "https://api.weixin.qq.com/wxa/getwxacode";
public File createWxCode(String path, int width, boolean autoColor, WxMaCodeLineColor lineColor) throws WxErrorException {
WxMaWxcode wxMaWxcode = new WxMaWxcode();
wxMaWxcode.setPath(path);
wxMaWxcode.setWidth(width);
wxMaWxcode.setAutoColor(autoColor);
wxMaWxcode.setLineColor(lineColor);
return this.wxMaService.execute(new QrCodeRequestExecutor(this.wxMaService.getRequestHttp()),
url, wxMaWxcode);
GET_WXACODE_URL, wxMaWxcode);
}

@Override
@@ -55,8 +54,7 @@ public class WxMaQrcodeServiceImpl implements WxMaQrcodeService {
}

@Override
public File createWxCodeLimit(String scene, String page, int width, boolean autoColor, LineColor lineColor) throws WxErrorException {
String url = "http://api.weixin.qq.com/wxa/getwxacodeunlimit";
public File createWxCodeLimit(String scene, String page, int width, boolean autoColor, WxMaCodeLineColor lineColor) throws WxErrorException {
WxMaWxcodeLimit wxMaWxcodeLimit = new WxMaWxcodeLimit();
wxMaWxcodeLimit.setScene(scene);
wxMaWxcodeLimit.setPage(page);
@@ -64,7 +62,7 @@ public class WxMaQrcodeServiceImpl implements WxMaQrcodeService {
wxMaWxcodeLimit.setAutoColor(autoColor);
wxMaWxcodeLimit.setLineColor(lineColor);
return this.wxMaService.execute(new QrCodeRequestExecutor(this.wxMaService.getRequestHttp()),
url, wxMaWxcodeLimit);
GET_WXACODE_UNLIMIT_URL, wxMaWxcodeLimit);
}

@Override


+ 6
- 5
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaServiceImpl.java Visa fil

@@ -2,6 +2,7 @@ package cn.binarywang.wx.miniapp.api.impl;

import cn.binarywang.wx.miniapp.api.*;
import cn.binarywang.wx.miniapp.config.WxMaConfig;
import cn.binarywang.wx.miniapp.constant.WxMaConstants;
import com.google.gson.JsonParser;
import me.chanjar.weixin.common.bean.WxAccessToken;
import me.chanjar.weixin.common.bean.result.WxError;
@@ -147,6 +148,7 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl
/**
* 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求
*/
@Override
public <T, E> T execute(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException {
int retryTimes = 0;
do {
@@ -179,7 +181,7 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl
throw new RuntimeException("微信服务端异常,超出重试次数");
}

public synchronized <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException {
public <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException {
if (uri.contains("access_token=")) {
throw new IllegalArgumentException("uri参数中不允许有access_token: " + uri);
}
@@ -195,11 +197,10 @@ public class WxMaServiceImpl implements WxMaService, RequestHttp<CloseableHttpCl
WxError error = e.getError();
/*
* 发生以下情况时尝试刷新access_token
* 40001 获取access_token时AppSecret错误,或者access_token无效
* 42001 access_token超时
* 40014 不合法的access_token,请开发者认真比对access_token的有效性(如是否过期)
*/
if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001 || error.getErrorCode() == 40014) {
if (error.getErrorCode() == WxMaConstants.ErrorCode.ERR_40001
|| error.getErrorCode() == WxMaConstants.ErrorCode.ERR_42001
|| error.getErrorCode() == WxMaConstants.ErrorCode.ERR_40014) {
// 强制设置wxMpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token
this.getWxMaConfig().expireAccessToken();
if (this.getWxMaConfig().autoRefreshToken()) {


+ 2
- 2
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/api/impl/WxMaUserServiceImpl.java Visa fil

@@ -19,14 +19,14 @@ import java.util.Map;
public class WxMaUserServiceImpl implements WxMaUserService {
private WxMaService service;

WxMaUserServiceImpl(WxMaService service) {
public WxMaUserServiceImpl(WxMaService service) {
this.service = service;
}

@Override
public WxMaJscode2SessionResult getSessionInfo(String jsCode) throws WxErrorException {
final WxMaConfig config = service.getWxMaConfig();
Map<String, String> params = new HashMap<>();
Map<String, String> params = new HashMap<>(8);
params.put("appid", config.getAppid());
params.put("secret", config.getSecret());
params.put("js_code", jsCode);


weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaQrcodeWrapper.java → weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/AbstractWxMaQrcodeWrapper.java Visa fil

@@ -3,10 +3,11 @@ package cn.binarywang.wx.miniapp.bean;
import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;

/**
* 微信二维码(小程序码)包装器
* Created by Element on 2017/7/27.
* 微信二维码(小程序码)包装器.
*
* @author Element
*/
public abstract class WxMaQrcodeWrapper {
public abstract class AbstractWxMaQrcodeWrapper {

@Override
public String toString() {

+ 18
- 0
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaCodeLineColor.java Visa fil

@@ -0,0 +1,18 @@
package cn.binarywang.wx.miniapp.bean;

import lombok.AllArgsConstructor;
import lombok.Data;

/**
* <pre>
* lineColor 包装类
* 用于描述二维码(小程序码)颜色(RGB参数值),
* 详情请查看文档 https://mp.weixin.qq.com/debug/wxadoc/dev/api/qrcode.html
* </pre>
* @author Element
*/
@Data
@AllArgsConstructor
public class WxMaCodeLineColor {
private String r = "0", g = "0", b = "0";
}

+ 9
- 33
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaJscode2SessionResult.java Visa fil

@@ -2,13 +2,21 @@ package cn.binarywang.wx.miniapp.bean;

import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.io.Serializable;

/**
* {"session_key":"nzoqhc3OnwHzeTxJs+inbQ==","expires_in":2592000,"openid":"oVBkZ0aYgDMDIywRdgPW8-joxXc4"}
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
public class WxMaJscode2SessionResult {
@Data
@EqualsAndHashCode(callSuper = false)
public class WxMaJscode2SessionResult implements Serializable {
private static final long serialVersionUID = -1060216618475607933L;

@SerializedName("session_key")
private String sessionKey;

@@ -25,36 +33,4 @@ public class WxMaJscode2SessionResult {
return WxMaGsonBuilder.create().fromJson(json, WxMaJscode2SessionResult.class);
}

public String getSessionKey() {
return sessionKey;
}

public void setSessionKey(String sessionKey) {
this.sessionKey = sessionKey;
}

public Integer getExpiresin() {
return expiresin;
}

public void setExpiresin(Integer expiresin) {
this.expiresin = expiresin;
}

public String getOpenid() {
return openid;
}

public void setOpenid(String openid) {
this.openid = openid;
}

public String getUnionid() {
return unionid;
}

public void setUnionid(String unionid) {
this.unionid = unionid;
}

}

+ 4
- 58
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaKefuMessage.java Visa fil

@@ -3,6 +3,7 @@ package cn.binarywang.wx.miniapp.bean;
import cn.binarywang.wx.miniapp.builder.ImageBuilder;
import cn.binarywang.wx.miniapp.builder.TextBuilder;
import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
import lombok.Data;

import java.io.Serializable;

@@ -11,6 +12,7 @@ import java.io.Serializable;
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
@Data
public class WxMaKefuMessage implements Serializable {
private static final long serialVersionUID = -9196732086954365246L;

@@ -25,73 +27,17 @@ public class WxMaKefuMessage implements Serializable {
/**
* 获得文本消息builder
*/
public static TextBuilder TEXT() {
public static TextBuilder newTextBuilder() {
return new TextBuilder();
}

/**
* 获得图片消息builder
*/
public static ImageBuilder IMAGE() {
public static ImageBuilder newImageBuilder() {
return new ImageBuilder();
}

public String getToUser() {
return this.toUser;
}

public void setToUser(String toUser) {
this.toUser = toUser;
}

public String getMsgType() {
return this.msgType;
}

public void setMsgType(String msgType) {
this.msgType = msgType;
}

public String getContent() {
return this.content;
}

public void setContent(String content) {
this.content = content;
}

public String getMediaId() {
return this.mediaId;
}

public void setMediaId(String mediaId) {
this.mediaId = mediaId;
}

public String getThumbMediaId() {
return this.thumbMediaId;
}

public void setThumbMediaId(String thumbMediaId) {
this.thumbMediaId = thumbMediaId;
}

public String getTitle() {
return this.title;
}

public void setTitle(String title) {
this.title = title;
}

public String getDescription() {
return this.description;
}

public void setDescription(String description) {
this.description = description;
}

public String toJson() {
return WxMaGsonBuilder.create().toJson(this);
}


+ 2
- 87
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaMessage.java Visa fil

@@ -7,6 +7,7 @@ import cn.binarywang.wx.miniapp.util.xml.XStreamTransformer;
import com.google.gson.annotations.SerializedName;
import com.thoughtworks.xstream.annotations.XStreamAlias;
import com.thoughtworks.xstream.annotations.XStreamConverter;
import lombok.Data;
import me.chanjar.weixin.common.util.ToStringUtils;
import me.chanjar.weixin.common.util.xml.XStreamCDataConverter;
import org.apache.commons.io.IOUtils;
@@ -20,6 +21,7 @@ import java.nio.charset.StandardCharsets;
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
@XStreamAlias("xml")
@Data
public class WxMaMessage implements Serializable {
private static final long serialVersionUID = -3586245291677274914L;

@@ -146,91 +148,4 @@ public class WxMaMessage implements Serializable {
return WxMaGsonBuilder.create().toJson(this);
}

public String getToUser() {
return toUser;
}

public void setToUser(String toUser) {
this.toUser = toUser;
}

public String getFromUser() {
return fromUser;
}

public void setFromUser(String fromUser) {
this.fromUser = fromUser;
}

public Integer getCreateTime() {
return createTime;
}

public void setCreateTime(Integer createTime) {
this.createTime = createTime;
}

public String getMsgType() {
return msgType;
}

public void setMsgType(String msgType) {
this.msgType = msgType;
}

public String getContent() {
return content;
}

public void setContent(String content) {
this.content = content;
}

public Long getMsgId() {
return msgId;
}

public void setMsgId(Long msgId) {
this.msgId = msgId;
}

public String getPicUrl() {
return picUrl;
}

public void setPicUrl(String picUrl) {
this.picUrl = picUrl;
}

public String getMediaId() {
return mediaId;
}

public void setMediaId(String mediaId) {
this.mediaId = mediaId;
}

public String getEvent() {
return event;
}

public void setEvent(String event) {
this.event = event;
}

public String getSessionFrom() {
return sessionFrom;
}

public void setSessionFrom(String sessionFrom) {
this.sessionFrom = sessionFrom;
}

public String getEncrypt() {
return encrypt;
}

public void setEncrypt(String encrypt) {
this.encrypt = encrypt;
}
}

+ 5
- 17
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaQrcode.java Visa fil

@@ -1,13 +1,17 @@
package cn.binarywang.wx.miniapp.bean;

import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.io.Serializable;

/**
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
public class WxMaQrcode extends WxMaQrcodeWrapper implements Serializable {
@Data
@EqualsAndHashCode(callSuper = false)
public class WxMaQrcode extends AbstractWxMaQrcodeWrapper implements Serializable {
private static final long serialVersionUID = 5777119669111011584L;
private String path;
private int width = 430;
@@ -21,22 +25,6 @@ public class WxMaQrcode extends WxMaQrcodeWrapper implements Serializable {
return WxMaGsonBuilder.create().fromJson(json, WxMaQrcode.class);
}

public String getPath() {
return path;
}

public void setPath(String path) {
this.path = path;
}

public int getWidth() {
return width;
}

public void setWidth(int width) {
this.width = width;
}

@Override
public String toString() {
return WxMaGsonBuilder.create().toJson(this);


+ 7
- 146
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaTemplateMessage.java Visa fil

@@ -1,6 +1,8 @@
package cn.binarywang.wx.miniapp.bean;

import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
import lombok.Builder;
import lombok.Data;

import java.io.Serializable;
import java.util.ArrayList;
@@ -11,6 +13,8 @@ import java.util.List;
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
@Data
@Builder
public class WxMaTemplateMessage implements Serializable {
private static final long serialVersionUID = 5063374783759519418L;

@@ -57,7 +61,8 @@ public class WxMaTemplateMessage implements Serializable {
* 描述: 模板内容,不填则下发空模板
* </pre>
*/
private List<Data> data = new ArrayList<>();
@Builder.Default
private final List<Data> data = new ArrayList<>();

/**
* <pre>
@@ -77,80 +82,11 @@ public class WxMaTemplateMessage implements Serializable {
*/
private String emphasisKeyword;

private WxMaTemplateMessage(Builder builder) {
setToUser(builder.toUser);
setTemplateId(builder.templateId);
setPage(builder.page);
setFormId(builder.formId);
setData(builder.data);
setColor(builder.color);
setEmphasisKeyword(builder.emphasisKeyword);
}

public static Builder newBuilder() {
return new Builder();
}

public String toJson() {
return WxMaGsonBuilder.create().toJson(this);
}

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 getPage() {
return page;
}

public void setPage(String page) {
this.page = page;
}

public String getFormId() {
return formId;
}

public void setFormId(String formId) {
this.formId = formId;
}

public List<Data> getData() {
return data;
}

public void setData(List<Data> data) {
this.data = data;
}

public String getColor() {
return color;
}

public void setColor(String color) {
this.color = color;
}

public String getEmphasisKeyword() {
return emphasisKeyword;
}

public void setEmphasisKeyword(String emphasisKeyword) {
this.emphasisKeyword = emphasisKeyword;
}

@lombok.Data
public static class Data {
private String name;
private String value;
@@ -167,81 +103,6 @@ public class WxMaTemplateMessage implements Serializable {
this.color = color;
}

public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}

public String getValue() {
return this.value;
}

public void setValue(String value) {
this.value = value;
}

public String getColor() {
return this.color;
}

public void setColor(String color) {
this.color = color;
}

}

public static final class Builder {
private String toUser;
private String templateId;
private String page;
private String formId;
private List<Data> data;
private String color;
private String emphasisKeyword;

private Builder() {
}

public Builder toUser(String toUser) {
this.toUser = toUser;
return this;
}

public Builder templateId(String templateId) {
this.templateId = templateId;
return this;
}

public Builder page(String page) {
this.page = page;
return this;
}

public Builder formId(String formId) {
this.formId = formId;
return this;
}

public Builder data(List<Data> data) {
this.data = data;
return this;
}

public Builder color(String color) {
this.color = color;
return this;
}

public Builder emphasisKeyword(String emphasisKeyword) {
this.emphasisKeyword = emphasisKeyword;
return this;
}

public WxMaTemplateMessage build() {
return new WxMaTemplateMessage(this);
}
}
}

+ 8
- 104
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaUserInfo.java Visa fil

@@ -1,13 +1,17 @@
package cn.binarywang.wx.miniapp.bean;

import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import lombok.Data;

import java.io.Serializable;

/**
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
public class WxMaUserInfo {
@Data
public class WxMaUserInfo implements Serializable {
private static final long serialVersionUID = 6719822331555402137L;

private String openId;
private String nickName;
private String gender;
@@ -23,109 +27,9 @@ public class WxMaUserInfo {
return WxMaGsonBuilder.create().fromJson(json, WxMaUserInfo.class);
}

@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, ToStringStyle.MULTI_LINE_STYLE);
}

public String getOpenId() {
return openId;
}

public void setOpenId(String openId) {
this.openId = openId;
}

public String getNickName() {
return nickName;
}

public void setNickName(String nickName) {
this.nickName = nickName;
}

public String getGender() {
return gender;
}

public void setGender(String gender) {
this.gender = gender;
}

public String getLanguage() {
return language;
}

public void setLanguage(String language) {
this.language = language;
}

public String getCity() {
return city;
}

public void setCity(String city) {
this.city = city;
}

public String getProvince() {
return province;
}

public void setProvince(String province) {
this.province = province;
}

public String getCountry() {
return country;
}

public void setCountry(String country) {
this.country = country;
}

public String getAvatarUrl() {
return avatarUrl;
}

public void setAvatarUrl(String avatarUrl) {
this.avatarUrl = avatarUrl;
}

public String getUnionId() {
return unionId;
}

public void setUnionId(String unionId) {
this.unionId = unionId;
}

public Watermark getWatermark() {
return watermark;
}

public void setWatermark(Watermark watermark) {
this.watermark = watermark;
}

@Data
public static class Watermark {
private String timestamp;
private String appid;

public String getTimestamp() {
return timestamp;
}

public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}

public String getAppid() {
return appid;
}

public void setAppid(String appid) {
this.appid = appid;
}
}
}

+ 10
- 41
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaWxcode.java Visa fil

@@ -1,17 +1,22 @@
package cn.binarywang.wx.miniapp.bean;

import cn.binarywang.wx.miniapp.api.WxMaQrcodeService;
import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.io.Serializable;

/**
* Created by Element on 2017/7/27.
*
* @author Element
* @date 2017/7/27
*/
public class WxMaWxcode extends WxMaQrcodeWrapper implements Serializable {

@Data
@EqualsAndHashCode(callSuper = false)
public class WxMaWxcode extends AbstractWxMaQrcodeWrapper implements Serializable {
private static final long serialVersionUID = 1287399621649210322L;

private String path;
private int width = 430;

@@ -19,46 +24,10 @@ public class WxMaWxcode extends WxMaQrcodeWrapper implements Serializable {
private boolean autoColor = true;

@SerializedName("line_color")
private WxMaQrcodeService.LineColor lineColor = new WxMaQrcodeService.LineColor("0", "0", "0");
private WxMaCodeLineColor lineColor = new WxMaCodeLineColor("0", "0", "0");

public static WxMaWxcode fromJson(String json) {
return WxMaGsonBuilder.create().fromJson(json, WxMaWxcode.class);
}

public static long getSerialVersionUID() {
return serialVersionUID;
}

public String getPath() {
return path;
}

public void setPath(String path) {
this.path = path;
}

public int getWidth() {
return width;
}

public void setWidth(int width) {
this.width = width;
}

public boolean isAutoColor() {
return autoColor;
}

public void setAutoColor(boolean autoColor) {
this.autoColor = autoColor;
}

public WxMaQrcodeService.LineColor getLineColor() {
return lineColor;
}

public void setLineColor(WxMaQrcodeService.LineColor lineColor) {
this.lineColor = lineColor;
}

}

+ 9
- 43
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/bean/WxMaWxcodeLimit.java Visa fil

@@ -1,15 +1,20 @@
package cn.binarywang.wx.miniapp.bean;

import cn.binarywang.wx.miniapp.api.WxMaQrcodeService;
import cn.binarywang.wx.miniapp.util.json.WxMaGsonBuilder;
import com.google.gson.annotations.SerializedName;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.io.Serializable;

/**
* Created by Element on 2017/7/27.
*
* @author Element
* @date 2017/7/27
*/
public class WxMaWxcodeLimit extends WxMaQrcodeWrapper implements Serializable {
@Data
@EqualsAndHashCode(callSuper = false)
public class WxMaWxcodeLimit extends AbstractWxMaQrcodeWrapper implements Serializable {
private static final long serialVersionUID = 4782193774524960401L;
private String scene;
private String page;
@@ -20,49 +25,10 @@ public class WxMaWxcodeLimit extends WxMaQrcodeWrapper implements Serializable {
private boolean autoColor = true;

@SerializedName("line_color")
private WxMaQrcodeService.LineColor lineColor = new WxMaQrcodeService.LineColor("0", "0", "0");
private WxMaCodeLineColor lineColor = new WxMaCodeLineColor("0", "0", "0");

public static WxMaWxcodeLimit fromJson(String json) {
return WxMaGsonBuilder.create().fromJson(json, WxMaWxcodeLimit.class);
}

public String getPage() {
return page;
}

public void setPage(String page) {
this.page = page;
}

public String getScene() {
return scene;
}

public void setScene(String scene) {
this.scene = scene;
}

public int getWidth() {
return width;
}

public void setWidth(int width) {
this.width = width;
}

public boolean isAutoColor() {
return autoColor;
}

public void setAutoColor(boolean autoColor) {
this.autoColor = autoColor;
}

public WxMaQrcodeService.LineColor getLineColor() {
return lineColor;
}

public void setLineColor(WxMaQrcodeService.LineColor lineColor) {
this.lineColor = lineColor;
}
}

+ 3
- 0
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/builder/BaseBuilder.java Visa fil

@@ -15,6 +15,9 @@ public class BaseBuilder<T> {
return (T) this;
}

/**
* 构造器方法.
*/
public WxMaKefuMessage build() {
WxMaKefuMessage m = new WxMaKefuMessage();
m.setMsgType(this.msgType);


+ 2
- 2
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/builder/ImageBuilder.java Visa fil

@@ -13,8 +13,8 @@ public final class ImageBuilder extends BaseBuilder<ImageBuilder> {
this.msgType = WxMaConstants.KefuMsgType.IMAGE;
}

public ImageBuilder mediaId(String media_id) {
this.mediaId = media_id;
public ImageBuilder mediaId(String mediaId) {
this.mediaId = mediaId;
return this;
}



+ 1
- 0
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/config/WxMaInMemoryConfig.java Visa fil

@@ -175,6 +175,7 @@ public class WxMaInMemoryConfig implements WxMaConfig {
return true;
}

@Override
public String getAppid() {
return appid;
}


+ 34
- 3
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/constant/WxMaConstants.java Visa fil

@@ -8,11 +8,19 @@ package cn.binarywang.wx.miniapp.constant;
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
public class WxMaConstants {
/**
* 微信接口返回的参数errcode
*/
public static final String ERRCODE = "errcode";

/**
* 素材类型
*/
public static class MediaType {
public static final String IMAGE = "image";//图片
/**
* 图片
*/
public static final String IMAGE = "image";
}

/**
@@ -27,7 +35,30 @@ public class WxMaConstants {
* 客服消息的消息类型
*/
public static class KefuMsgType {
public static final String TEXT = "text";//文本消息
public static final String IMAGE = "image";//图片消息
/**
* 文本消息
*/
public static final String TEXT = "text";
/**
* 图片消息
*/
public static final String IMAGE = "image";
}

public static final class ErrorCode {
/**
* 40001 获取access_token时AppSecret错误,或者access_token无效
*/
public static final int ERR_40001 = 40001;

/**
* 42001 access_token超时
*/
public static final int ERR_42001 = 42001;

/**
* 40014 不合法的access_token,请开发者认真比对access_token的有效性(如是否过期)
*/
public static final int ERR_40014 = 40014;
}
}

+ 6
- 6
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/message/WxMaMessageRouter.java Visa fil

@@ -2,6 +2,7 @@ package cn.binarywang.wx.miniapp.message;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaMessage;
import com.google.common.util.concurrent.ThreadFactoryBuilder;
import me.chanjar.weixin.common.api.WxErrorExceptionHandler;
import me.chanjar.weixin.common.api.WxMessageDuplicateChecker;
import me.chanjar.weixin.common.api.WxMessageInMemoryDuplicateChecker;
@@ -17,10 +18,7 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.*;

/**
* @author <a href="https://github.com/binarywang">Binary Wang</a>
@@ -42,7 +40,9 @@ public class WxMaMessageRouter {

public WxMaMessageRouter(WxMaService wxMaService) {
this.wxMaService = wxMaService;
this.executorService = Executors.newFixedThreadPool(DEFAULT_THREAD_POOL_SIZE);
ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat("WxMaMessageRouter-pool-%d").build();
this.executorService = new ThreadPoolExecutor(DEFAULT_THREAD_POOL_SIZE, DEFAULT_THREAD_POOL_SIZE,
0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>(), namedThreadFactory);
this.messageDuplicateChecker = new WxMessageInMemoryDuplicateChecker();
this.sessionManager = new StandardSessionManager();
this.exceptionHandler = new LogExceptionHandler();
@@ -159,7 +159,7 @@ public class WxMaMessageRouter {
}

public void route(final WxMaMessage wxMessage) {
this.route(wxMessage, new HashMap<String, Object>());
this.route(wxMessage, new HashMap<String, Object>(2));
}

/**


+ 1
- 1
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/message/WxMaMessageRouterRule.java Visa fil

@@ -196,7 +196,7 @@ public class WxMaMessageRouterRule {
WxSessionManager sessionManager,
WxErrorExceptionHandler exceptionHandler) {
if (context == null) {
context = new HashMap<>();
context = new HashMap<>(16);
}

try {


+ 8
- 9
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/http/QrCodeRequestExecutor.java Visa fil

@@ -1,6 +1,6 @@
package cn.binarywang.wx.miniapp.util.http;

import cn.binarywang.wx.miniapp.bean.WxMaQrcodeWrapper;
import cn.binarywang.wx.miniapp.bean.AbstractWxMaQrcodeWrapper;
import me.chanjar.weixin.common.bean.result.WxError;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.fs.FileUtils;
@@ -25,7 +25,7 @@ import java.util.UUID;
/**
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
public class QrCodeRequestExecutor implements RequestExecutor<File, WxMaQrcodeWrapper> {
public class QrCodeRequestExecutor implements RequestExecutor<File, AbstractWxMaQrcodeWrapper> {
protected RequestHttp<CloseableHttpClient, HttpHost> requestHttp;

public QrCodeRequestExecutor(RequestHttp requestHttp) {
@@ -33,14 +33,12 @@ public class QrCodeRequestExecutor implements RequestExecutor<File, WxMaQrcodeWr
}

@Override
public File execute(String uri, WxMaQrcodeWrapper ticket) throws WxErrorException, IOException {
public File execute(String uri, AbstractWxMaQrcodeWrapper ticket) throws WxErrorException, IOException {
HttpPost httpPost = new HttpPost(uri);
if (requestHttp.getRequestHttpProxy() != null) {
httpPost
.setConfig(RequestConfig.custom()
.setProxy(requestHttp.getRequestHttpProxy())
.build()
);
httpPost.setConfig(
RequestConfig.custom().setProxy(requestHttp.getRequestHttpProxy()).build()
);
}
httpPost.setEntity(new StringEntity(ticket.toString()));

@@ -48,7 +46,8 @@ public class QrCodeRequestExecutor implements RequestExecutor<File, WxMaQrcodeWr
InputStream inputStream = InputStreamResponseHandler.INSTANCE.handleResponse(response);) {
Header[] contentTypeHeader = response.getHeaders("Content-Type");
if (contentTypeHeader != null && contentTypeHeader.length > 0
&& ContentType.APPLICATION_JSON.getMimeType().equals(contentTypeHeader[0].getValue())) {
&& ContentType.APPLICATION_JSON.getMimeType()
.equals(ContentType.parse(contentTypeHeader[0].getValue()).getMimeType())) {
String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response);
throw new WxErrorException(WxError.fromJson(responseContent));
}


+ 6
- 4
weixin-java-miniapp/src/main/java/cn/binarywang/wx/miniapp/util/xml/XStreamTransformer.java Visa fil

@@ -18,7 +18,7 @@ public class XStreamTransformer {
}

/**
* xml -> pojo
* xml -> pojo.
*/
@SuppressWarnings("unchecked")
public static <T> T fromXml(Class<T> clazz, String xml) {
@@ -33,14 +33,14 @@ public class XStreamTransformer {
}

/**
* pojo -> xml
* pojo -> xml.
*/
public static <T> String toXml(Class<T> clazz, T object) {
return CLASS_2_XSTREAM_INSTANCE.get(clazz).toXML(object);
}

/**
* 注册扩展消息的解析器
* 注册扩展消息的解析器.
*
* @param clz 类型
* @param xStream xml解析器
@@ -50,12 +50,14 @@ public class XStreamTransformer {
}

/**
* 会自动注册该类及其子类
* 会自动注册该类及其子类.
*
* @param clz 要注册的类
*/
private static void registerClass(Class<?> clz) {
XStream xstream = XStreamInitializer.getInstance();
xstream.setClassLoader(Thread.currentThread().getContextClassLoader());

xstream.processAnnotations(clz);
xstream.processAnnotations(getInnerClasses(clz));
if (clz.equals(WxMaMessage.class)) {


+ 3
- 3
weixin-java-miniapp/src/test/java/cn/binarywang/wx/miniapp/api/impl/WxMaMsgServiceImplTest.java Visa fil

@@ -31,7 +31,7 @@ public class WxMaMsgServiceImplTest {
TestConfig configStorage = (TestConfig) this.wxService
.getWxMaConfig();
WxMaKefuMessage message = new WxMaKefuMessage();
message.setMsgType(WxConsts.CUSTOM_MSG_MPNEWS);
message.setMsgType(WxConsts.KefuMsgType.MPNEWS);
message.setToUser(configStorage.getOpenid());

this.wxService.getMsgService().sendKefuMsg(message);
@@ -41,7 +41,7 @@ public class WxMaMsgServiceImplTest {
TestConfig config = (TestConfig) this.wxService
.getWxMaConfig();
WxMaKefuMessage message = new WxMaKefuMessage();
message.setMsgType(WxConsts.CUSTOM_MSG_TEXT);
message.setMsgType(WxConsts.KefuMsgType.TEXT);
message.setToUser(config.getOpenid());
message.setContent(
"欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>");
@@ -54,7 +54,7 @@ public class WxMaMsgServiceImplTest {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
TestConfig config = (TestConfig) this.wxService.getWxMaConfig();

WxMaTemplateMessage templateMessage = WxMaTemplateMessage.newBuilder()
WxMaTemplateMessage templateMessage = WxMaTemplateMessage.builder()
.toUser(config.getOpenid())
.formId("FORMID")
.page("index")


Vissa filer visades inte eftersom för många filer har ändrats

Laddar…
Avbryt
Spara