Browse Source

Merge branch 'develop'

# Conflicts:
#	README.md
master
BinaryWang 8 years ago
parent
commit
9a26c755e6
100 changed files with 1047 additions and 943 deletions
  1. +14
    -0
      .editorconfig
  2. +6
    -6
      README.md
  3. +5
    -3
      build.gradle
  4. +22
    -7
      pom.xml
  5. +1
    -1
      weixin-java-common/pom.xml
  6. +19
    -0
      weixin-java-common/src/main/java/me/chanjar/weixin/common/annotation/Required.java
  7. +4
    -1
      weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java
  8. +7
    -7
      weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxMessageInMemoryDuplicateChecker.java
  9. +2
    -2
      weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxAccessToken.java
  10. +9
    -9
      weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxCardApiSignature.java
  11. +5
    -5
      weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxJsapiSignature.java
  12. +4
    -4
      weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenu.java
  13. +7
    -7
      weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuButton.java
  14. +7
    -7
      weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuRule.java
  15. +6
    -6
      weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxError.java
  16. +6
    -6
      weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxMediaUploadResult.java
  17. +1
    -1
      weixin-java-common/src/main/java/me/chanjar/weixin/common/exception/WxErrorException.java
  18. +48
    -48
      weixin-java-common/src/main/java/me/chanjar/weixin/common/session/StandardSession.java
  19. +6
    -6
      weixin-java-common/src/main/java/me/chanjar/weixin/common/session/StandardSessionFacade.java
  20. +25
    -25
      weixin-java-common/src/main/java/me/chanjar/weixin/common/session/StandardSessionManager.java
  21. +2
    -2
      weixin-java-common/src/main/java/me/chanjar/weixin/common/session/TooManyActiveSessionsException.java
  22. +1
    -1
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/LogExceptionHandler.java
  23. +6
    -6
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/ByteGroup.java
  24. +1
    -1
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/PKCS7Encoder.java
  25. +4
    -5
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/SHA1.java
  26. +27
    -62
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/WxCryptUtil.java
  27. +12
    -24
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/fs/FileUtils.java
  28. +23
    -21
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/DefaultApacheHttpClientBuilder.java
  29. +1
    -0
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/InputStreamResponseHandler.java
  30. +4
    -5
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/JoddGetRequestExecutor.java
  31. +4
    -5
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/JoddPostRequestExecutor.java
  32. +18
    -16
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/MediaDownloadRequestExecutor.java
  33. +0
    -2
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/RequestExecutor.java
  34. +15
    -3
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/SimplePostRequestExecutor.java
  35. +1
    -1
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/URIUtil.java
  36. +1
    -0
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/Utf8ResponseHandler.java
  37. +21
    -0
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/GsonHelper.java
  38. +1
    -0
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxAccessTokenAdapter.java
  39. +1
    -0
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxErrorAdapter.java
  40. +1
    -0
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxMediaUploadResultAdapter.java
  41. +2
    -0
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxMenuGsonAdapter.java
  42. +8
    -8
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/res/StringManager.java
  43. +9
    -4
      weixin-java-common/src/main/java/me/chanjar/weixin/common/util/xml/XStreamInitializer.java
  44. +2
    -2
      weixin-java-common/src/test/java/me/chanjar/weixin/common/session/SessionTest.java
  45. +12
    -12
      weixin-java-common/src/test/java/me/chanjar/weixin/common/util/crypto/WxCryptUtilTest.java
  46. +1
    -1
      weixin-java-cp/pom.xml
  47. +4
    -4
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpConfigStorage.java
  48. +50
    -43
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpInMemoryConfigStorage.java
  49. +20
    -20
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpJedisConfigStorage.java
  50. +15
    -14
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageRouter.java
  51. +5
    -5
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageRouterRule.java
  52. +134
    -97
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java
  53. +12
    -8
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpDepart.java
  54. +23
    -19
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java
  55. +7
    -2
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTag.java
  56. +20
    -16
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUser.java
  57. +83
    -78
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java
  58. +1
    -1
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessage.java
  59. +4
    -4
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutMessage.java
  60. +11
    -11
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessage.java
  61. +1
    -1
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessage.java
  62. +9
    -9
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessage.java
  63. +1
    -1
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessage.java
  64. +1
    -0
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/FileBuilder.java
  65. +1
    -0
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/ImageBuilder.java
  66. +2
    -1
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/NewsBuilder.java
  67. +1
    -0
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TextBuilder.java
  68. +4
    -3
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VideoBuilder.java
  69. +1
    -0
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VoiceBuilder.java
  70. +1
    -0
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/ImageBuilder.java
  71. +3
    -2
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/NewsBuilder.java
  72. +1
    -0
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/TextBuilder.java
  73. +4
    -3
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/VideoBuilder.java
  74. +2
    -1
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/VoiceBuilder.java
  75. +2
    -0
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpDepartGsonAdapter.java
  76. +1
    -0
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpMessageGsonAdapter.java
  77. +2
    -0
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpTagGsonAdapter.java
  78. +1
    -0
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpUserGsonAdapter.java
  79. +1
    -1
      weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XStreamTransformer.java
  80. +22
    -15
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/ApiTestModule.java
  81. +7
    -5
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBaseAPITest.java
  82. +10
    -7
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBusyRetryTest.java
  83. +19
    -16
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpDepartAPITest.java
  84. +26
    -20
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMediaAPITest.java
  85. +8
    -6
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageAPITest.java
  86. +1
    -1
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageRouterTest.java
  87. +12
    -12
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpTagAPITest.java
  88. +5
    -5
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpUserAPITest.java
  89. +3
    -3
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxMenuAPITest.java
  90. +2
    -2
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoInMemoryConfigStorage.java
  91. +56
    -57
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoServer.java
  92. +13
    -13
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpEndpointServlet.java
  93. +8
    -7
      weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpOAuth2Servlet.java
  94. +4
    -4
      weixin-java-mp/pom.xml
  95. +1
    -2
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCardService.java
  96. +0
    -69
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpGroupService.java
  97. +18
    -4
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpKefuService.java
  98. +2
    -0
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMaterialService.java
  99. +19
    -18
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java
  100. +1
    -1
      weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouterRule.java

+ 14
- 0
.editorconfig View File

@@ -0,0 +1,14 @@
# EditorConfig: http://editorconfig.org/

root = true

[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

[*.md]
trim_trailing_whitespace = false

+ 6
- 6
README.md View File

@@ -5,7 +5,7 @@
### 注意: ### 注意:
1. ***本项目Fork自chanjarster/weixin-java-tools,但由于原项目已停止维护,故单独维护和发布,且发布到maven上的groupId也会不同,详细信息见下文。*** 1. ***本项目Fork自chanjarster/weixin-java-tools,但由于原项目已停止维护,故单独维护和发布,且发布到maven上的groupId也会不同,详细信息见下文。***
1. ***自2.0.0版本以来,主要是公众号的接口调整比较大,主要是为了解决主接口类过于庞大不方便管理的问题,将接口实现代码按模块进行拆分。*** 1. ***自2.0.0版本以来,主要是公众号的接口调整比较大,主要是为了解决主接口类过于庞大不方便管理的问题,将接口实现代码按模块进行拆分。***
1. 最新更新:2016-08-31 发布2.1.0正式版!
1. 最新更新:2016-09-30 发布2.2.0正式版!


=========== ===========


@@ -33,12 +33,12 @@ maven:
<dependency> <dependency>
<groupId>com.github.binarywang</groupId> <groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-mp</artifactId> <artifactId>weixin-java-mp</artifactId>
<version>2.1.0</version>
<version>2.2.0</version>
</dependency> </dependency>
``` ```
gradle: gradle:
```groovy ```groovy
compile 'com.github.binarywang:weixin-java-mp:2.1.0'
compile 'com.github.binarywang:weixin-java-mp:2.2.0'
``` ```


* 企业号: * 企业号:
@@ -48,12 +48,12 @@ maven:
<dependency> <dependency>
<groupId>com.github.binarywang</groupId> <groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-cp</artifactId> <artifactId>weixin-java-cp</artifactId>
<version>2.1.0</version>
<version>2.2.0</version>
</dependency> </dependency>
``` ```
gradle: gradle:
```groovy ```groovy
compile 'com.github.binarywang:weixin-java-cp:2.1.0'
compile 'com.github.binarywang:weixin-java-cp:2.2.0'
``` ```


#### 本项目主要存放在github上,地址为 : #### 本项目主要存放在github上,地址为 :
@@ -74,4 +74,4 @@ compile 'com.github.binarywang:weixin-java-cp:2.1.0'
* 本项目可以采用两种方式接受代码贡献: * 本项目可以采用两种方式接受代码贡献:


1. 第一种就是基于[Git Flow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow)开发流程,因此在发起Pull Request的时候请选择develop分支。 1. 第一种就是基于[Git Flow](https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow)开发流程,因此在发起Pull Request的时候请选择develop分支。
1. 另外一种贡献代码的方式就是加入SDK Developers开发组,如果对自己的代码足够自信,可以随时提交代码,注意要随时进行单元测试,保证提交代码没有明显问题,具体加入方式,请咨询管理员。
1. 另外一种贡献代码的方式就是加入SDK Developers开发组,前提是对自己的代码足够自信就可以申请加入,加入之后可以随时直接提交代码,但要注意对所做的修改或新增的代码进行单元测试,保证提交代码没有明显问题,具体加入方式,请咨询管理员。

+ 5
- 3
build.gradle View File

@@ -2,7 +2,7 @@ allprojects {
apply plugin: 'maven' apply plugin: 'maven'


group = 'com.github.binarywang' group = 'com.github.binarywang'
version = '2.1.0-SNAPSHOT'
version = '2.2.0'
} }


subprojects { subprojects {
@@ -13,8 +13,8 @@ subprojects {


repositories { repositories {
mavenLocal() mavenLocal()
maven { url "http://maven.aliyun.com/nexus/content/groups/public" }
maven { url "http://central.maven.org/maven2" }
//maven { url "http://maven.aliyun.com/nexus/content/groups/public" }
} }




@@ -24,6 +24,8 @@ subprojects {
compile group: 'org.apache.httpcomponents', name: 'httpmime', version:'4.5' compile group: 'org.apache.httpcomponents', name: 'httpmime', version:'4.5'
compile group: 'org.jodd', name: 'jodd-http', version:'3.6.7' compile group: 'org.jodd', name: 'jodd-http', version:'3.6.7'
compile group: 'com.google.code.gson', name: 'gson', version:'2.7' compile group: 'com.google.code.gson', name: 'gson', version:'2.7'
compile group: 'com.google.guava', name: 'guava', version:'19.0'
compile group: 'org.jooq', name: 'joor', version:'0.9.6'
compile group: 'commons-codec', name: 'commons-codec', version:'1.10' compile group: 'commons-codec', name: 'commons-codec', version:'1.10'
compile group: 'commons-io', name: 'commons-io', version:'2.5' compile group: 'commons-io', name: 'commons-io', version:'2.5'
compile group: 'org.apache.commons', name: 'commons-lang3', version:'3.4' compile group: 'org.apache.commons', name: 'commons-lang3', version:'3.4'


+ 22
- 7
pom.xml View File

@@ -5,7 +5,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.github.binarywang</groupId> <groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-parent</artifactId> <artifactId>weixin-java-parent</artifactId>
<version>2.1.0</version>
<version>2.2.0</version>
<packaging>pom</packaging> <packaging>pom</packaging>
<name>WeiXin Java Tools - Parent</name> <name>WeiXin Java Tools - Parent</name>
<description>微信公众号、企业号上级POM</description> <description>微信公众号、企业号上级POM</description>
@@ -49,9 +49,10 @@
<slf4j.version>1.7.10</slf4j.version> <slf4j.version>1.7.10</slf4j.version>
<logback.version>1.1.2</logback.version> <logback.version>1.1.2</logback.version>
<jodd-http.version>3.6.7</jodd-http.version> <jodd-http.version>3.6.7</jodd-http.version>
<jackson.version>2.8.0</jackson.version>
<jedis.version>2.9.0</jedis.version> <jedis.version>2.9.0</jedis.version>
<gson.version>2.7</gson.version> <gson.version>2.7</gson.version>
<guava.version>19.0</guava.version>
<joor.version>0.9.6</joor.version>
<commons-lang3.version>3.4</commons-lang3.version> <commons-lang3.version>3.4</commons-lang3.version>
<commons-io.version>2.5</commons-io.version> <commons-io.version>2.5</commons-io.version>
<commons-codec.version>1.10</commons-codec.version> <commons-codec.version>1.10</commons-codec.version>
@@ -106,15 +107,19 @@
<artifactId>commons-lang3</artifactId> <artifactId>commons-lang3</artifactId>
<version>${commons-lang3.version}</version> <version>${commons-lang3.version}</version>
</dependency> </dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
</dependency>
<dependency> <dependency>
<groupId>redis.clients</groupId> <groupId>redis.clients</groupId>
<artifactId>jedis</artifactId> <artifactId>jedis</artifactId>
<version>${jedis.version}</version> <version>${jedis.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</dependency>
<dependency>
<groupId>org.jooq</groupId>
<artifactId>joor</artifactId>
</dependency> </dependency>
</dependencies> </dependencies>


@@ -156,6 +161,16 @@
<version>${jetty.version}</version> <version>${jetty.version}</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>org.jooq</groupId>
<artifactId>joor</artifactId>
<version>${joor.version}</version>
</dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>




+ 1
- 1
weixin-java-common/pom.xml View File

@@ -6,7 +6,7 @@
<parent> <parent>
<groupId>com.github.binarywang</groupId> <groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-parent</artifactId> <artifactId>weixin-java-parent</artifactId>
<version>2.1.0</version>
<version>2.2.0</version>
</parent> </parent>


<artifactId>weixin-java-common</artifactId> <artifactId>weixin-java-common</artifactId>


+ 19
- 0
weixin-java-common/src/main/java/me/chanjar/weixin/common/annotation/Required.java View File

@@ -0,0 +1,19 @@
package me.chanjar.weixin.common.annotation;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* 标识某个字段是否是必填的
*
* Created by Binary Wang on 2016/9/25.
* @author binarywang (https://github.com/binarywang)
*
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Required {

}

+ 4
- 1
weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxConsts.java View File

@@ -30,6 +30,7 @@ public class WxConsts {
public static final String CUSTOM_MSG_MUSIC = "music"; public static final String CUSTOM_MSG_MUSIC = "music";
public static final String CUSTOM_MSG_NEWS = "news"; public static final String CUSTOM_MSG_NEWS = "news";
public static final String CUSTOM_MSG_FILE = "file"; public static final String CUSTOM_MSG_FILE = "file";
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_TRANSFER_CUSTOMER_SERVICE = "transfer_customer_service";
public static final String CUSTOM_MSG_SAFE_NO = "0"; public static final String CUSTOM_MSG_SAFE_NO = "0";
public static final String CUSTOM_MSG_SAFE_YES = "1"; public static final String CUSTOM_MSG_SAFE_YES = "1";
@@ -61,7 +62,7 @@ public class WxConsts {
/** /**
* 群发反馈消息代码所对应的文字描述 * 群发反馈消息代码所对应的文字描述
*/ */
public static final Map<String, String> MASS_ST_2_DESC = new HashMap<String, String>();
public static final Map<String, String> MASS_ST_2_DESC = new HashMap<>();
/////////////////////// ///////////////////////
// 微信端推送过来的事件类型 // 微信端推送过来的事件类型
/////////////////////// ///////////////////////
@@ -92,6 +93,8 @@ public class WxConsts {
public static final String EVT_KF_CREATE_SESSION = "kf_create_session"; // 客服接入会话 public static final String EVT_KF_CREATE_SESSION = "kf_create_session"; // 客服接入会话
public static final String EVT_KF_CLOSE_SESSION = "kf_close_session"; // 客服关闭会话 public static final String EVT_KF_CLOSE_SESSION = "kf_close_session"; // 客服关闭会话
public static final String EVT_KF_SWITCH_SESSION = "kf_switch_session"; // 客服转接会话 public static final String EVT_KF_SWITCH_SESSION = "kf_switch_session"; // 客服转接会话
public static final String EVT_POI_CHECK_NOTIFY = "poi_check_notify"; //门店审核事件推送

/////////////////////// ///////////////////////
// 上传多媒体文件的类型 // 上传多媒体文件的类型
/////////////////////// ///////////////////////


+ 7
- 7
weixin-java-common/src/main/java/me/chanjar/weixin/common/api/WxMessageInMemoryDuplicateChecker.java View File

@@ -25,7 +25,7 @@ public class WxMessageInMemoryDuplicateChecker implements WxMessageDuplicateChec
/** /**
* 消息id->消息时间戳的map * 消息id->消息时间戳的map
*/ */
private final ConcurrentHashMap<String, Long> msgId2Timestamp = new ConcurrentHashMap<String, Long>();
private final ConcurrentHashMap<String, Long> msgId2Timestamp = new ConcurrentHashMap<>();


/** /**
* 后台清理线程是否已经开启 * 后台清理线程是否已经开启
@@ -56,7 +56,7 @@ public class WxMessageInMemoryDuplicateChecker implements WxMessageDuplicateChec
} }


protected void checkBackgroundProcessStarted() { protected void checkBackgroundProcessStarted() {
if (backgroundProcessStarted.getAndSet(true)) {
if (this.backgroundProcessStarted.getAndSet(true)) {
return; return;
} }
Thread t = new Thread(new Runnable() { Thread t = new Thread(new Runnable() {
@@ -64,11 +64,11 @@ public class WxMessageInMemoryDuplicateChecker implements WxMessageDuplicateChec
public void run() { public void run() {
try { try {
while (true) { while (true) {
Thread.sleep(clearPeriod);
Thread.sleep(WxMessageInMemoryDuplicateChecker.this.clearPeriod);
Long now = System.currentTimeMillis(); Long now = System.currentTimeMillis();
for (Map.Entry<String, Long> entry : msgId2Timestamp.entrySet()) {
if (now - entry.getValue() > timeToLive) {
msgId2Timestamp.entrySet().remove(entry);
for (Map.Entry<String, Long> entry : WxMessageInMemoryDuplicateChecker.this.msgId2Timestamp.entrySet()) {
if (now - entry.getValue() > WxMessageInMemoryDuplicateChecker.this.timeToLive) {
WxMessageInMemoryDuplicateChecker.this.msgId2Timestamp.entrySet().remove(entry);
} }
} }
} }
@@ -87,7 +87,7 @@ public class WxMessageInMemoryDuplicateChecker implements WxMessageDuplicateChec
return false; return false;
} }
checkBackgroundProcessStarted(); checkBackgroundProcessStarted();
Long timestamp = msgId2Timestamp.putIfAbsent(messageId, System.currentTimeMillis());
Long timestamp = this.msgId2Timestamp.putIfAbsent(messageId, System.currentTimeMillis());
return timestamp != null; return timestamp != null;
} }




+ 2
- 2
weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxAccessToken.java View File

@@ -16,7 +16,7 @@ public class WxAccessToken implements Serializable {
} }


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


public void setAccessToken(String accessToken) { public void setAccessToken(String accessToken) {
@@ -24,7 +24,7 @@ public class WxAccessToken implements Serializable {
} }


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


public void setExpiresIn(int expiresIn) { public void setExpiresIn(int expiresIn) {


+ 9
- 9
weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxCardApiSignature.java View File

@@ -39,7 +39,7 @@ public class WxCardApiSignature implements Serializable {
} }


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


public void setAppId(String appId) { public void setAppId(String appId) {
@@ -47,7 +47,7 @@ public class WxCardApiSignature implements Serializable {
} }


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


public void setCardId(String cardId) { public void setCardId(String cardId) {
@@ -55,7 +55,7 @@ public class WxCardApiSignature implements Serializable {
} }


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


public void setCardType(String cardType) { public void setCardType(String cardType) {
@@ -63,7 +63,7 @@ public class WxCardApiSignature implements Serializable {
} }


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


public void setLocationId(String locationId) { public void setLocationId(String locationId) {
@@ -71,7 +71,7 @@ public class WxCardApiSignature implements Serializable {
} }


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


public void setCode(String code) { public void setCode(String code) {
@@ -79,7 +79,7 @@ public class WxCardApiSignature implements Serializable {
} }


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


public void setOpenId(String openId) { public void setOpenId(String openId) {
@@ -87,7 +87,7 @@ public class WxCardApiSignature implements Serializable {
} }


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


public void setTimestamp(Long timestamp) { public void setTimestamp(Long timestamp) {
@@ -95,7 +95,7 @@ public class WxCardApiSignature implements Serializable {
} }


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


public void setNonceStr(String nonceStr) { public void setNonceStr(String nonceStr) {
@@ -103,7 +103,7 @@ public class WxCardApiSignature implements Serializable {
} }


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


public void setSignature(String signature) { public void setSignature(String signature) {


+ 5
- 5
weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/WxJsapiSignature.java View File

@@ -19,7 +19,7 @@ public class WxJsapiSignature implements Serializable {
private String signature; private String signature;


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


public void setSignature(String signature) { public void setSignature(String signature) {
@@ -27,7 +27,7 @@ public class WxJsapiSignature implements Serializable {
} }


public String getNoncestr() { public String getNoncestr() {
return noncestr;
return this.noncestr;
} }


public void setNoncestr(String noncestr) { public void setNoncestr(String noncestr) {
@@ -35,7 +35,7 @@ public class WxJsapiSignature implements Serializable {
} }


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


public void setTimestamp(long timestamp) { public void setTimestamp(long timestamp) {
@@ -43,7 +43,7 @@ public class WxJsapiSignature implements Serializable {
} }


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


public void setUrl(String url) { public void setUrl(String url) {
@@ -51,7 +51,7 @@ public class WxJsapiSignature implements Serializable {
} }


public String getAppid() { public String getAppid() {
return appid;
return this.appid;
} }


public void setAppid(String appid) { public void setAppid(String appid) {


+ 4
- 4
weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenu.java View File

@@ -19,7 +19,7 @@ public class WxMenu implements Serializable {


private static final long serialVersionUID = -7083914585539687746L; private static final long serialVersionUID = -7083914585539687746L;


private List<WxMenuButton> buttons = new ArrayList<WxMenuButton>();
private List<WxMenuButton> buttons = new ArrayList<>();


private WxMenuRule matchRule; private WxMenuRule matchRule;


@@ -40,7 +40,7 @@ public class WxMenu implements Serializable {
} }


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


public void setButtons(List<WxMenuButton> buttons) { public void setButtons(List<WxMenuButton> buttons) {
@@ -48,7 +48,7 @@ public class WxMenu implements Serializable {
} }


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


public void setMatchRule(WxMenuRule matchRule) { public void setMatchRule(WxMenuRule matchRule) {
@@ -62,7 +62,7 @@ public class WxMenu implements Serializable {
@Override @Override
public String toString() { public String toString() {
return "WxMenu{" + return "WxMenu{" +
"buttons=" + buttons +
"buttons=" + this.buttons +
'}'; '}';
} }




+ 7
- 7
weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuButton.java View File

@@ -14,7 +14,7 @@ public class WxMenuButton {
private String url; private String url;
private String mediaId; private String mediaId;


private List<WxMenuButton> subButtons = new ArrayList<WxMenuButton>();
private List<WxMenuButton> subButtons = new ArrayList<>();


@Override @Override
public String toString() { public String toString() {
@@ -23,7 +23,7 @@ public class WxMenuButton {
} }
public String getType() { public String getType() {
return type;
return this.type;
} }


public void setType(String type) { public void setType(String type) {
@@ -31,7 +31,7 @@ public class WxMenuButton {
} }


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


public void setName(String name) { public void setName(String name) {
@@ -39,7 +39,7 @@ public class WxMenuButton {
} }


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


public void setKey(String key) { public void setKey(String key) {
@@ -47,7 +47,7 @@ public class WxMenuButton {
} }


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


public void setUrl(String url) { public void setUrl(String url) {
@@ -55,7 +55,7 @@ public class WxMenuButton {
} }


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


public void setSubButtons(List<WxMenuButton> subButtons) { public void setSubButtons(List<WxMenuButton> subButtons) {
@@ -63,7 +63,7 @@ public class WxMenuButton {
} }


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


public void setMediaId(String mediaId) { public void setMediaId(String mediaId) {


+ 7
- 7
weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/menu/WxMenuRule.java View File

@@ -13,7 +13,7 @@ public class WxMenuRule {
private String language; private String language;


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


public void setTagId(String tagId) { public void setTagId(String tagId) {
@@ -21,7 +21,7 @@ public class WxMenuRule {
} }


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


public void setSex(String sex) { public void setSex(String sex) {
@@ -29,7 +29,7 @@ public class WxMenuRule {
} }


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


public void setCountry(String country) { public void setCountry(String country) {
@@ -37,7 +37,7 @@ public class WxMenuRule {
} }


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


public void setProvince(String province) { public void setProvince(String province) {
@@ -45,7 +45,7 @@ public class WxMenuRule {
} }


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


public void setCity(String city) { public void setCity(String city) {
@@ -53,7 +53,7 @@ public class WxMenuRule {
} }


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


public void setClientPlatformType(String clientPlatformType) { public void setClientPlatformType(String clientPlatformType) {
@@ -61,7 +61,7 @@ public class WxMenuRule {
} }


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


public void setLanguage(String language) { public void setLanguage(String language) {


+ 6
- 6
weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxError.java View File

@@ -29,7 +29,7 @@ public class WxError implements Serializable {
} }


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


public void setErrorCode(int errorCode) { public void setErrorCode(int errorCode) {
@@ -37,7 +37,7 @@ public class WxError implements Serializable {
} }


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


public void setErrorMsg(String errorMsg) { public void setErrorMsg(String errorMsg) {
@@ -45,7 +45,7 @@ public class WxError implements Serializable {
} }


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


public void setJson(String json) { public void setJson(String json) {
@@ -54,10 +54,10 @@ public class WxError implements Serializable {


@Override @Override
public String toString() { public String toString() {
if (json != null) {
return json;
if (this.json != null) {
return this.json;
} }
return "错误: Code=" + errorCode + ", Msg=" + errorMsg;
return "错误: Code=" + this.errorCode + ", Msg=" + this.errorMsg;
} }


public static class Builder { public static class Builder {


+ 6
- 6
weixin-java-common/src/main/java/me/chanjar/weixin/common/bean/result/WxMediaUploadResult.java View File

@@ -17,7 +17,7 @@ public class WxMediaUploadResult implements Serializable {
} }


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


public void setType(String type) { public void setType(String type) {
@@ -25,7 +25,7 @@ public class WxMediaUploadResult implements Serializable {
} }


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


public void setMediaId(String mediaId) { public void setMediaId(String mediaId) {
@@ -33,7 +33,7 @@ public class WxMediaUploadResult implements Serializable {
} }


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


public void setCreatedAt(long createdAt) { public void setCreatedAt(long createdAt) {
@@ -41,7 +41,7 @@ public class WxMediaUploadResult implements Serializable {
} }


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


public void setThumbMediaId(String thumbMediaId) { public void setThumbMediaId(String thumbMediaId) {
@@ -50,8 +50,8 @@ public class WxMediaUploadResult implements Serializable {


@Override @Override
public String toString() { public String toString() {
return "WxUploadResult [type=" + type + ", media_id=" + mediaId + ", thumb_media_id=" + thumbMediaId
+ ", created_at=" + createdAt + "]";
return "WxUploadResult [type=" + this.type + ", media_id=" + this.mediaId + ", thumb_media_id=" + this.thumbMediaId
+ ", created_at=" + this.createdAt + "]";
} }


} }

+ 1
- 1
weixin-java-common/src/main/java/me/chanjar/weixin/common/exception/WxErrorException.java View File

@@ -14,7 +14,7 @@ public class WxErrorException extends Exception {
} }


public WxError getError() { public WxError getError() {
return error;
return this.error;
} }






+ 48
- 48
weixin-java-common/src/main/java/me/chanjar/weixin/common/session/StandardSession.java View File

@@ -18,7 +18,7 @@ public class StandardSession implements WxSession, InternalSession {
*/ */
protected static final String EMPTY_ARRAY[] = new String[0]; protected static final String EMPTY_ARRAY[] = new String[0];
// ------------------------------ WxSession // ------------------------------ WxSession
protected Map<String, Object> attributes = new ConcurrentHashMap<String, Object>();
protected Map<String, Object> attributes = new ConcurrentHashMap<>();
/** /**
* The session identifier of this Session. * The session identifier of this Session.
*/ */
@@ -47,7 +47,7 @@ public class StandardSession implements WxSession, InternalSession {
/** /**
* The current accessed time for this session. * The current accessed time for this session.
*/ */
protected volatile long thisAccessedTime = creationTime;
protected volatile long thisAccessedTime = this.creationTime;
/** /**
* The default maximum inactive interval for Sessions created by * The default maximum inactive interval for Sessions created by
* this Manager. * this Manager.
@@ -77,7 +77,7 @@ public class StandardSession implements WxSession, InternalSession {


if (name == null) return null; if (name == null) return null;


return (attributes.get(name));
return (this.attributes.get(name));
} }


@Override @Override
@@ -86,8 +86,8 @@ public class StandardSession implements WxSession, InternalSession {
throw new IllegalStateException throw new IllegalStateException
(sm.getString("sessionImpl.getAttributeNames.ise")); (sm.getString("sessionImpl.getAttributeNames.ise"));


Set<String> names = new HashSet<String>();
names.addAll(attributes.keySet());
Set<String> names = new HashSet<>();
names.addAll(this.attributes.keySet());
return Collections.enumeration(names); return Collections.enumeration(names);
} }


@@ -109,7 +109,7 @@ public class StandardSession implements WxSession, InternalSession {
throw new IllegalStateException(sm.getString( throw new IllegalStateException(sm.getString(
"sessionImpl.setAttribute.ise", getIdInternal())); "sessionImpl.setAttribute.ise", getIdInternal()));


attributes.put(name, value);
this.attributes.put(name, value);


} }


@@ -132,10 +132,10 @@ public class StandardSession implements WxSession, InternalSession {
@Override @Override
public WxSession getSession() { public WxSession getSession() {


if (facade == null) {
facade = new StandardSessionFacade(this);
if (this.facade == null) {
this.facade = new StandardSessionFacade(this);
} }
return (facade);
return (this.facade);


} }


@@ -157,15 +157,15 @@ public class StandardSession implements WxSession, InternalSession {
return true; return true;
} }


if (accessCount.get() > 0) {
if (this.accessCount.get() > 0) {
return true; return true;
} }


if (maxInactiveInterval > 0) {
if (this.maxInactiveInterval > 0) {
long timeNow = System.currentTimeMillis(); long timeNow = System.currentTimeMillis();
int timeIdle; int timeIdle;
timeIdle = (int) ((timeNow - thisAccessedTime) / 1000L);
if (timeIdle >= maxInactiveInterval) {
timeIdle = (int) ((timeNow - this.thisAccessedTime) / 1000L);
if (timeIdle >= this.maxInactiveInterval) {
expire(); expire();
} }
} }
@@ -193,7 +193,7 @@ public class StandardSession implements WxSession, InternalSession {
if (name == null) return; if (name == null) return;


// Remove this attribute from our collection // Remove this attribute from our collection
attributes.remove(name);
this.attributes.remove(name);


} }


@@ -202,7 +202,7 @@ public class StandardSession implements WxSession, InternalSession {
// Check to see if session has already been invalidated. // Check to see if session has already been invalidated.
// Do not check expiring at this point as expire should not return until // Do not check expiring at this point as expire should not return until
// isValid is false // isValid is false
if (!isValid)
if (!this.isValid)
return; return;


synchronized (this) { synchronized (this) {
@@ -210,24 +210,24 @@ public class StandardSession implements WxSession, InternalSession {
// Double check locking - isValid needs to be volatile // Double check locking - isValid needs to be volatile
// The check of expiring is to ensure that an infinite loop is not // The check of expiring is to ensure that an infinite loop is not
// entered as per bug 56339 // entered as per bug 56339
if (expiring || !isValid)
if (this.expiring || !this.isValid)
return; return;


if (manager == null)
if (this.manager == null)
return; return;


// Mark this session as "being expired" // Mark this session as "being expired"
expiring = true;
this.expiring = true;


accessCount.set(0);
this.accessCount.set(0);


// Remove this session from our manager's active sessions // Remove this session from our manager's active sessions
manager.remove(this, true);
this.manager.remove(this, true);




// We have completed expire of this session // We have completed expire of this session
setValid(false); setValid(false);
expiring = false;
this.expiring = false;


// Unbind any objects associated with this session // Unbind any objects associated with this session
String keys[] = keys(); String keys[] = keys();
@@ -244,7 +244,7 @@ public class StandardSession implements WxSession, InternalSession {
public void access() { public void access() {


this.thisAccessedTime = System.currentTimeMillis(); this.thisAccessedTime = System.currentTimeMillis();
accessCount.incrementAndGet();
this.accessCount.incrementAndGet();


} }


@@ -253,7 +253,7 @@ public class StandardSession implements WxSession, InternalSession {
public void endAccess() { public void endAccess() {


this.thisAccessedTime = System.currentTimeMillis(); this.thisAccessedTime = System.currentTimeMillis();
accessCount.decrementAndGet();
this.accessCount.decrementAndGet();


} }


@@ -273,13 +273,13 @@ public class StandardSession implements WxSession, InternalSession {


@Override @Override
public void setId(String id) { public void setId(String id) {
if ((this.id != null) && (manager != null))
manager.remove(this);
if ((this.id != null) && (this.manager != null))
this.manager.remove(this);


this.id = id; this.id = id;


if (manager != null)
manager.add(this);
if (this.manager != null)
this.manager.add(this);
} }


/** /**
@@ -289,7 +289,7 @@ public class StandardSession implements WxSession, InternalSession {
*/ */
protected String[] keys() { protected String[] keys() {


return attributes.keySet().toArray(EMPTY_ARRAY);
return this.attributes.keySet().toArray(EMPTY_ARRAY);


} }


@@ -300,31 +300,31 @@ public class StandardSession implements WxSession, InternalSession {


StandardSession session = (StandardSession) o; StandardSession session = (StandardSession) o;


if (creationTime != session.creationTime) return false;
if (expiring != session.expiring) return false;
if (isValid != session.isValid) return false;
if (maxInactiveInterval != session.maxInactiveInterval) return false;
if (thisAccessedTime != session.thisAccessedTime) return false;
if (!accessCount.equals(session.accessCount)) return false;
if (!attributes.equals(session.attributes)) return false;
if (!facade.equals(session.facade)) return false;
if (!id.equals(session.id)) return false;
return manager.equals(session.manager);
if (this.creationTime != session.creationTime) return false;
if (this.expiring != session.expiring) return false;
if (this.isValid != session.isValid) return false;
if (this.maxInactiveInterval != session.maxInactiveInterval) return false;
if (this.thisAccessedTime != session.thisAccessedTime) return false;
if (!this.accessCount.equals(session.accessCount)) return false;
if (!this.attributes.equals(session.attributes)) return false;
if (!this.facade.equals(session.facade)) return false;
if (!this.id.equals(session.id)) return false;
return this.manager.equals(session.manager);


} }


@Override @Override
public int hashCode() { public int hashCode() {
int result = attributes.hashCode();
result = 31 * result + id.hashCode();
result = 31 * result + (isValid ? 1 : 0);
result = 31 * result + (expiring ? 1 : 0);
result = 31 * result + manager.hashCode();
result = 31 * result + (int) (creationTime ^ (creationTime >>> 32));
result = 31 * result + (int) (thisAccessedTime ^ (thisAccessedTime >>> 32));
result = 31 * result + maxInactiveInterval;
result = 31 * result + facade.hashCode();
result = 31 * result + accessCount.hashCode();
int result = this.attributes.hashCode();
result = 31 * result + this.id.hashCode();
result = 31 * result + (this.isValid ? 1 : 0);
result = 31 * result + (this.expiring ? 1 : 0);
result = 31 * result + this.manager.hashCode();
result = 31 * result + (int) (this.creationTime ^ (this.creationTime >>> 32));
result = 31 * result + (int) (this.thisAccessedTime ^ (this.thisAccessedTime >>> 32));
result = 31 * result + this.maxInactiveInterval;
result = 31 * result + this.facade.hashCode();
result = 31 * result + this.accessCount.hashCode();
return result; return result;
} }




+ 6
- 6
weixin-java-common/src/main/java/me/chanjar/weixin/common/session/StandardSessionFacade.java View File

@@ -14,32 +14,32 @@ public class StandardSessionFacade implements WxSession {
} }


public InternalSession getInternalSession() { public InternalSession getInternalSession() {
return (InternalSession) session;
return (InternalSession) this.session;
} }


@Override @Override
public Object getAttribute(String name) { public Object getAttribute(String name) {
return session.getAttribute(name);
return this.session.getAttribute(name);
} }


@Override @Override
public Enumeration<String> getAttributeNames() { public Enumeration<String> getAttributeNames() {
return session.getAttributeNames();
return this.session.getAttributeNames();
} }


@Override @Override
public void setAttribute(String name, Object value) { public void setAttribute(String name, Object value) {
session.setAttribute(name, value);
this.session.setAttribute(name, value);
} }


@Override @Override
public void removeAttribute(String name) { public void removeAttribute(String name) {
session.removeAttribute(name);
this.session.removeAttribute(name);
} }


@Override @Override
public void invalidate() { public void invalidate() {
session.invalidate();
this.session.invalidate();
} }


} }

+ 25
- 25
weixin-java-common/src/main/java/me/chanjar/weixin/common/session/StandardSessionManager.java View File

@@ -32,7 +32,7 @@ public class StandardSessionManager implements WxSessionManager, InternalSession
* The set of currently active Sessions for this Manager, keyed by * The set of currently active Sessions for this Manager, keyed by
* session identifier. * session identifier.
*/ */
protected Map<String, InternalSession> sessions = new ConcurrentHashMap<String, InternalSession>();
protected Map<String, InternalSession> sessions = new ConcurrentHashMap<>();
/** /**
* The maximum number of active Sessions allowed, or -1 for no limit. * The maximum number of active Sessions allowed, or -1 for no limit.
*/ */
@@ -117,7 +117,7 @@ public class StandardSessionManager implements WxSessionManager, InternalSession
@Override @Override
public void remove(InternalSession session, boolean update) { public void remove(InternalSession session, boolean update) {
if (session.getIdInternal() != null) { if (session.getIdInternal() != null) {
sessions.remove(session.getIdInternal());
this.sessions.remove(session.getIdInternal());
} }
} }


@@ -127,7 +127,7 @@ public class StandardSessionManager implements WxSessionManager, InternalSession


if (id == null) if (id == null)
return (null); return (null);
return sessions.get(id);
return this.sessions.get(id);


} }


@@ -138,12 +138,12 @@ public class StandardSessionManager implements WxSessionManager, InternalSession
(sm.getString("sessionManagerImpl.createSession.ise")); (sm.getString("sessionManagerImpl.createSession.ise"));
} }


if ((maxActiveSessions >= 0) &&
(getActiveSessions() >= maxActiveSessions)) {
rejectedSessions++;
if ((this.maxActiveSessions >= 0) &&
(getActiveSessions() >= this.maxActiveSessions)) {
this.rejectedSessions++;
throw new TooManyActiveSessionsException( throw new TooManyActiveSessionsException(
sm.getString("sessionManagerImpl.createSession.tmase"), sm.getString("sessionManagerImpl.createSession.tmase"),
maxActiveSessions);
this.maxActiveSessions);
} }


// Recycle or create a Session instance // Recycle or create a Session instance
@@ -155,7 +155,7 @@ public class StandardSessionManager implements WxSessionManager, InternalSession
session.setMaxInactiveInterval(this.maxInactiveInterval); session.setMaxInactiveInterval(this.maxInactiveInterval);
String id = sessionId; String id = sessionId;
session.setId(id); session.setId(id);
sessionCounter++;
this.sessionCounter++;


return (session); return (session);


@@ -164,7 +164,7 @@ public class StandardSessionManager implements WxSessionManager, InternalSession


@Override @Override
public int getActiveSessions() { public int getActiveSessions() {
return sessions.size();
return this.sessions.size();
} }




@@ -185,17 +185,17 @@ public class StandardSessionManager implements WxSessionManager, InternalSession
public void add(InternalSession session) { public void add(InternalSession session) {


// 当第一次有session创建的时候,开启session清理线程 // 当第一次有session创建的时候,开启session清理线程
if (!backgroundProcessStarted.getAndSet(true)) {
if (!this.backgroundProcessStarted.getAndSet(true)) {
Thread t = new Thread(new Runnable() { Thread t = new Thread(new Runnable() {
@Override @Override
public void run() { public void run() {
while (true) { while (true) {
try { try {
// 每秒清理一次 // 每秒清理一次
Thread.sleep(backgroundProcessorDelay * 1000l);
Thread.sleep(StandardSessionManager.this.backgroundProcessorDelay * 1000l);
backgroundProcess(); backgroundProcess();
} catch (InterruptedException e) { } catch (InterruptedException e) {
log.error("SessionManagerImpl.backgroundProcess error", e);
StandardSessionManager.this.log.error("SessionManagerImpl.backgroundProcess error", e);
} }
} }
} }
@@ -204,12 +204,12 @@ public class StandardSessionManager implements WxSessionManager, InternalSession
t.start(); t.start();
} }


sessions.put(session.getIdInternal(), session);
this.sessions.put(session.getIdInternal(), session);
int size = getActiveSessions(); int size = getActiveSessions();
if (size > maxActive) {
synchronized (maxActiveUpdateLock) {
if (size > maxActive) {
maxActive = size;
if (size > this.maxActive) {
synchronized (this.maxActiveUpdateLock) {
if (size > this.maxActive) {
this.maxActive = size;
} }
} }
} }
@@ -223,14 +223,14 @@ public class StandardSessionManager implements WxSessionManager, InternalSession
@Override @Override
public InternalSession[] findSessions() { public InternalSession[] findSessions() {


return sessions.values().toArray(new InternalSession[0]);
return this.sessions.values().toArray(new InternalSession[0]);


} }


@Override @Override
public void backgroundProcess() { public void backgroundProcess() {
count = (count + 1) % processExpiresFrequency;
if (count == 0)
this.count = (this.count + 1) % this.processExpiresFrequency;
if (this.count == 0)
processExpires(); processExpires();
} }


@@ -243,17 +243,17 @@ public class StandardSessionManager implements WxSessionManager, InternalSession
InternalSession sessions[] = findSessions(); InternalSession sessions[] = findSessions();
int expireHere = 0; int expireHere = 0;


if (log.isDebugEnabled())
log.debug("Start expire sessions {} at {} sessioncount {}", getName(), timeNow, sessions.length);
if (this.log.isDebugEnabled())
this.log.debug("Start expire sessions {} at {} sessioncount {}", getName(), timeNow, sessions.length);
for (int i = 0; i < sessions.length; i++) { for (int i = 0; i < sessions.length; i++) {
if (sessions[i] != null && !sessions[i].isValid()) { if (sessions[i] != null && !sessions[i].isValid()) {
expireHere++; expireHere++;
} }
} }
long timeEnd = System.currentTimeMillis(); long timeEnd = System.currentTimeMillis();
if (log.isDebugEnabled())
log.debug("End expire sessions {} processingTime {} expired sessions: {}", getName(), timeEnd - timeNow, expireHere);
processingTime += (timeEnd - timeNow);
if (this.log.isDebugEnabled())
this.log.debug("End expire sessions {} processingTime {} expired sessions: {}", getName(), timeEnd - timeNow, expireHere);
this.processingTime += (timeEnd - timeNow);


} }




+ 2
- 2
weixin-java-common/src/main/java/me/chanjar/weixin/common/session/TooManyActiveSessionsException.java View File

@@ -40,7 +40,7 @@ public class TooManyActiveSessionsException
int maxActive) { int maxActive) {
super(message); super(message);


maxActiveSessions = maxActive;
this.maxActiveSessions = maxActive;
} }


/** /**
@@ -49,6 +49,6 @@ public class TooManyActiveSessionsException
* @return The maximum number of sessions allowed by the session manager. * @return The maximum number of sessions allowed by the session manager.
*/ */
public int getMaxActiveSessions() { public int getMaxActiveSessions() {
return maxActiveSessions;
return this.maxActiveSessions;
} }
} }

+ 1
- 1
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/LogExceptionHandler.java View File

@@ -13,7 +13,7 @@ public class LogExceptionHandler implements WxErrorExceptionHandler {
@Override @Override
public void handle(WxErrorException e) { public void handle(WxErrorException e) {


log.error("Error happens", e);
this.log.error("Error happens", e);


} }




+ 6
- 6
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/ByteGroup.java View File

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

+ 1
- 1
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/PKCS7Encoder.java View File

@@ -47,7 +47,7 @@ public class PKCS7Encoder {
* @return 删除补位字符后的明文 * @return 删除补位字符后的明文
*/ */
public static byte[] decode(byte[] decrypted) { public static byte[] decode(byte[] decrypted) {
int pad = (int) decrypted[decrypted.length - 1];
int pad = decrypted[decrypted.length - 1];
if (pad < 1 || pad > 32) { if (pad < 1 || pad > 32) {
pad = 0; pad = 0;
} }


+ 4
- 5
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/SHA1.java View File

@@ -1,10 +1,9 @@
package me.chanjar.weixin.common.util.crypto; package me.chanjar.weixin.common.util.crypto;


import org.apache.commons.codec.digest.DigestUtils;

import java.security.NoSuchAlgorithmException;
import java.util.Arrays; import java.util.Arrays;


import org.apache.commons.codec.digest.DigestUtils;

/** /**
* Created by Daniel Qian on 14/10/19. * Created by Daniel Qian on 14/10/19.
*/ */
@@ -13,7 +12,7 @@ public class SHA1 {
/** /**
* 串接arr参数,生成sha1 digest * 串接arr参数,生成sha1 digest
*/ */
public static String gen(String... arr) throws NoSuchAlgorithmException {
public static String gen(String... arr) {
Arrays.sort(arr); Arrays.sort(arr);
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (String a : arr) { for (String a : arr) {
@@ -25,7 +24,7 @@ public class SHA1 {
/** /**
* 用&串接arr参数,生成sha1 digest * 用&串接arr参数,生成sha1 digest
*/ */
public static String genWithAmple(String... arr) throws NoSuchAlgorithmException {
public static String genWithAmple(String... arr) {
Arrays.sort(arr); Arrays.sort(arr);
StringBuilder sb = new StringBuilder(); StringBuilder sb = new StringBuilder();
for (int i = 0; i < arr.length; i++) { for (int i = 0; i < arr.length; i++) {


+ 27
- 62
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/crypto/WxCryptUtil.java View File

@@ -17,11 +17,10 @@
*/ */
package me.chanjar.weixin.common.util.crypto; package me.chanjar.weixin.common.util.crypto;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
import java.io.StringReader;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Random;
import javax.crypto.Cipher; import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.IvParameterSpec;
@@ -29,10 +28,11 @@ import javax.crypto.spec.SecretKeySpec;
import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.ParserConfigurationException;
import java.io.StringReader;
import java.nio.charset.Charset;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import org.apache.commons.codec.binary.Base64;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.InputSource;
public class WxCryptUtil { public class WxCryptUtil {
@@ -72,33 +72,6 @@ public class WxCryptUtil {
this.aesKey = Base64.decodeBase64(encodingAesKey + "="); this.aesKey = Base64.decodeBase64(encodingAesKey + "=");
} }
/**
* 微信公众号支付签名算法(详见:http://pay.weixin.qq.com/wiki/doc/api/index.php?chapter=4_3)
* @param packageParams 原始参数
* @param signKey 加密Key(即 商户Key)
* @return 签名字符串
*/
public static String createSign(Map<String, String> packageParams,
String signKey) {
SortedMap<String, String> sortedMap = new TreeMap<String, String>();
sortedMap.putAll(packageParams);
List<String> keys = new ArrayList<String>(packageParams.keySet());
Collections.sort(keys);
StringBuffer toSign = new StringBuffer();
for (String key : keys) {
String value = packageParams.get(key);
if (null != value && !"".equals(value) && !"sign".equals(key)
&& !"key".equals(key)) {
toSign.append(key + "=" + value + "&");
}
}
toSign.append("key=" + signKey);
String sign = DigestUtils.md5Hex(toSign.toString()).toUpperCase();
return sign;
}
static String extractEncryptPart(String xml) { static String extractEncryptPart(String xml) {
try { try {
DocumentBuilder db = builderLocal.get(); DocumentBuilder db = builderLocal.get();
@@ -130,13 +103,9 @@ public class WxCryptUtil {
String timeStamp = Long.toString(System.currentTimeMillis() / 1000l); String timeStamp = Long.toString(System.currentTimeMillis() / 1000l);
String nonce = genRandomStr(); String nonce = genRandomStr();
try {
String signature = SHA1.gen(token, timeStamp, nonce, encryptedXml);
String result = generateXml(encryptedXml, signature, timeStamp, nonce);
return result;
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
String signature = SHA1.gen(this.token, timeStamp, nonce, encryptedXml);
String result = generateXml(encryptedXml, signature, timeStamp, nonce);
return result;
} }
/** /**
@@ -151,7 +120,7 @@ public class WxCryptUtil {
byte[] plainTextBytes = plainText.getBytes(CHARSET); byte[] plainTextBytes = plainText.getBytes(CHARSET);
byte[] bytesOfSizeInNetworkOrder = number2BytesInNetworkOrder( byte[] bytesOfSizeInNetworkOrder = number2BytesInNetworkOrder(
plainTextBytes.length); plainTextBytes.length);
byte[] appIdBytes = appidOrCorpid.getBytes(CHARSET);
byte[] appIdBytes = this.appidOrCorpid.getBytes(CHARSET);
// randomStr + networkBytesOrder + text + appid // randomStr + networkBytesOrder + text + appid
byteCollector.addBytes(randomStringBytes); byteCollector.addBytes(randomStringBytes);
@@ -169,8 +138,8 @@ public class WxCryptUtil {
try { try {
// 设置加密模式为AES的CBC模式 // 设置加密模式为AES的CBC模式
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec keySpec = new SecretKeySpec(aesKey, "AES");
IvParameterSpec iv = new IvParameterSpec(aesKey, 0, 16);
SecretKeySpec keySpec = new SecretKeySpec(this.aesKey, "AES");
IvParameterSpec iv = new IvParameterSpec(this.aesKey, 0, 16);
cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv); cipher.init(Cipher.ENCRYPT_MODE, keySpec, iv);
// 加密 // 加密
@@ -205,14 +174,10 @@ public class WxCryptUtil {
// 提取密文 // 提取密文
String cipherText = extractEncryptPart(encryptedXml); String cipherText = extractEncryptPart(encryptedXml);
try {
// 验证安全签名
String signature = SHA1.gen(token, timeStamp, nonce, cipherText);
if (!signature.equals(msgSignature)) {
throw new RuntimeException("加密消息签名校验失败");
}
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
// 验证安全签名
String signature = SHA1.gen(this.token, timeStamp, nonce, cipherText);
if (!signature.equals(msgSignature)) {
throw new RuntimeException("加密消息签名校验失败");
} }
// 解密 // 解密
@@ -231,9 +196,9 @@ public class WxCryptUtil {
try { try {
// 设置解密模式为AES的CBC模式 // 设置解密模式为AES的CBC模式
Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding"); Cipher cipher = Cipher.getInstance("AES/CBC/NoPadding");
SecretKeySpec key_spec = new SecretKeySpec(aesKey, "AES");
SecretKeySpec key_spec = new SecretKeySpec(this.aesKey, "AES");
IvParameterSpec iv = new IvParameterSpec( IvParameterSpec iv = new IvParameterSpec(
Arrays.copyOfRange(aesKey, 0, 16));
Arrays.copyOfRange(this.aesKey, 0, 16));
cipher.init(Cipher.DECRYPT_MODE, key_spec, iv); cipher.init(Cipher.DECRYPT_MODE, key_spec, iv);
// 使用BASE64对密文进行解码 // 使用BASE64对密文进行解码
@@ -264,7 +229,7 @@ public class WxCryptUtil {
} }
// appid不相同的情况 // appid不相同的情况
if (!from_appid.equals(appidOrCorpid)) {
if (!from_appid.equals(this.appidOrCorpid)) {
throw new RuntimeException("AppID不正确"); throw new RuntimeException("AppID不正确");
} }
@@ -277,7 +242,7 @@ public class WxCryptUtil {
* *
* @param number * @param number
*/ */
private byte[] number2BytesInNetworkOrder(int number) {
private static byte[] number2BytesInNetworkOrder(int number) {
byte[] orderBytes = new byte[4]; byte[] orderBytes = new byte[4];
orderBytes[3] = (byte) (number & 0xFF); orderBytes[3] = (byte) (number & 0xFF);
orderBytes[2] = (byte) (number >> 8 & 0xFF); orderBytes[2] = (byte) (number >> 8 & 0xFF);
@@ -291,7 +256,7 @@ public class WxCryptUtil {
* *
* @param bytesInNetworkOrder * @param bytesInNetworkOrder
*/ */
private int bytesNetworkOrder2Number(byte[] bytesInNetworkOrder) {
private static int bytesNetworkOrder2Number(byte[] bytesInNetworkOrder) {
int sourceNumber = 0; int sourceNumber = 0;
for (int i = 0; i < 4; i++) { for (int i = 0; i < 4; i++) {
sourceNumber <<= 8; sourceNumber <<= 8;
@@ -303,7 +268,7 @@ public class WxCryptUtil {
/** /**
* 随机生成16位字符串 * 随机生成16位字符串
*/ */
private String genRandomStr() {
private static String genRandomStr() {
String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; String base = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
Random random = new Random(); Random random = new Random();
StringBuffer sb = new StringBuffer(); StringBuffer sb = new StringBuffer();
@@ -323,8 +288,8 @@ public class WxCryptUtil {
* @param nonce 随机字符串 * @param nonce 随机字符串
* @return 生成的xml字符串 * @return 生成的xml字符串
*/ */
private String generateXml(String encrypt, String signature, String timestamp,
String nonce) {
private static String generateXml(String encrypt, String signature,
String timestamp, String nonce) {
String format = "<xml>\n" + "<Encrypt><![CDATA[%1$s]]></Encrypt>\n" String format = "<xml>\n" + "<Encrypt><![CDATA[%1$s]]></Encrypt>\n"
+ "<MsgSignature><![CDATA[%2$s]]></MsgSignature>\n" + "<MsgSignature><![CDATA[%2$s]]></MsgSignature>\n"
+ "<TimeStamp>%3$s</TimeStamp>\n" + "<Nonce><![CDATA[%4$s]]></Nonce>\n" + "<TimeStamp>%3$s</TimeStamp>\n" + "<Nonce><![CDATA[%4$s]]></Nonce>\n"


+ 12
- 24
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/fs/FileUtils.java View File

@@ -17,37 +17,25 @@ public class FileUtils {
* @param tmpDirFile 临时文件夹目录 * @param tmpDirFile 临时文件夹目录
*/ */
public static File createTmpFile(InputStream inputStream, String name, String ext, File tmpDirFile) throws IOException { public static File createTmpFile(InputStream inputStream, String name, String ext, File tmpDirFile) throws IOException {
FileOutputStream fos = null;
try {
File tmpFile;
if (tmpDirFile == null) {
tmpFile = File.createTempFile(name, '.' + ext);
} else {
tmpFile = File.createTempFile(name, '.' + ext, tmpDirFile);
}
tmpFile.deleteOnExit();
fos = new FileOutputStream(tmpFile);
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; int read = 0;
byte[] bytes = new byte[1024 * 100]; byte[] bytes = new byte[1024 * 100];
while ((read = inputStream.read(bytes)) != -1) { while ((read = inputStream.read(bytes)) != -1) {
fos.write(bytes, 0, read); fos.write(bytes, 0, read);
} }

fos.flush(); fos.flush();
return tmpFile; return tmpFile;
} finally {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
}
}
}
}
} }


/** /**


+ 23
- 21
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/DefaultApacheHttpClientBuilder.java View File

@@ -103,43 +103,45 @@ public class DefaultApacheHttpClientBuilder implements ApacheHttpClientBuilder {


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


@SuppressWarnings("resource")
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry); PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(registry);
connectionManager.setMaxTotal(this.maxTotalConn); connectionManager.setMaxTotal(this.maxTotalConn);
connectionManager.setDefaultMaxPerRoute(this.maxConnPerHost); connectionManager.setDefaultMaxPerRoute(this.maxConnPerHost);
connectionManager.setDefaultSocketConfig( connectionManager.setDefaultSocketConfig(
SocketConfig.copy(SocketConfig.DEFAULT)
.setSoTimeout(this.soTimeout)
.build()
SocketConfig.copy(SocketConfig.DEFAULT)
.setSoTimeout(this.soTimeout)
.build()
); );


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


this.httpClientBuilder = HttpClients.custom() this.httpClientBuilder = HttpClients.custom()
.setConnectionManager(connectionManager)
.setDefaultRequestConfig(
RequestConfig.custom()
.setSocketTimeout(this.soTimeout)
.setConnectTimeout(this.connectionTimeout)
.setConnectionRequestTimeout(this.connectionRequestTimeout)
.build()
)
.setRetryHandler(this.httpRequestRetryHandler);
.setConnectionManager(connectionManager)
.setConnectionManagerShared(true)
.setDefaultRequestConfig(
RequestConfig.custom()
.setSocketTimeout(this.soTimeout)
.setConnectTimeout(this.connectionTimeout)
.setConnectionRequestTimeout(this.connectionRequestTimeout)
.build()
)
.setRetryHandler(this.httpRequestRetryHandler);


if (StringUtils.isNotBlank(this.httpProxyHost) if (StringUtils.isNotBlank(this.httpProxyHost)
&& StringUtils.isNotBlank(this.httpProxyUsername)) {
&& StringUtils.isNotBlank(this.httpProxyUsername)) {
// 使用代理服务器 需要用户认证的代理服务器 // 使用代理服务器 需要用户认证的代理服务器
CredentialsProvider provider = new BasicCredentialsProvider(); CredentialsProvider provider = new BasicCredentialsProvider();
provider.setCredentials( provider.setCredentials(
new AuthScope(this.httpProxyHost, this.httpProxyPort),
new UsernamePasswordCredentials(this.httpProxyUsername,
this.httpProxyPassword));
new AuthScope(this.httpProxyHost, this.httpProxyPort),
new UsernamePasswordCredentials(this.httpProxyUsername,
this.httpProxyPassword));
this.httpClientBuilder.setDefaultCredentialsProvider(provider); this.httpClientBuilder.setDefaultCredentialsProvider(provider);
} }


@@ -180,7 +182,7 @@ public class DefaultApacheHttpClientBuilder implements ApacheHttpClientBuilder {
wait(this.checkWaitTime); wait(this.checkWaitTime);
this.connMgr.closeExpiredConnections(); this.connMgr.closeExpiredConnections();
this.connMgr.closeIdleConnections(this.idleConnTimeout, this.connMgr.closeIdleConnections(this.idleConnTimeout,
TimeUnit.MILLISECONDS);
TimeUnit.MILLISECONDS);
} }
} }
} catch (InterruptedException ignore) { } catch (InterruptedException ignore) {


+ 1
- 0
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/InputStreamResponseHandler.java View File

@@ -14,6 +14,7 @@ public class InputStreamResponseHandler implements ResponseHandler<InputStream>


public static final ResponseHandler<InputStream> INSTANCE = new InputStreamResponseHandler(); public static final ResponseHandler<InputStream> INSTANCE = new InputStreamResponseHandler();


@Override
public InputStream handleResponse(final HttpResponse response) throws IOException { public InputStream handleResponse(final HttpResponse response) throws IOException {
final StatusLine statusLine = response.getStatusLine(); final StatusLine statusLine = response.getStatusLine();
final HttpEntity entity = response.getEntity(); final HttpEntity entity = response.getEntity();


+ 4
- 5
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/JoddGetRequestExecutor.java View File

@@ -1,15 +1,14 @@
package me.chanjar.weixin.common.util.http; package me.chanjar.weixin.common.util.http;


import org.apache.http.HttpHost;
import org.apache.http.impl.client.CloseableHttpClient;

import jodd.http.HttpRequest; import jodd.http.HttpRequest;
import jodd.http.HttpResponse; import jodd.http.HttpResponse;
import jodd.http.ProxyInfo; import jodd.http.ProxyInfo;
import jodd.http.net.SocketHttpConnectionProvider; import jodd.http.net.SocketHttpConnectionProvider;
import me.chanjar.weixin.common.bean.result.WxError; import me.chanjar.weixin.common.bean.result.WxError;
import me.chanjar.weixin.common.exception.WxErrorException; import me.chanjar.weixin.common.exception.WxErrorException;
import org.apache.http.HttpHost;
import org.apache.http.impl.client.CloseableHttpClient;

import java.io.IOException;


/** /**
* 简单的GET请求执行器,请求的参数是String, 返回的结果也是String * 简单的GET请求执行器,请求的参数是String, 返回的结果也是String
@@ -20,7 +19,7 @@ public class JoddGetRequestExecutor implements RequestExecutor<String, String> {


@Override @Override
public String execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, public String execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri,
String queryParam) throws WxErrorException, IOException {
String queryParam) throws WxErrorException {
if (queryParam != null) { if (queryParam != null) {
if (uri.indexOf('?') == -1) { if (uri.indexOf('?') == -1) {
uri += '?'; uri += '?';


+ 4
- 5
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/JoddPostRequestExecutor.java View File

@@ -1,15 +1,14 @@
package me.chanjar.weixin.common.util.http; package me.chanjar.weixin.common.util.http;


import org.apache.http.HttpHost;
import org.apache.http.impl.client.CloseableHttpClient;

import jodd.http.HttpRequest; import jodd.http.HttpRequest;
import jodd.http.HttpResponse; import jodd.http.HttpResponse;
import jodd.http.ProxyInfo; import jodd.http.ProxyInfo;
import jodd.http.net.SocketHttpConnectionProvider; import jodd.http.net.SocketHttpConnectionProvider;
import me.chanjar.weixin.common.bean.result.WxError; import me.chanjar.weixin.common.bean.result.WxError;
import me.chanjar.weixin.common.exception.WxErrorException; import me.chanjar.weixin.common.exception.WxErrorException;
import org.apache.http.HttpHost;
import org.apache.http.impl.client.CloseableHttpClient;

import java.io.IOException;


/** /**
* 简单的POST请求执行器,请求的参数是String, 返回的结果也是String * 简单的POST请求执行器,请求的参数是String, 返回的结果也是String
@@ -20,7 +19,7 @@ public class JoddPostRequestExecutor implements RequestExecutor<String, String>


@Override @Override
public String execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, public String execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri,
String postEntity) throws WxErrorException, IOException {
String postEntity) throws WxErrorException {
SocketHttpConnectionProvider provider = new SocketHttpConnectionProvider(); SocketHttpConnectionProvider provider = new SocketHttpConnectionProvider();


if (httpProxy != null) { if (httpProxy != null) {


+ 18
- 16
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/MediaDownloadRequestExecutor.java View File

@@ -20,7 +20,7 @@ import java.util.regex.Pattern;


/** /**
* 下载媒体文件请求执行器,请求的参数是String, 返回的结果是File * 下载媒体文件请求执行器,请求的参数是String, 返回的结果是File
*
* 视频文件不支持下载
* @author Daniel Qian * @author Daniel Qian
*/ */
public class MediaDownloadRequestExecutor implements RequestExecutor<File, String> { public class MediaDownloadRequestExecutor implements RequestExecutor<File, String> {
@@ -28,15 +28,12 @@ public class MediaDownloadRequestExecutor implements RequestExecutor<File, Strin
private File tmpDirFile; private File tmpDirFile;


public MediaDownloadRequestExecutor() { public MediaDownloadRequestExecutor() {
super();
} }


public MediaDownloadRequestExecutor(File tmpDirFile) { public MediaDownloadRequestExecutor(File tmpDirFile) {
super();
this.tmpDirFile = tmpDirFile; this.tmpDirFile = tmpDirFile;
} }



@Override @Override
public File execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, String queryParam) throws WxErrorException, IOException { public File execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, String queryParam) throws WxErrorException, IOException {
if (queryParam != null) { if (queryParam != null) {
@@ -52,26 +49,26 @@ public class MediaDownloadRequestExecutor implements RequestExecutor<File, Strin
httpGet.setConfig(config); httpGet.setConfig(config);
} }


try (CloseableHttpResponse response = httpclient.execute(httpGet)) {
try (CloseableHttpResponse response = httpclient.execute(httpGet);
InputStream inputStream = InputStreamResponseHandler.INSTANCE
.handleResponse(response)) {


Header[] contentTypeHeader = response.getHeaders("Content-Type"); Header[] contentTypeHeader = response.getHeaders("Content-Type");
if (contentTypeHeader != null && contentTypeHeader.length > 0) { if (contentTypeHeader != null && contentTypeHeader.length > 0) {
// 下载媒体文件出错
if (ContentType.TEXT_PLAIN.getMimeType().equals(contentTypeHeader[0].getValue())) {
if (contentTypeHeader[0].getValue().startsWith(ContentType.APPLICATION_JSON.getMimeType())) {
// application/json; encoding=utf-8 下载媒体文件出错
String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response);
throw new WxErrorException(WxError.fromJson(responseContent)); throw new WxErrorException(WxError.fromJson(responseContent));
} }
} }
InputStream inputStream = InputStreamResponseHandler.INSTANCE.handleResponse(response);


// 视频文件不支持下载
String fileName = getFileName(response); String fileName = getFileName(response);
if (StringUtils.isBlank(fileName)) { if (StringUtils.isBlank(fileName)) {
return null; return null;
} }
String[] name_ext = fileName.split("\\.");
File localFile = FileUtils.createTmpFile(inputStream, name_ext[0], name_ext[1], tmpDirFile);
return localFile;
String[] nameAndExt = fileName.split("\\.");
return FileUtils.createTmpFile(inputStream, nameAndExt[0], nameAndExt[1], this.tmpDirFile);


} finally { } finally {
httpGet.releaseConnection(); httpGet.releaseConnection();
@@ -79,13 +76,18 @@ public class MediaDownloadRequestExecutor implements RequestExecutor<File, Strin


} }


protected String getFileName(CloseableHttpResponse response) {
private String getFileName(CloseableHttpResponse response) throws WxErrorException {
Header[] contentDispositionHeader = response.getHeaders("Content-disposition"); Header[] contentDispositionHeader = response.getHeaders("Content-disposition");
if(contentDispositionHeader == null || contentDispositionHeader.length == 0){
throw new WxErrorException(WxError.newBuilder().setErrorMsg("无法获取到文件名").build());
}

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


} }

+ 0
- 2
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/RequestExecutor.java View File

@@ -2,7 +2,6 @@ package me.chanjar.weixin.common.util.http;


import me.chanjar.weixin.common.exception.WxErrorException; import me.chanjar.weixin.common.exception.WxErrorException;
import org.apache.http.HttpHost; import org.apache.http.HttpHost;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;


import java.io.IOException; import java.io.IOException;
@@ -21,7 +20,6 @@ public interface RequestExecutor<T, E> {
* @param uri uri * @param uri uri
* @param data 数据 * @param data 数据
* @throws WxErrorException * @throws WxErrorException
* @throws ClientProtocolException
* @throws IOException * @throws IOException
*/ */
T execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, E data) throws WxErrorException, IOException; T execute(CloseableHttpClient httpclient, HttpHost httpProxy, String uri, E data) throws WxErrorException, IOException;


+ 15
- 3
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/SimplePostRequestExecutor.java View File

@@ -1,7 +1,7 @@
package me.chanjar.weixin.common.util.http; package me.chanjar.weixin.common.util.http;


import me.chanjar.weixin.common.bean.result.WxError;
import me.chanjar.weixin.common.exception.WxErrorException;
import java.io.IOException;
import org.apache.http.Consts; import org.apache.http.Consts;
import org.apache.http.HttpHost; import org.apache.http.HttpHost;
import org.apache.http.client.config.RequestConfig; import org.apache.http.client.config.RequestConfig;
@@ -10,7 +10,8 @@ import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity; import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.CloseableHttpClient;


import java.io.IOException;
import me.chanjar.weixin.common.bean.result.WxError;
import me.chanjar.weixin.common.exception.WxErrorException;


/** /**
* 简单的POST请求执行器,请求的参数是String, 返回的结果也是String * 简单的POST请求执行器,请求的参数是String, 返回的结果也是String
@@ -34,6 +35,17 @@ public class SimplePostRequestExecutor implements RequestExecutor<String, String


try (CloseableHttpResponse response = httpclient.execute(httpPost)) { try (CloseableHttpResponse response = httpclient.execute(httpPost)) {
String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response); String responseContent = Utf8ResponseHandler.INSTANCE.handleResponse(response);
if (responseContent.isEmpty()) {
throw new WxErrorException(
WxError.newBuilder().setErrorCode(9999).setErrorMsg("无响应内容")
.build());
}

if (responseContent.startsWith("<xml>")) {
//xml格式输出直接返回
return responseContent;
}

WxError error = WxError.fromJson(responseContent); WxError error = WxError.fromJson(responseContent);
if (error.getErrorCode() != 0) { if (error.getErrorCode() != 0) {
throw new WxErrorException(error); throw new WxErrorException(error);


+ 1
- 1
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/URIUtil.java View File

@@ -35,7 +35,7 @@ public class URIUtil {
private static String getHex(byte buf[]) { private static String getHex(byte buf[]) {
StringBuilder o = new StringBuilder(buf.length * 3); StringBuilder o = new StringBuilder(buf.length * 3);
for (int i = 0; i < buf.length; i++) { for (int i = 0; i < buf.length; i++) {
int n = (int) buf[i] & 0xff;
int n = buf[i] & 0xff;
o.append("%"); o.append("%");
if (n < 0x10) { if (n < 0x10) {
o.append("0"); o.append("0");


+ 1
- 0
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/http/Utf8ResponseHandler.java View File

@@ -19,6 +19,7 @@ public class Utf8ResponseHandler implements ResponseHandler<String> {


public static final ResponseHandler<String> INSTANCE = new Utf8ResponseHandler(); public static final ResponseHandler<String> INSTANCE = new Utf8ResponseHandler();


@Override
public String handleResponse(final HttpResponse response) throws IOException { public String handleResponse(final HttpResponse response) throws IOException {
final StatusLine statusLine = response.getStatusLine(); final StatusLine statusLine = response.getStatusLine();
final HttpEntity entity = response.getEntity(); final HttpEntity entity = response.getEntity();


+ 21
- 0
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/GsonHelper.java View File

@@ -9,6 +9,10 @@
package me.chanjar.weixin.common.util.json; package me.chanjar.weixin.common.util.json;




import java.util.List;

import com.google.common.collect.Lists;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;


@@ -112,4 +116,21 @@ public class GsonHelper {
return r == null ? 0f : r; return r == null ? 0f : r;
} }


public static Integer[] getIntArray(JsonObject o, String string) {
JsonArray jsonArray = getAsJsonArray(o.getAsJsonArray(string));
if (jsonArray == null) {
return null;
}

List<Integer> result = Lists.newArrayList();
for (int i = 0; i < jsonArray.size(); i++) {
result.add(jsonArray.get(i).getAsInt());
}

return result.toArray(new Integer[0]);
}

public static JsonArray getAsJsonArray(JsonElement element) {
return element == null ? null : element.getAsJsonArray();
}
} }

+ 1
- 0
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxAccessTokenAdapter.java View File

@@ -18,6 +18,7 @@ import java.lang.reflect.Type;
*/ */
public class WxAccessTokenAdapter implements JsonDeserializer<WxAccessToken> { public class WxAccessTokenAdapter implements JsonDeserializer<WxAccessToken> {


@Override
public WxAccessToken deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { public WxAccessToken deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
WxAccessToken accessToken = new WxAccessToken(); WxAccessToken accessToken = new WxAccessToken();
JsonObject accessTokenJsonObject = json.getAsJsonObject(); JsonObject accessTokenJsonObject = json.getAsJsonObject();


+ 1
- 0
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxErrorAdapter.java View File

@@ -18,6 +18,7 @@ import java.lang.reflect.Type;
*/ */
public class WxErrorAdapter implements JsonDeserializer<WxError> { public class WxErrorAdapter implements JsonDeserializer<WxError> {


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


+ 1
- 0
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxMediaUploadResultAdapter.java View File

@@ -18,6 +18,7 @@ import java.lang.reflect.Type;
*/ */
public class WxMediaUploadResultAdapter implements JsonDeserializer<WxMediaUploadResult> { public class WxMediaUploadResultAdapter implements JsonDeserializer<WxMediaUploadResult> {


@Override
public WxMediaUploadResult deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { public WxMediaUploadResult deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
WxMediaUploadResult uploadResult = new WxMediaUploadResult(); WxMediaUploadResult uploadResult = new WxMediaUploadResult();
JsonObject uploadResultJsonObject = json.getAsJsonObject(); JsonObject uploadResultJsonObject = json.getAsJsonObject();


+ 2
- 0
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/json/WxMenuGsonAdapter.java View File

@@ -29,6 +29,7 @@ import me.chanjar.weixin.common.bean.menu.WxMenuRule;
*/ */
public class WxMenuGsonAdapter implements JsonSerializer<WxMenu>, JsonDeserializer<WxMenu> { public class WxMenuGsonAdapter implements JsonSerializer<WxMenu>, JsonDeserializer<WxMenu> {


@Override
public JsonElement serialize(WxMenu menu, Type typeOfSrc, JsonSerializationContext context) { public JsonElement serialize(WxMenu menu, Type typeOfSrc, JsonSerializationContext context) {
JsonObject json = new JsonObject(); JsonObject json = new JsonObject();


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


@Override
public WxMenu deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { public WxMenu deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
/* /*
* 操蛋的微信 * 操蛋的微信


+ 8
- 8
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/res/StringManager.java View File

@@ -47,7 +47,7 @@ import java.util.*;
public class StringManager { public class StringManager {


private static final Map<String, Map<Locale, StringManager>> managers = private static final Map<String, Map<Locale, StringManager>> managers =
new Hashtable<String, Map<Locale, StringManager>>();
new Hashtable<>();
private static int LOCALE_CACHE_SIZE = 10; private static int LOCALE_CACHE_SIZE = 10;
/** /**
* The ResourceBundle for this StringManager. * The ResourceBundle for this StringManager.
@@ -81,10 +81,10 @@ public class StringManager {
} }
} }
} }
bundle = bnd;
this.bundle = bnd;
// Get the actual locale, which may be different from the requested one // Get the actual locale, which may be different from the requested one
if (bundle != null) {
Locale bundleLocale = bundle.getLocale();
if (this.bundle != null) {
Locale bundleLocale = this.bundle.getLocale();
if (bundleLocale.equals(Locale.ROOT)) { if (bundleLocale.equals(Locale.ROOT)) {
this.locale = Locale.ENGLISH; this.locale = Locale.ENGLISH;
} else { } else {
@@ -192,8 +192,8 @@ public class StringManager {


try { try {
// Avoid NPE if bundle is null and treat it like an MRE // Avoid NPE if bundle is null and treat it like an MRE
if (bundle != null) {
str = bundle.getString(key);
if (this.bundle != null) {
str = this.bundle.getString(key);
} }
} catch (MissingResourceException mre) { } catch (MissingResourceException mre) {
//bad: shouldn't mask an exception the following way: //bad: shouldn't mask an exception the following way:
@@ -227,7 +227,7 @@ public class StringManager {
} }


MessageFormat mf = new MessageFormat(value); MessageFormat mf = new MessageFormat(value);
mf.setLocale(locale);
mf.setLocale(this.locale);
return mf.format(args, new StringBuffer(), null).toString(); return mf.format(args, new StringBuffer(), null).toString();
} }


@@ -235,6 +235,6 @@ public class StringManager {
* Identify the Locale this StringManager is associated with * Identify the Locale this StringManager is associated with
*/ */
public Locale getLocale() { public Locale getLocale() {
return locale;
return this.locale;
} }
} }

+ 9
- 4
weixin-java-common/src/main/java/me/chanjar/weixin/common/util/xml/XStreamInitializer.java View File

@@ -1,5 +1,7 @@
package me.chanjar.weixin.common.util.xml; package me.chanjar.weixin.common.util.xml;


import java.io.Writer;

import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.core.util.QuickWriter; import com.thoughtworks.xstream.core.util.QuickWriter;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter; import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
@@ -8,8 +10,6 @@ import com.thoughtworks.xstream.io.xml.XppDriver;
import com.thoughtworks.xstream.security.NullPermission; import com.thoughtworks.xstream.security.NullPermission;
import com.thoughtworks.xstream.security.PrimitiveTypePermission; import com.thoughtworks.xstream.security.PrimitiveTypePermission;


import java.io.Writer;

public class XStreamInitializer { public class XStreamInitializer {


public static XStream getInstance() { public static XStream getInstance() {
@@ -25,15 +25,20 @@ public class XStreamInitializer {


@Override @Override
protected void writeText(QuickWriter writer, String text) { protected void writeText(QuickWriter writer, String text) {
if (text.startsWith(PREFIX_CDATA) && text.endsWith(SUFFIX_CDATA)) {
if (text.startsWith(this.PREFIX_CDATA) && text.endsWith(this.SUFFIX_CDATA)) {
writer.write(text); writer.write(text);
} else if (text.startsWith(PREFIX_MEDIA_ID) && text.endsWith(SUFFIX_MEDIA_ID)) {
} else if (text.startsWith(this.PREFIX_MEDIA_ID) && text.endsWith(this.SUFFIX_MEDIA_ID)) {
writer.write(text); writer.write(text);
} else { } else {
super.writeText(writer, text); super.writeText(writer, text);
} }


} }

@Override
public String encodeNode(String name) {
return name;//防止将_转换成__
}
}; };
} }
}); });


+ 2
- 2
weixin-java-common/src/test/java/me/chanjar/weixin/common/session/SessionTest.java View File

@@ -106,7 +106,7 @@ public class SessionTest {
} }


@Test(dataProvider = "getSessionManager") @Test(dataProvider = "getSessionManager")
public void testMaxActive(WxSessionManager sessionManager) throws InterruptedException {
public void testMaxActive(WxSessionManager sessionManager) {


InternalSessionManager ism = (InternalSessionManager) sessionManager; InternalSessionManager ism = (InternalSessionManager) sessionManager;
ism.setMaxActiveSessions(2); ism.setMaxActiveSessions(2);
@@ -118,7 +118,7 @@ public class SessionTest {
} }


@Test(dataProvider = "getSessionManager", expectedExceptions = TooManyActiveSessionsException.class) @Test(dataProvider = "getSessionManager", expectedExceptions = TooManyActiveSessionsException.class)
public void testMaxActive2(WxSessionManager sessionManager) throws InterruptedException {
public void testMaxActive2(WxSessionManager sessionManager) {


InternalSessionManager ism = (InternalSessionManager) sessionManager; InternalSessionManager ism = (InternalSessionManager) sessionManager;
ism.setMaxActiveSessions(2); ism.setMaxActiveSessions(2);


+ 12
- 12
weixin-java-common/src/test/java/me/chanjar/weixin/common/util/crypto/WxCryptUtilTest.java View File

@@ -34,8 +34,8 @@ public class WxCryptUtilTest {
String afterAesEncrypt2 = "jn1L23DB+6ELqJ+6bruv23M2GmYfkv0xBh2h+XTBOKVKcgDFHle6gqcZ1cZrk3e1qjPQ1F4RsLWzQRG9udbKWesxlkupqcEcW7ZQweImX9+wLMa0GaUzpkycA8+IamDBxn5loLgZpnS7fVAbExOkK5DYHBmv5tptA9tklE/fTIILHR8HLXa5nQvFb3tYPKAlHF3rtTeayNf0QuM+UW/wM9enGIDIJHF7CLHiDNAYxr+r+OrJCmPQyTy8cVWlu9iSvOHPT/77bZqJucQHQ04sq7KZI27OcqpQNSto2OdHCoTccjggX5Z9Mma0nMJBU+jLKJ38YB1fBIz+vBzsYjrTmFQ44YfeEuZ+xRTQwr92vhA9OxchWVINGC50qE/6lmkwWTwGX9wtQpsJKhP+oS7rvTY8+VdzETdfakjkwQ5/Xka042OlUb1/slTwo4RscuQ+RdxSGvDahxAJ6+EAjLt9d8igHngxIbf6YyqqROxuxqIeIch3CssH/LqRs+iAcILvApYZckqmA7FNERspKA5f8GoJ9sv8xmGvZ9Yrf57cExWtnX8aCMMaBropU/1k+hKP5LVdzbWCG0hGwx/dQudYR/eXp3P0XxjlFiy+9DMlaFExWUZQDajPkdPrEeOwofJb"; String afterAesEncrypt2 = "jn1L23DB+6ELqJ+6bruv23M2GmYfkv0xBh2h+XTBOKVKcgDFHle6gqcZ1cZrk3e1qjPQ1F4RsLWzQRG9udbKWesxlkupqcEcW7ZQweImX9+wLMa0GaUzpkycA8+IamDBxn5loLgZpnS7fVAbExOkK5DYHBmv5tptA9tklE/fTIILHR8HLXa5nQvFb3tYPKAlHF3rtTeayNf0QuM+UW/wM9enGIDIJHF7CLHiDNAYxr+r+OrJCmPQyTy8cVWlu9iSvOHPT/77bZqJucQHQ04sq7KZI27OcqpQNSto2OdHCoTccjggX5Z9Mma0nMJBU+jLKJ38YB1fBIz+vBzsYjrTmFQ44YfeEuZ+xRTQwr92vhA9OxchWVINGC50qE/6lmkwWTwGX9wtQpsJKhP+oS7rvTY8+VdzETdfakjkwQ5/Xka042OlUb1/slTwo4RscuQ+RdxSGvDahxAJ6+EAjLt9d8igHngxIbf6YyqqROxuxqIeIch3CssH/LqRs+iAcILvApYZckqmA7FNERspKA5f8GoJ9sv8xmGvZ9Yrf57cExWtnX8aCMMaBropU/1k+hKP5LVdzbWCG0hGwx/dQudYR/eXp3P0XxjlFiy+9DMlaFExWUZQDajPkdPrEeOwofJb";
public void testNormal() throws ParserConfigurationException, SAXException, IOException { public void testNormal() throws ParserConfigurationException, SAXException, IOException {
WxCryptUtil pc = new WxCryptUtil(token, encodingAesKey, appId);
String encryptedXml = pc.encrypt(replyMsg);
WxCryptUtil pc = new WxCryptUtil(this.token, this.encodingAesKey, this.appId);
String encryptedXml = pc.encrypt(this.replyMsg);
System.out.println(encryptedXml); System.out.println(encryptedXml);
@@ -56,31 +56,31 @@ public class WxCryptUtilTest {
String nonce = root.getElementsByTagName("Nonce").item(0).getTextContent(); String nonce = root.getElementsByTagName("Nonce").item(0).getTextContent();
System.out.println(nonce); System.out.println(nonce);
String messageText = String.format(xmlFormat, cipherText);
String messageText = String.format(this.xmlFormat, cipherText);
System.out.println(messageText); System.out.println(messageText);
// 第三方收到企业号平台发送的消息 // 第三方收到企业号平台发送的消息
String plainMessage = pc.decrypt(cipherText); String plainMessage = pc.decrypt(cipherText);
System.out.println(plainMessage); System.out.println(plainMessage);
assertEquals(plainMessage, replyMsg);
assertEquals(plainMessage, this.replyMsg);
} }
public void testAesEncrypt() { public void testAesEncrypt() {
WxCryptUtil pc = new WxCryptUtil(token, encodingAesKey, appId);
assertEquals(pc.encrypt(randomStr, replyMsg), afterAesEncrypt);
WxCryptUtil pc = new WxCryptUtil(this.token, this.encodingAesKey, this.appId);
assertEquals(pc.encrypt(this.randomStr, this.replyMsg), this.afterAesEncrypt);
} }
public void testAesEncrypt2() { public void testAesEncrypt2() {
WxCryptUtil pc = new WxCryptUtil(token, encodingAesKey, appId);
assertEquals(pc.encrypt(randomStr, replyMsg2), afterAesEncrypt2);
WxCryptUtil pc = new WxCryptUtil(this.token, this.encodingAesKey, this.appId);
assertEquals(pc.encrypt(this.randomStr, this.replyMsg2), this.afterAesEncrypt2);
} }
public void testValidateSignatureError() throws ParserConfigurationException, SAXException, public void testValidateSignatureError() throws ParserConfigurationException, SAXException,
IOException { IOException {
try { try {
WxCryptUtil pc = new WxCryptUtil(token, encodingAesKey, appId);
String afterEncrpt = pc.encrypt(replyMsg);
WxCryptUtil pc = new WxCryptUtil(this.token, this.encodingAesKey, this.appId);
String afterEncrpt = pc.encrypt(this.replyMsg);
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder(); DocumentBuilder db = dbf.newDocumentBuilder();
StringReader sr = new StringReader(afterEncrpt); StringReader sr = new StringReader(afterEncrpt);
@@ -91,8 +91,8 @@ public class WxCryptUtilTest {
NodeList nodelist1 = root.getElementsByTagName("Encrypt"); NodeList nodelist1 = root.getElementsByTagName("Encrypt");
String encrypt = nodelist1.item(0).getTextContent(); String encrypt = nodelist1.item(0).getTextContent();
String fromXML = String.format(xmlFormat, encrypt);
pc.decrypt("12345", timestamp, nonce, fromXML); // 这里签名错误
String fromXML = String.format(this.xmlFormat, encrypt);
pc.decrypt("12345", this.timestamp, this.nonce, fromXML); // 这里签名错误
} catch (RuntimeException e) { } catch (RuntimeException e) {
assertEquals(e.getMessage(), "加密消息签名校验失败"); assertEquals(e.getMessage(), "加密消息签名校验失败");
return; return;


+ 1
- 1
weixin-java-cp/pom.xml View File

@@ -6,7 +6,7 @@
<parent> <parent>
<groupId>com.github.binarywang</groupId> <groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-parent</artifactId> <artifactId>weixin-java-parent</artifactId>
<version>2.1.0</version>
<version>2.2.0</version>
</parent> </parent>


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


+ 4
- 4
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpConfigStorage.java View File

@@ -55,13 +55,13 @@ public interface WxCpConfigStorage {


String getOauth2redirectUri(); String getOauth2redirectUri();


String getHttp_proxy_host();
String getHttpProxyHost();


int getHttp_proxy_port();
int getHttpProxyPort();


String getHttp_proxy_username();
String getHttpProxyUsername();


String getHttp_proxy_password();
String getHttpProxyPassword();


File getTmpDirFile(); File getTmpDirFile();




+ 50
- 43
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpInMemoryConfigStorage.java View File

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


import java.io.File;

import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import me.chanjar.weixin.common.bean.WxAccessToken; import me.chanjar.weixin.common.bean.WxAccessToken;
import me.chanjar.weixin.common.util.http.ApacheHttpClientBuilder; import me.chanjar.weixin.common.util.http.ApacheHttpClientBuilder;


import java.io.File;

/** /**
* 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化 * 基于内存的微信配置provider,在实际生产环境中应该将这些配置持久化
* *
@@ -23,10 +26,10 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage {


protected volatile String oauth2redirectUri; protected volatile String oauth2redirectUri;


protected volatile String http_proxy_host;
protected volatile int http_proxy_port;
protected volatile String http_proxy_username;
protected volatile String http_proxy_password;
protected volatile String httpProxyHost;
protected volatile int httpProxyPort;
protected volatile String httpProxyUsername;
protected volatile String httpProxyPassword;


protected volatile String jsapiTicket; protected volatile String jsapiTicket;
protected volatile long jsapiTicketExpiresTime; protected volatile long jsapiTicketExpiresTime;
@@ -35,6 +38,7 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage {


private volatile ApacheHttpClientBuilder apacheHttpClientBuilder; private volatile ApacheHttpClientBuilder apacheHttpClientBuilder;


@Override
public String getAccessToken() { public String getAccessToken() {
return this.accessToken; return this.accessToken;
} }
@@ -43,18 +47,22 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage {
this.accessToken = accessToken; this.accessToken = accessToken;
} }


@Override
public boolean isAccessTokenExpired() { public boolean isAccessTokenExpired() {
return System.currentTimeMillis() > this.expiresTime; return System.currentTimeMillis() > this.expiresTime;
} }


@Override
public void expireAccessToken() { public void expireAccessToken() {
this.expiresTime = 0; this.expiresTime = 0;
} }


@Override
public synchronized void updateAccessToken(WxAccessToken accessToken) { public synchronized void updateAccessToken(WxAccessToken accessToken) {
updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn()); updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn());
} }


@Override
public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) { public synchronized void updateAccessToken(String accessToken, int expiresInSeconds) {
this.accessToken = accessToken; this.accessToken = accessToken;
this.expiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000l; this.expiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000l;
@@ -62,7 +70,7 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage {


@Override @Override
public String getJsapiTicket() { public String getJsapiTicket() {
return jsapiTicket;
return this.jsapiTicket;
} }


public void setJsapiTicket(String jsapiTicket) { public void setJsapiTicket(String jsapiTicket) {
@@ -70,27 +78,31 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage {
} }


public long getJsapiTicketExpiresTime() { public long getJsapiTicketExpiresTime() {
return jsapiTicketExpiresTime;
return this.jsapiTicketExpiresTime;
} }


public void setJsapiTicketExpiresTime(long jsapiTicketExpiresTime) { public void setJsapiTicketExpiresTime(long jsapiTicketExpiresTime) {
this.jsapiTicketExpiresTime = jsapiTicketExpiresTime; this.jsapiTicketExpiresTime = jsapiTicketExpiresTime;
} }


@Override
public boolean isJsapiTicketExpired() { public boolean isJsapiTicketExpired() {
return System.currentTimeMillis() > this.jsapiTicketExpiresTime; return System.currentTimeMillis() > this.jsapiTicketExpiresTime;
} }


@Override
public synchronized void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) { public synchronized void updateJsapiTicket(String jsapiTicket, int expiresInSeconds) {
this.jsapiTicket = jsapiTicket; this.jsapiTicket = jsapiTicket;
// 预留200秒的时间 // 预留200秒的时间
this.jsapiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000l; this.jsapiTicketExpiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000l;
} }


@Override
public void expireJsapiTicket() { public void expireJsapiTicket() {
this.jsapiTicketExpiresTime = 0; this.jsapiTicketExpiresTime = 0;
} }


@Override
public String getCorpId() { public String getCorpId() {
return this.corpId; return this.corpId;
} }
@@ -99,6 +111,7 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage {
this.corpId = corpId; this.corpId = corpId;
} }


@Override
public String getCorpSecret() { public String getCorpSecret() {
return this.corpSecret; return this.corpSecret;
} }
@@ -107,6 +120,7 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage {
this.corpSecret = corpSecret; this.corpSecret = corpSecret;
} }


@Override
public String getToken() { public String getToken() {
return this.token; return this.token;
} }
@@ -115,6 +129,7 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage {
this.token = token; this.token = token;
} }


@Override
public long getExpiresTime() { public long getExpiresTime() {
return this.expiresTime; return this.expiresTime;
} }
@@ -123,16 +138,18 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage {
this.expiresTime = expiresTime; this.expiresTime = expiresTime;
} }


@Override
public String getAesKey() { public String getAesKey() {
return aesKey;
return this.aesKey;
} }


public void setAesKey(String aesKey) { public void setAesKey(String aesKey) {
this.aesKey = aesKey; this.aesKey = aesKey;
} }


@Override
public String getAgentId() { public String getAgentId() {
return agentId;
return this.agentId;
} }


public void setAgentId(String agentId) { public void setAgentId(String agentId) {
@@ -148,60 +165,50 @@ public class WxCpInMemoryConfigStorage implements WxCpConfigStorage {
this.oauth2redirectUri = oauth2redirectUri; this.oauth2redirectUri = oauth2redirectUri;
} }


public String getHttp_proxy_host() {
return http_proxy_host;
@Override
public String getHttpProxyHost() {
return this.httpProxyHost;
} }


public void setHttp_proxy_host(String http_proxy_host) {
this.http_proxy_host = http_proxy_host;
public void setHttpProxyHost(String httpProxyHost) {
this.httpProxyHost = httpProxyHost;
} }


public int getHttp_proxy_port() {
return http_proxy_port;
@Override
public int getHttpProxyPort() {
return this.httpProxyPort;
} }


public void setHttp_proxy_port(int http_proxy_port) {
this.http_proxy_port = http_proxy_port;
public void setHttpProxyPort(int httpProxyPort) {
this.httpProxyPort = httpProxyPort;
} }


public String getHttp_proxy_username() {
return http_proxy_username;
@Override
public String getHttpProxyUsername() {
return this.httpProxyUsername;
} }


public void setHttp_proxy_username(String http_proxy_username) {
this.http_proxy_username = http_proxy_username;
public void setHttpProxyUsername(String httpProxyUsername) {
this.httpProxyUsername = httpProxyUsername;
} }


public String getHttp_proxy_password() {
return http_proxy_password;
@Override
public String getHttpProxyPassword() {
return this.httpProxyPassword;
} }


public void setHttp_proxy_password(String http_proxy_password) {
this.http_proxy_password = http_proxy_password;
public void setHttpProxyPassword(String httpProxyPassword) {
this.httpProxyPassword = httpProxyPassword;
} }


@Override @Override
public String toString() { public String toString() {
return "WxCpInMemoryConfigStorage{" +
"corpId='" + corpId + '\'' +
", corpSecret='" + corpSecret + '\'' +
", token='" + token + '\'' +
", accessToken='" + accessToken + '\'' +
", aesKey='" + aesKey + '\'' +
", agentId='" + agentId + '\'' +
", expiresTime=" + expiresTime +
", http_proxy_host='" + http_proxy_host + '\'' +
", http_proxy_port=" + http_proxy_port +
", http_proxy_username='" + http_proxy_username + '\'' +
", http_proxy_password='" + http_proxy_password + '\'' +
", jsapiTicket='" + jsapiTicket + '\'' +
", jsapiTicketExpiresTime='" + jsapiTicketExpiresTime + '\'' +
", tmpDirFile='" + tmpDirFile + '\'' +
'}';
return ToStringBuilder.reflectionToString(this, ToStringStyle.JSON_STYLE);
} }


@Override
public File getTmpDirFile() { public File getTmpDirFile() {
return tmpDirFile;
return this.tmpDirFile;
} }


public void setTmpDirFile(File tmpDirFile) { public void setTmpDirFile(File tmpDirFile) {


+ 20
- 20
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpJedisConfigStorage.java View File

@@ -29,10 +29,10 @@ public class WxCpJedisConfigStorage implements WxCpConfigStorage {
private volatile String oauth2redirectUri; private volatile String oauth2redirectUri;
private volatile String http_proxy_host;
private volatile int http_proxy_port;
private volatile String http_proxy_username;
private volatile String http_proxy_password;
private volatile String httpProxyHost;
private volatile int httpProxyPort;
private volatile String httpProxyUsername;
private volatile String httpProxyPassword;
private volatile File tmpDirFile; private volatile File tmpDirFile;
@@ -185,23 +185,23 @@ public class WxCpJedisConfigStorage implements WxCpConfigStorage {
} }
@Override @Override
public String getHttp_proxy_host() {
return this.http_proxy_host;
public String getHttpProxyHost() {
return this.httpProxyHost;
} }
@Override @Override
public int getHttp_proxy_port() {
return this.http_proxy_port;
public int getHttpProxyPort() {
return this.httpProxyPort;
} }
@Override @Override
public String getHttp_proxy_username() {
return this.http_proxy_username;
public String getHttpProxyUsername() {
return this.httpProxyUsername;
} }
@Override @Override
public String getHttp_proxy_password() {
return this.http_proxy_password;
public String getHttpProxyPassword() {
return this.httpProxyPassword;
} }
@Override @Override
@@ -240,20 +240,20 @@ public class WxCpJedisConfigStorage implements WxCpConfigStorage {
this.oauth2redirectUri = oauth2redirectUri; this.oauth2redirectUri = oauth2redirectUri;
} }
public void setHttp_proxy_host(String http_proxy_host) {
this.http_proxy_host = http_proxy_host;
public void setHttpProxyHost(String httpProxyHost) {
this.httpProxyHost = httpProxyHost;
} }
public void setHttp_proxy_port(int http_proxy_port) {
this.http_proxy_port = http_proxy_port;
public void setHttpProxyPort(int httpProxyPort) {
this.httpProxyPort = httpProxyPort;
} }
public void setHttp_proxy_username(String http_proxy_username) {
this.http_proxy_username = http_proxy_username;
public void setHttpProxyUsername(String httpProxyUsername) {
this.httpProxyUsername = httpProxyUsername;
} }
public void setHttp_proxy_password(String http_proxy_password) {
this.http_proxy_password = http_proxy_password;
public void setHttpProxyPassword(String httpProxyPassword) {
this.httpProxyPassword = httpProxyPassword;
} }
public void setTmpDirFile(File tmpDirFile) { public void setTmpDirFile(File tmpDirFile) {


+ 15
- 14
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageRouter.java View File

@@ -52,7 +52,7 @@ public class WxCpMessageRouter {


private static final int DEFAULT_THREAD_POOL_SIZE = 100; private static final int DEFAULT_THREAD_POOL_SIZE = 100;
protected final Logger log = LoggerFactory.getLogger(WxCpMessageRouter.class); protected final Logger log = LoggerFactory.getLogger(WxCpMessageRouter.class);
private final List<WxCpMessageRouterRule> rules = new ArrayList<WxCpMessageRouterRule>();
private final List<WxCpMessageRouterRule> rules = new ArrayList<>();


private final WxCpService wxCpService; private final WxCpService wxCpService;


@@ -142,9 +142,9 @@ public class WxCpMessageRouter {
return null; return null;
} }


final List<WxCpMessageRouterRule> matchRules = new ArrayList<WxCpMessageRouterRule>();
final List<WxCpMessageRouterRule> matchRules = new ArrayList<>();
// 收集匹配的规则 // 收集匹配的规则
for (final WxCpMessageRouterRule rule : rules) {
for (final WxCpMessageRouterRule rule : this.rules) {
if (rule.test(wxMessage)) { if (rule.test(wxMessage)) {
matchRules.add(rule); matchRules.add(rule);
if (!rule.isReEnter()) { if (!rule.isReEnter()) {
@@ -158,39 +158,40 @@ public class WxCpMessageRouter {
} }


WxCpXmlOutMessage res = null; WxCpXmlOutMessage res = null;
final List<Future> futures = new ArrayList<Future>();
final List<Future> futures = new ArrayList<>();
for (final WxCpMessageRouterRule rule : matchRules) { for (final WxCpMessageRouterRule rule : matchRules) {
// 返回最后一个非异步的rule的执行结果 // 返回最后一个非异步的rule的执行结果
if (rule.isAsync()) { if (rule.isAsync()) {
futures.add( futures.add(
executorService.submit(new Runnable() {
this.executorService.submit(new Runnable() {
@Override
public void run() { public void run() {
rule.service(wxMessage, wxCpService, sessionManager, exceptionHandler);
rule.service(wxMessage, WxCpMessageRouter.this.wxCpService, WxCpMessageRouter.this.sessionManager, WxCpMessageRouter.this.exceptionHandler);
} }
}) })
); );
} else { } else {
res = rule.service(wxMessage, wxCpService, sessionManager, exceptionHandler);
res = rule.service(wxMessage, this.wxCpService, this.sessionManager, this.exceptionHandler);
// 在同步操作结束,session访问结束 // 在同步操作结束,session访问结束
log.debug("End session access: async=false, sessionId={}", wxMessage.getFromUserName());
this.log.debug("End session access: async=false, sessionId={}", wxMessage.getFromUserName());
sessionEndAccess(wxMessage); sessionEndAccess(wxMessage);
} }
} }


if (futures.size() > 0) { if (futures.size() > 0) {
executorService.submit(new Runnable() {
this.executorService.submit(new Runnable() {
@Override @Override
public void run() { public void run() {
for (Future future : futures) { for (Future future : futures) {
try { try {
future.get(); future.get();
log.debug("End session access: async=true, sessionId={}", wxMessage.getFromUserName());
WxCpMessageRouter.this.log.debug("End session access: async=true, sessionId={}", wxMessage.getFromUserName());
// 异步操作结束,session访问结束 // 异步操作结束,session访问结束
sessionEndAccess(wxMessage); sessionEndAccess(wxMessage);
} catch (InterruptedException e) { } catch (InterruptedException e) {
log.error("Error happened when wait task finish", e);
WxCpMessageRouter.this.log.error("Error happened when wait task finish", e);
} catch (ExecutionException e) { } catch (ExecutionException e) {
log.error("Error happened when wait task finish", e);
WxCpMessageRouter.this.log.error("Error happened when wait task finish", e);
} }
} }
} }
@@ -213,7 +214,7 @@ public class WxCpMessageRouter {
messageId = String.valueOf(wxMessage.getMsgId()); messageId = String.valueOf(wxMessage.getMsgId());
} }


return messageDuplicateChecker.isDuplicate(messageId);
return this.messageDuplicateChecker.isDuplicate(messageId);


} }


@@ -224,7 +225,7 @@ public class WxCpMessageRouter {
*/ */
protected void sessionEndAccess(WxCpXmlMessage wxMessage) { protected void sessionEndAccess(WxCpXmlMessage wxMessage) {


InternalSession session = ((InternalSessionManager) sessionManager).findSession(wxMessage.getFromUserName());
InternalSession session = ((InternalSessionManager) this.sessionManager).findSession(wxMessage.getFromUserName());
if (session != null) { if (session != null) {
session.endAccess(); session.endAccess();
} }


+ 5
- 5
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpMessageRouterRule.java View File

@@ -36,9 +36,9 @@ public class WxCpMessageRouterRule {


private Integer agentId; private Integer agentId;


private List<WxCpMessageHandler> handlers = new ArrayList<WxCpMessageHandler>();
private List<WxCpMessageHandler> handlers = new ArrayList<>();


private List<WxCpMessageInterceptor> interceptors = new ArrayList<WxCpMessageInterceptor>();
private List<WxCpMessageInterceptor> interceptors = new ArrayList<>();


protected WxCpMessageRouterRule(WxCpMessageRouter routerBuilder) { protected WxCpMessageRouterRule(WxCpMessageRouter routerBuilder) {
this.routerBuilder = routerBuilder; this.routerBuilder = routerBuilder;
@@ -235,7 +235,7 @@ public class WxCpMessageRouterRule {


try { try {


Map<String, Object> context = new HashMap<String, Object>();
Map<String, Object> context = new HashMap<>();
// 如果拦截器不通过 // 如果拦截器不通过
for (WxCpMessageInterceptor interceptor : this.interceptors) { for (WxCpMessageInterceptor interceptor : this.interceptors) {
if (!interceptor.intercept(wxMessage, context, wxCpService, sessionManager)) { if (!interceptor.intercept(wxMessage, context, wxCpService, sessionManager)) {
@@ -300,7 +300,7 @@ public class WxCpMessageRouterRule {
} }


public boolean isAsync() { public boolean isAsync() {
return async;
return this.async;
} }


public void setAsync(boolean async) { public void setAsync(boolean async) {
@@ -308,7 +308,7 @@ public class WxCpMessageRouterRule {
} }


public boolean isReEnter() { public boolean isReEnter() {
return reEnter;
return this.reEnter;
} }


public void setReEnter(boolean reEnter) { public void setReEnter(boolean reEnter) {


+ 134
- 97
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/api/WxCpServiceImpl.java View File

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


import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.UUID;

import org.apache.http.HttpHost;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.CloseableHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.gson.JsonArray; import com.google.gson.JsonArray;
import com.google.gson.JsonElement; import com.google.gson.JsonElement;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.google.gson.JsonPrimitive; import com.google.gson.JsonPrimitive;
import com.google.gson.internal.Streams;
import com.google.gson.reflect.TypeToken; import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import me.chanjar.weixin.common.bean.WxAccessToken; import me.chanjar.weixin.common.bean.WxAccessToken;
import me.chanjar.weixin.common.bean.WxJsapiSignature; import me.chanjar.weixin.common.bean.WxJsapiSignature;
import me.chanjar.weixin.common.bean.menu.WxMenu; import me.chanjar.weixin.common.bean.menu.WxMenu;
@@ -20,30 +36,20 @@ import me.chanjar.weixin.common.util.RandomUtils;
import me.chanjar.weixin.common.util.StringUtils; import me.chanjar.weixin.common.util.StringUtils;
import me.chanjar.weixin.common.util.crypto.SHA1; import me.chanjar.weixin.common.util.crypto.SHA1;
import me.chanjar.weixin.common.util.fs.FileUtils; import me.chanjar.weixin.common.util.fs.FileUtils;
import me.chanjar.weixin.common.util.http.*;
import me.chanjar.weixin.common.util.http.ApacheHttpClientBuilder;
import me.chanjar.weixin.common.util.http.DefaultApacheHttpClientBuilder;
import me.chanjar.weixin.common.util.http.MediaDownloadRequestExecutor;
import me.chanjar.weixin.common.util.http.MediaUploadRequestExecutor;
import me.chanjar.weixin.common.util.http.RequestExecutor;
import me.chanjar.weixin.common.util.http.SimpleGetRequestExecutor;
import me.chanjar.weixin.common.util.http.SimplePostRequestExecutor;
import me.chanjar.weixin.common.util.http.URIUtil;
import me.chanjar.weixin.common.util.json.GsonHelper; import me.chanjar.weixin.common.util.json.GsonHelper;
import me.chanjar.weixin.cp.bean.WxCpDepart; import me.chanjar.weixin.cp.bean.WxCpDepart;
import me.chanjar.weixin.cp.bean.WxCpMessage; import me.chanjar.weixin.cp.bean.WxCpMessage;
import me.chanjar.weixin.cp.bean.WxCpTag; import me.chanjar.weixin.cp.bean.WxCpTag;
import me.chanjar.weixin.cp.bean.WxCpUser; import me.chanjar.weixin.cp.bean.WxCpUser;
import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder; import me.chanjar.weixin.cp.util.json.WxCpGsonBuilder;
import org.apache.http.HttpHost;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.CloseableHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.security.NoSuchAlgorithmException;
import java.util.List;
import java.util.UUID;


public class WxCpServiceImpl implements WxCpService { public class WxCpServiceImpl implements WxCpService {


@@ -59,7 +65,7 @@ public class WxCpServiceImpl implements WxCpService {
*/ */
protected final Object globalJsapiTicketRefreshLock = new Object(); protected final Object globalJsapiTicketRefreshLock = new Object();


protected WxCpConfigStorage wxCpConfigStorage;
protected WxCpConfigStorage configStorage;


protected CloseableHttpClient httpClient; protected CloseableHttpClient httpClient;


@@ -72,42 +78,48 @@ public class WxCpServiceImpl implements WxCpService {
private int retrySleepMillis = 1000; private int retrySleepMillis = 1000;
private int maxRetryTimes = 5; private int maxRetryTimes = 5;


@Override
public boolean checkSignature(String msgSignature, String timestamp, String nonce, String data) { public boolean checkSignature(String msgSignature, String timestamp, String nonce, String data) {
try { try {
return SHA1.gen(wxCpConfigStorage.getToken(), timestamp, nonce, data).equals(msgSignature);
return SHA1.gen(this.configStorage.getToken(), timestamp, nonce, data)
.equals(msgSignature);
} catch (Exception e) { } catch (Exception e) {
return false; return false;
} }
} }


@Override
public void userAuthenticated(String userId) throws WxErrorException { public void userAuthenticated(String userId) throws WxErrorException {
String url = "https://qyapi.weixin.qq.com/cgi-bin/user/authsucc?userid=" + userId; String url = "https://qyapi.weixin.qq.com/cgi-bin/user/authsucc?userid=" + userId;
get(url, null); get(url, null);
} }


@Override
public String getAccessToken() throws WxErrorException { public String getAccessToken() throws WxErrorException {
return getAccessToken(false); return getAccessToken(false);
} }


@Override
public String getAccessToken(boolean forceRefresh) throws WxErrorException { public String getAccessToken(boolean forceRefresh) throws WxErrorException {
if (forceRefresh) { if (forceRefresh) {
wxCpConfigStorage.expireAccessToken();
this.configStorage.expireAccessToken();
} }
if (wxCpConfigStorage.isAccessTokenExpired()) {
synchronized (globalAccessTokenRefreshLock) {
if (wxCpConfigStorage.isAccessTokenExpired()) {
if (this.configStorage.isAccessTokenExpired()) {
synchronized (this.globalAccessTokenRefreshLock) {
if (this.configStorage.isAccessTokenExpired()) {
String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?" String url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken?"
+ "&corpid=" + wxCpConfigStorage.getCorpId()
+ "&corpsecret=" + wxCpConfigStorage.getCorpSecret();
+ "&corpid=" + this.configStorage.getCorpId()
+ "&corpsecret=" + this.configStorage.getCorpSecret();
try { try {
HttpGet httpGet = new HttpGet(url); HttpGet httpGet = new HttpGet(url);
if (httpProxy != null) {
RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build();
if (this.httpProxy != null) {
RequestConfig config = RequestConfig.custom()
.setProxy(this.httpProxy).build();
httpGet.setConfig(config); httpGet.setConfig(config);
} }
CloseableHttpClient httpclient = getHttpclient();
String resultContent = null; String resultContent = null;
try (CloseableHttpResponse response = httpclient.execute(httpGet)) {
try (CloseableHttpClient httpclient = getHttpclient();
CloseableHttpResponse response = httpclient.execute(httpGet)) {
resultContent = new BasicResponseHandler().handleResponse(response); resultContent = new BasicResponseHandler().handleResponse(response);
} finally { } finally {
httpGet.releaseConnection(); httpGet.releaseConnection();
@@ -117,7 +129,8 @@ public class WxCpServiceImpl implements WxCpService {
throw new WxErrorException(error); throw new WxErrorException(error);
} }
WxAccessToken accessToken = WxAccessToken.fromJson(resultContent); WxAccessToken accessToken = WxAccessToken.fromJson(resultContent);
wxCpConfigStorage.updateAccessToken(accessToken.getAccessToken(), accessToken.getExpiresIn());
this.configStorage.updateAccessToken(
accessToken.getAccessToken(), accessToken.getExpiresIn());
} catch (ClientProtocolException e) { } catch (ClientProtocolException e) {
throw new RuntimeException(e); throw new RuntimeException(e);
} catch (IOException e) { } catch (IOException e) {
@@ -126,59 +139,60 @@ public class WxCpServiceImpl implements WxCpService {
} }
} }
} }
return wxCpConfigStorage.getAccessToken();
return this.configStorage.getAccessToken();
} }


@Override
public String getJsapiTicket() throws WxErrorException { public String getJsapiTicket() throws WxErrorException {
return getJsapiTicket(false); return getJsapiTicket(false);
} }


@Override
public String getJsapiTicket(boolean forceRefresh) throws WxErrorException { public String getJsapiTicket(boolean forceRefresh) throws WxErrorException {
if (forceRefresh) { if (forceRefresh) {
wxCpConfigStorage.expireJsapiTicket();
this.configStorage.expireJsapiTicket();
} }
if (wxCpConfigStorage.isJsapiTicketExpired()) {
synchronized (globalJsapiTicketRefreshLock) {
if (wxCpConfigStorage.isJsapiTicketExpired()) {
if (this.configStorage.isJsapiTicketExpired()) {
synchronized (this.globalJsapiTicketRefreshLock) {
if (this.configStorage.isJsapiTicketExpired()) {
String url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket"; String url = "https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket";
String responseContent = execute(new SimpleGetRequestExecutor(), url, null); String responseContent = execute(new SimpleGetRequestExecutor(), url, null);
JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent)));
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject(); JsonObject tmpJsonObject = tmpJsonElement.getAsJsonObject();
String jsapiTicket = tmpJsonObject.get("ticket").getAsString(); String jsapiTicket = tmpJsonObject.get("ticket").getAsString();
int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt(); int expiresInSeconds = tmpJsonObject.get("expires_in").getAsInt();
wxCpConfigStorage.updateJsapiTicket(jsapiTicket, expiresInSeconds);
this.configStorage.updateJsapiTicket(jsapiTicket,
expiresInSeconds);
} }
} }
} }
return wxCpConfigStorage.getJsapiTicket();
return this.configStorage.getJsapiTicket();
} }


@Override
public WxJsapiSignature createJsapiSignature(String url) throws WxErrorException { public WxJsapiSignature createJsapiSignature(String url) throws WxErrorException {
long timestamp = System.currentTimeMillis() / 1000; long timestamp = System.currentTimeMillis() / 1000;
String noncestr = RandomUtils.getRandomStr(); String noncestr = RandomUtils.getRandomStr();
String jsapiTicket = getJsapiTicket(false); String jsapiTicket = getJsapiTicket(false);
try {
String signature = SHA1.genWithAmple(
"jsapi_ticket=" + jsapiTicket,
"noncestr=" + noncestr,
"timestamp=" + timestamp,
"url=" + url
);
WxJsapiSignature jsapiSignature = new WxJsapiSignature();
jsapiSignature.setTimestamp(timestamp);
jsapiSignature.setNoncestr(noncestr);
jsapiSignature.setUrl(url);
jsapiSignature.setSignature(signature);
// Fixed bug
jsapiSignature.setAppid(this.wxCpConfigStorage.getCorpId());
return jsapiSignature;
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
String signature = SHA1.genWithAmple(
"jsapi_ticket=" + jsapiTicket,
"noncestr=" + noncestr,
"timestamp=" + timestamp,
"url=" + url
);
WxJsapiSignature jsapiSignature = new WxJsapiSignature();
jsapiSignature.setTimestamp(timestamp);
jsapiSignature.setNoncestr(noncestr);
jsapiSignature.setUrl(url);
jsapiSignature.setSignature(signature);
// Fixed bug
jsapiSignature.setAppid(this.configStorage.getCorpId());
return jsapiSignature;
} }


@Override
public void messageSend(WxCpMessage message) throws WxErrorException { public void messageSend(WxCpMessage message) throws WxErrorException {
String url = "https://qyapi.weixin.qq.com/cgi-bin/message/send"; String url = "https://qyapi.weixin.qq.com/cgi-bin/message/send";
post(url, message.toJson()); post(url, message.toJson());
@@ -186,18 +200,19 @@ public class WxCpServiceImpl implements WxCpService {


@Override @Override
public void menuCreate(WxMenu menu) throws WxErrorException { public void menuCreate(WxMenu menu) throws WxErrorException {
menuCreate(wxCpConfigStorage.getAgentId(), menu);
menuCreate(this.configStorage.getAgentId(), menu);
} }


@Override @Override
public void menuCreate(String agentId, WxMenu menu) throws WxErrorException { public void menuCreate(String agentId, WxMenu menu) throws WxErrorException {
String url = "https://qyapi.weixin.qq.com/cgi-bin/menu/create?agentid=" + wxCpConfigStorage.getAgentId();
String url = "https://qyapi.weixin.qq.com/cgi-bin/menu/create?agentid="
+ this.configStorage.getAgentId();
post(url, menu.toJson()); post(url, menu.toJson());
} }


@Override @Override
public void menuDelete() throws WxErrorException { public void menuDelete() throws WxErrorException {
menuDelete(wxCpConfigStorage.getAgentId());
menuDelete(this.configStorage.getAgentId());
} }


@Override @Override
@@ -208,7 +223,7 @@ public class WxCpServiceImpl implements WxCpService {


@Override @Override
public WxMenu menuGet() throws WxErrorException { public WxMenu menuGet() throws WxErrorException {
return menuGet(wxCpConfigStorage.getAgentId());
return menuGet(this.configStorage.getAgentId());
} }


@Override @Override
@@ -226,42 +241,52 @@ public class WxCpServiceImpl implements WxCpService {
} }
} }


@Override
public WxMediaUploadResult mediaUpload(String mediaType, String fileType, InputStream inputStream) public WxMediaUploadResult mediaUpload(String mediaType, String fileType, InputStream inputStream)
throws WxErrorException, IOException { throws WxErrorException, IOException {
return mediaUpload(mediaType, FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType)); return mediaUpload(mediaType, FileUtils.createTmpFile(inputStream, UUID.randomUUID().toString(), fileType));
} }


@Override
public WxMediaUploadResult mediaUpload(String mediaType, File file) throws WxErrorException { public WxMediaUploadResult mediaUpload(String mediaType, File file) throws WxErrorException {
String url = "https://qyapi.weixin.qq.com/cgi-bin/media/upload?type=" + mediaType; String url = "https://qyapi.weixin.qq.com/cgi-bin/media/upload?type=" + mediaType;
return execute(new MediaUploadRequestExecutor(), url, file); return execute(new MediaUploadRequestExecutor(), url, file);
} }


@Override
public File mediaDownload(String media_id) throws WxErrorException { public File mediaDownload(String media_id) throws WxErrorException {
String url = "https://qyapi.weixin.qq.com/cgi-bin/media/get"; String url = "https://qyapi.weixin.qq.com/cgi-bin/media/get";
return execute(new MediaDownloadRequestExecutor(wxCpConfigStorage.getTmpDirFile()), url, "media_id=" + media_id);
return execute(
new MediaDownloadRequestExecutor(
this.configStorage.getTmpDirFile()),
url, "media_id=" + media_id);
} }




@Override
public Integer departCreate(WxCpDepart depart) throws WxErrorException { public Integer departCreate(WxCpDepart depart) throws WxErrorException {
String url = "https://qyapi.weixin.qq.com/cgi-bin/department/create"; String url = "https://qyapi.weixin.qq.com/cgi-bin/department/create";
String responseContent = execute( String responseContent = execute(
new SimplePostRequestExecutor(), new SimplePostRequestExecutor(),
url, url,
depart.toJson()); depart.toJson());
JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent)));
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return GsonHelper.getAsInteger(tmpJsonElement.getAsJsonObject().get("id")); return GsonHelper.getAsInteger(tmpJsonElement.getAsJsonObject().get("id"));
} }


@Override
public void departUpdate(WxCpDepart group) throws WxErrorException { public void departUpdate(WxCpDepart group) throws WxErrorException {
String url = "https://qyapi.weixin.qq.com/cgi-bin/department/update"; String url = "https://qyapi.weixin.qq.com/cgi-bin/department/update";
post(url, group.toJson()); post(url, group.toJson());
} }


@Override
public void departDelete(Integer departId) throws WxErrorException { public void departDelete(Integer departId) throws WxErrorException {
String url = "https://qyapi.weixin.qq.com/cgi-bin/department/delete?id=" + departId; String url = "https://qyapi.weixin.qq.com/cgi-bin/department/delete?id=" + departId;
get(url, null); get(url, null);
} }


@Override
public List<WxCpDepart> departGet() throws WxErrorException { public List<WxCpDepart> departGet() throws WxErrorException {
String url = "https://qyapi.weixin.qq.com/cgi-bin/department/list"; String url = "https://qyapi.weixin.qq.com/cgi-bin/department/list";
String responseContent = get(url, null); String responseContent = get(url, null);
@@ -269,7 +294,7 @@ public class WxCpServiceImpl implements WxCpService {
* 操蛋的微信API,创建时返回的是 { group : { id : ..., name : ...} } * 操蛋的微信API,创建时返回的是 { group : { id : ..., name : ...} }
* 查询时返回的是 { groups : [ { id : ..., name : ..., count : ... }, ... ] } * 查询时返回的是 { groups : [ { id : ..., name : ..., count : ... }, ... ] }
*/ */
JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent)));
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return WxCpGsonBuilder.INSTANCE.create() return WxCpGsonBuilder.INSTANCE.create()
.fromJson( .fromJson(
tmpJsonElement.getAsJsonObject().get("department"), tmpJsonElement.getAsJsonObject().get("department"),
@@ -329,7 +354,7 @@ public class WxCpServiceImpl implements WxCpService {
} }


String responseContent = get(url, params); String responseContent = get(url, params);
JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent)));
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return WxCpGsonBuilder.INSTANCE.create() return WxCpGsonBuilder.INSTANCE.create()
.fromJson( .fromJson(
tmpJsonElement.getAsJsonObject().get("userlist"), tmpJsonElement.getAsJsonObject().get("userlist"),
@@ -352,7 +377,7 @@ public class WxCpServiceImpl implements WxCpService {
} }


String responseContent = get(url, params); String responseContent = get(url, params);
JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent)));
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return WxCpGsonBuilder.INSTANCE.create() return WxCpGsonBuilder.INSTANCE.create()
.fromJson( .fromJson(
tmpJsonElement.getAsJsonObject().get("userlist"), tmpJsonElement.getAsJsonObject().get("userlist"),
@@ -367,7 +392,7 @@ public class WxCpServiceImpl implements WxCpService {
JsonObject o = new JsonObject(); JsonObject o = new JsonObject();
o.addProperty("tagname", tagName); o.addProperty("tagname", tagName);
String responseContent = post(url, o.toString()); String responseContent = post(url, o.toString());
JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent)));
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return tmpJsonElement.getAsJsonObject().get("tagid").getAsString(); return tmpJsonElement.getAsJsonObject().get("tagid").getAsString();
} }


@@ -390,7 +415,7 @@ public class WxCpServiceImpl implements WxCpService {
public List<WxCpTag> tagGet() throws WxErrorException { public List<WxCpTag> tagGet() throws WxErrorException {
String url = "https://qyapi.weixin.qq.com/cgi-bin/tag/list"; String url = "https://qyapi.weixin.qq.com/cgi-bin/tag/list";
String responseContent = get(url, null); String responseContent = get(url, null);
JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent)));
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return WxCpGsonBuilder.INSTANCE.create() return WxCpGsonBuilder.INSTANCE.create()
.fromJson( .fromJson(
tmpJsonElement.getAsJsonObject().get("taglist"), tmpJsonElement.getAsJsonObject().get("taglist"),
@@ -403,7 +428,7 @@ public class WxCpServiceImpl implements WxCpService {
public List<WxCpUser> tagGetUsers(String tagId) throws WxErrorException { public List<WxCpUser> tagGetUsers(String tagId) throws WxErrorException {
String url = "https://qyapi.weixin.qq.com/cgi-bin/tag/get?tagid=" + tagId; String url = "https://qyapi.weixin.qq.com/cgi-bin/tag/get?tagid=" + tagId;
String responseContent = get(url, null); String responseContent = get(url, null);
JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent)));
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return WxCpGsonBuilder.INSTANCE.create() return WxCpGsonBuilder.INSTANCE.create()
.fromJson( .fromJson(
tmpJsonElement.getAsJsonObject().get("userlist"), tmpJsonElement.getAsJsonObject().get("userlist"),
@@ -450,7 +475,7 @@ public class WxCpServiceImpl implements WxCpService {
@Override @Override
public String oauth2buildAuthorizationUrl(String state) { public String oauth2buildAuthorizationUrl(String state) {
return this.oauth2buildAuthorizationUrl( return this.oauth2buildAuthorizationUrl(
this.wxCpConfigStorage.getOauth2redirectUri(),
this.configStorage.getOauth2redirectUri(),
state state
); );
} }
@@ -458,7 +483,7 @@ public class WxCpServiceImpl implements WxCpService {
@Override @Override
public String oauth2buildAuthorizationUrl(String redirectUri, String state) { public String oauth2buildAuthorizationUrl(String redirectUri, String state) {
String url = "https://open.weixin.qq.com/connect/oauth2/authorize?"; String url = "https://open.weixin.qq.com/connect/oauth2/authorize?";
url += "appid=" + wxCpConfigStorage.getCorpId();
url += "appid=" + this.configStorage.getCorpId();
url += "&redirect_uri=" + URIUtil.encodeURIComponent(redirectUri); url += "&redirect_uri=" + URIUtil.encodeURIComponent(redirectUri);
url += "&response_type=code"; url += "&response_type=code";
url += "&scope=snsapi_base"; url += "&scope=snsapi_base";
@@ -471,7 +496,7 @@ public class WxCpServiceImpl implements WxCpService {


@Override @Override
public String[] oauth2getUserInfo(String code) throws WxErrorException { public String[] oauth2getUserInfo(String code) throws WxErrorException {
return oauth2getUserInfo(wxCpConfigStorage.getAgentId(), code);
return oauth2getUserInfo(this.configStorage.getAgentId(), code);
} }


@Override @Override
@@ -480,7 +505,7 @@ public class WxCpServiceImpl implements WxCpService {
+ "code=" + code + "code=" + code
+ "&agendid=" + agentId; + "&agendid=" + agentId;
String responseText = get(url, null); String responseText = get(url, null);
JsonElement je = Streams.parse(new JsonReader(new StringReader(responseText)));
JsonElement je = new JsonParser().parse(responseText);
JsonObject jo = je.getAsJsonObject(); JsonObject jo = je.getAsJsonObject();
return new String[]{GsonHelper.getString(jo, "UserId"), GsonHelper.getString(jo, "DeviceId")}; return new String[]{GsonHelper.getString(jo, "UserId"), GsonHelper.getString(jo, "DeviceId")};
} }
@@ -494,7 +519,7 @@ public class WxCpServiceImpl implements WxCpService {
jsonObject.addProperty("invite_tips", inviteTips); jsonObject.addProperty("invite_tips", inviteTips);
} }
String responseContent = post(url, jsonObject.toString()); String responseContent = post(url, jsonObject.toString());
JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent)));
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
return tmpJsonElement.getAsJsonObject().get("type").getAsInt(); return tmpJsonElement.getAsJsonObject().get("type").getAsInt();
} }


@@ -502,7 +527,7 @@ public class WxCpServiceImpl implements WxCpService {
public String[] getCallbackIp() throws WxErrorException { public String[] getCallbackIp() throws WxErrorException {
String url = "https://qyapi.weixin.qq.com/cgi-bin/getcallbackip"; String url = "https://qyapi.weixin.qq.com/cgi-bin/getcallbackip";
String responseContent = get(url, null); String responseContent = get(url, null);
JsonElement tmpJsonElement = Streams.parse(new JsonReader(new StringReader(responseContent)));
JsonElement tmpJsonElement = new JsonParser().parse(responseContent);
JsonArray jsonArray = tmpJsonElement.getAsJsonObject().get("ip_list").getAsJsonArray(); JsonArray jsonArray = tmpJsonElement.getAsJsonObject().get("ip_list").getAsJsonArray();
String[] ips = new String[jsonArray.size()]; String[] ips = new String[jsonArray.size()];
for (int i = 0; i < jsonArray.size(); i++) { for (int i = 0; i < jsonArray.size(); i++) {
@@ -511,10 +536,12 @@ public class WxCpServiceImpl implements WxCpService {
return ips; return ips;
} }


@Override
public String get(String url, String queryParam) throws WxErrorException { public String get(String url, String queryParam) throws WxErrorException {
return execute(new SimpleGetRequestExecutor(), url, queryParam); return execute(new SimpleGetRequestExecutor(), url, queryParam);
} }


@Override
public String post(String url, String postData) throws WxErrorException { public String post(String url, String postData) throws WxErrorException {
return execute(new SimplePostRequestExecutor(), url, postData); return execute(new SimplePostRequestExecutor(), url, postData);
} }
@@ -522,6 +549,7 @@ public class WxCpServiceImpl implements WxCpService {
/** /**
* 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求 * 向微信端发送请求,在这里执行的策略是当发生access_token过期时才去刷新,然后重新执行请求,而不是全局定时请求
*/ */
@Override
public <T, E> T execute(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException { public <T, E> T execute(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException {
int retryTimes = 0; int retryTimes = 0;
do { do {
@@ -533,9 +561,10 @@ public class WxCpServiceImpl implements WxCpService {
* -1 系统繁忙, 1000ms后重试 * -1 系统繁忙, 1000ms后重试
*/ */
if (error.getErrorCode() == -1) { if (error.getErrorCode() == -1) {
int sleepMillis = retrySleepMillis * (1 << retryTimes);
int sleepMillis = this.retrySleepMillis * (1 << retryTimes);
try { try {
log.debug("微信系统繁忙,{}ms 后重试(第{}次)", sleepMillis, retryTimes + 1);
this.log.debug("微信系统繁忙,{}ms 后重试(第{}次)", sleepMillis,
retryTimes + 1);
Thread.sleep(sleepMillis); Thread.sleep(sleepMillis);
} catch (InterruptedException e1) { } catch (InterruptedException e1) {
throw new RuntimeException(e1); throw new RuntimeException(e1);
@@ -544,7 +573,7 @@ public class WxCpServiceImpl implements WxCpService {
throw e; throw e;
} }
} }
} while (++retryTimes < maxRetryTimes);
} while (++retryTimes < this.maxRetryTimes);


throw new RuntimeException("微信服务端异常,超出重试次数"); throw new RuntimeException("微信服务端异常,超出重试次数");
} }
@@ -559,7 +588,8 @@ public class WxCpServiceImpl implements WxCpService {
uriWithAccessToken += uri.indexOf('?') == -1 ? "?access_token=" + accessToken : "&access_token=" + accessToken; uriWithAccessToken += uri.indexOf('?') == -1 ? "?access_token=" + accessToken : "&access_token=" + accessToken;


try { try {
return executor.execute(getHttpclient(), httpProxy, uriWithAccessToken, data);
return executor.execute(getHttpclient(), this.httpProxy,
uriWithAccessToken, data);
} catch (WxErrorException e) { } catch (WxErrorException e) {
WxError error = e.getError(); WxError error = e.getError();
/* /*
@@ -569,7 +599,7 @@ public class WxCpServiceImpl implements WxCpService {
*/ */
if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001) { if (error.getErrorCode() == 42001 || error.getErrorCode() == 40001) {
// 强制设置wxCpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token // 强制设置wxCpConfigStorage它的access token过期了,这样在下一次请求里就会刷新access token
wxCpConfigStorage.expireAccessToken();
this.configStorage.expireAccessToken();
return execute(executor, uri, data); return execute(executor, uri, data);
} }
if (error.getErrorCode() != 0) { if (error.getErrorCode() != 0) {
@@ -584,21 +614,28 @@ public class WxCpServiceImpl implements WxCpService {
} }


protected CloseableHttpClient getHttpclient() { protected CloseableHttpClient getHttpclient() {
return httpClient;
return this.httpClient;
} }


@Override
public void setWxCpConfigStorage(WxCpConfigStorage wxConfigProvider) { public void setWxCpConfigStorage(WxCpConfigStorage wxConfigProvider) {
this.wxCpConfigStorage = wxConfigProvider;
ApacheHttpClientBuilder apacheHttpClientBuilder = wxCpConfigStorage.getApacheHttpClientBuilder();
this.configStorage = wxConfigProvider;
ApacheHttpClientBuilder apacheHttpClientBuilder = this.configStorage
.getApacheHttpClientBuilder();
if (null == apacheHttpClientBuilder) { if (null == apacheHttpClientBuilder) {
apacheHttpClientBuilder = DefaultApacheHttpClientBuilder.get(); apacheHttpClientBuilder = DefaultApacheHttpClientBuilder.get();
} }
apacheHttpClientBuilder.httpProxyHost(wxCpConfigStorage.getHttp_proxy_host())
.httpProxyPort(wxCpConfigStorage.getHttp_proxy_port())
.httpProxyUsername(wxCpConfigStorage.getHttp_proxy_username())
.httpProxyPassword(wxCpConfigStorage.getHttp_proxy_password());


httpClient = apacheHttpClientBuilder.build();
apacheHttpClientBuilder.httpProxyHost(this.configStorage.getHttpProxyHost())
.httpProxyPort(this.configStorage.getHttpProxyPort())
.httpProxyUsername(this.configStorage.getHttpProxyUsername())
.httpProxyPassword(this.configStorage.getHttpProxyPassword());

if (this.configStorage.getHttpProxyHost() != null && this.configStorage.getHttpProxyPort() > 0) {
this.httpProxy = new HttpHost(this.configStorage.getHttpProxyHost(), this.configStorage.getHttpProxyPort());
}

this.httpClient = apacheHttpClientBuilder.build();
} }


@Override @Override
@@ -614,18 +651,18 @@ public class WxCpServiceImpl implements WxCpService {


@Override @Override
public WxSession getSession(String id) { public WxSession getSession(String id) {
if (sessionManager == null) {
if (this.sessionManager == null) {
return null; return null;
} }
return sessionManager.getSession(id);
return this.sessionManager.getSession(id);
} }


@Override @Override
public WxSession getSession(String id, boolean create) { public WxSession getSession(String id, boolean create) {
if (sessionManager == null) {
if (this.sessionManager == null) {
return null; return null;
} }
return sessionManager.getSession(id, create);
return this.sessionManager.getSession(id, create);
} }




@@ -657,7 +694,7 @@ public class WxCpServiceImpl implements WxCpService {
} }


public File getTmpDirFile() { public File getTmpDirFile() {
return tmpDirFile;
return this.tmpDirFile;
} }


public void setTmpDirFile(File tmpDirFile) { public void setTmpDirFile(File tmpDirFile) {


+ 12
- 8
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpDepart.java View File

@@ -11,6 +11,10 @@ import java.io.Serializable;
*/ */
public class WxCpDepart implements Serializable { public class WxCpDepart implements Serializable {


/**
*
*/
private static final long serialVersionUID = -5028321625140879571L;
private Integer id; private Integer id;
private String name; private String name;
private Integer parentId; private Integer parentId;
@@ -21,7 +25,7 @@ public class WxCpDepart implements Serializable {
} }


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


public void setId(Integer id) { public void setId(Integer id) {
@@ -29,7 +33,7 @@ public class WxCpDepart implements Serializable {
} }


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


public void setName(String name) { public void setName(String name) {
@@ -37,7 +41,7 @@ public class WxCpDepart implements Serializable {
} }


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


public void setParentId(Integer parentId) { public void setParentId(Integer parentId) {
@@ -45,7 +49,7 @@ public class WxCpDepart implements Serializable {
} }


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


public void setOrder(Integer order) { public void setOrder(Integer order) {
@@ -59,10 +63,10 @@ public class WxCpDepart implements Serializable {
@Override @Override
public String toString() { public String toString() {
return "WxCpDepart{" + return "WxCpDepart{" +
"id=" + id +
", name='" + name + '\'' +
", parentId=" + parentId +
", order=" + order +
"id=" + this.id +
", name='" + this.name + '\'' +
", parentId=" + this.parentId +
", order=" + this.order +
'}'; '}';
} }
} }

+ 23
- 19
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpMessage.java View File

@@ -14,6 +14,10 @@ import java.util.List;
*/ */
public class WxCpMessage implements Serializable { public class WxCpMessage implements Serializable {


/**
*
*/
private static final long serialVersionUID = -2082278303476631708L;
private String toUser; private String toUser;
private String toParty; private String toParty;
private String toTag; private String toTag;
@@ -27,7 +31,7 @@ public class WxCpMessage implements Serializable {
private String musicUrl; private String musicUrl;
private String hqMusicUrl; private String hqMusicUrl;
private String safe; private String safe;
private List<WxArticle> articles = new ArrayList<WxArticle>();
private List<WxArticle> articles = new ArrayList<>();


/** /**
* 获得文本消息builder * 获得文本消息builder
@@ -72,7 +76,7 @@ public class WxCpMessage implements Serializable {
} }


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


public void setToUser(String toUser) { public void setToUser(String toUser) {
@@ -80,7 +84,7 @@ public class WxCpMessage implements Serializable {
} }


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


public void setToParty(String toParty) { public void setToParty(String toParty) {
@@ -88,7 +92,7 @@ public class WxCpMessage implements Serializable {
} }


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


public void setToTag(String toTag) { public void setToTag(String toTag) {
@@ -96,7 +100,7 @@ public class WxCpMessage implements Serializable {
} }


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


public void setAgentId(String agentId) { public void setAgentId(String agentId) {
@@ -104,7 +108,7 @@ public class WxCpMessage implements Serializable {
} }


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


/** /**
@@ -125,7 +129,7 @@ public class WxCpMessage implements Serializable {
} }


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


public void setSafe(String safe) { public void setSafe(String safe) {
@@ -133,7 +137,7 @@ public class WxCpMessage implements Serializable {
} }


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


public void setContent(String content) { public void setContent(String content) {
@@ -141,7 +145,7 @@ public class WxCpMessage implements Serializable {
} }


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


public void setMediaId(String mediaId) { public void setMediaId(String mediaId) {
@@ -149,7 +153,7 @@ public class WxCpMessage implements Serializable {
} }


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


public void setThumbMediaId(String thumbMediaId) { public void setThumbMediaId(String thumbMediaId) {
@@ -157,7 +161,7 @@ public class WxCpMessage implements Serializable {
} }


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


public void setTitle(String title) { public void setTitle(String title) {
@@ -165,7 +169,7 @@ public class WxCpMessage implements Serializable {
} }


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


public void setDescription(String description) { public void setDescription(String description) {
@@ -173,7 +177,7 @@ public class WxCpMessage implements Serializable {
} }


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


public void setMusicUrl(String musicUrl) { public void setMusicUrl(String musicUrl) {
@@ -181,7 +185,7 @@ public class WxCpMessage implements Serializable {
} }


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


public void setHqMusicUrl(String hqMusicUrl) { public void setHqMusicUrl(String hqMusicUrl) {
@@ -189,7 +193,7 @@ public class WxCpMessage implements Serializable {
} }


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


public void setArticles(List<WxArticle> articles) { public void setArticles(List<WxArticle> articles) {
@@ -208,7 +212,7 @@ public class WxCpMessage implements Serializable {
private String picUrl; private String picUrl;


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


public void setTitle(String title) { public void setTitle(String title) {
@@ -216,7 +220,7 @@ public class WxCpMessage implements Serializable {
} }


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


public void setDescription(String description) { public void setDescription(String description) {
@@ -224,7 +228,7 @@ public class WxCpMessage implements Serializable {
} }


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


public void setUrl(String url) { public void setUrl(String url) {
@@ -232,7 +236,7 @@ public class WxCpMessage implements Serializable {
} }


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


public void setPicUrl(String picUrl) { public void setPicUrl(String picUrl) {


+ 7
- 2
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpTag.java View File

@@ -9,6 +9,11 @@ import java.io.Serializable;
*/ */
public class WxCpTag implements Serializable { public class WxCpTag implements Serializable {


/**
*
*/
private static final long serialVersionUID = -7243320279646928402L;

private String id; private String id;


private String name; private String name;
@@ -28,7 +33,7 @@ public class WxCpTag implements Serializable {
} }


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


public void setName(String name) { public void setName(String name) {
@@ -36,7 +41,7 @@ public class WxCpTag implements Serializable {
} }


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


public void setId(String id) { public void setId(String id) {


+ 20
- 16
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpUser.java View File

@@ -13,7 +13,11 @@ import java.util.List;
*/ */
public class WxCpUser implements Serializable { public class WxCpUser implements Serializable {


private final List<Attr> extAttrs = new ArrayList<Attr>();
/**
*
*/
private static final long serialVersionUID = -5696099236344075582L;
private final List<Attr> extAttrs = new ArrayList<>();
private String userId; private String userId;
private String name; private String name;
private Integer[] departIds; private Integer[] departIds;
@@ -32,7 +36,7 @@ public class WxCpUser implements Serializable {
} }


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


public void setUserId(String userId) { public void setUserId(String userId) {
@@ -40,7 +44,7 @@ public class WxCpUser implements Serializable {
} }


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


public void setName(String name) { public void setName(String name) {
@@ -48,7 +52,7 @@ public class WxCpUser implements Serializable {
} }


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


public void setDepartIds(Integer[] departIds) { public void setDepartIds(Integer[] departIds) {
@@ -56,7 +60,7 @@ public class WxCpUser implements Serializable {
} }


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


public void setGender(String gender) { public void setGender(String gender) {
@@ -64,7 +68,7 @@ public class WxCpUser implements Serializable {
} }


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


public void setPosition(String position) { public void setPosition(String position) {
@@ -72,7 +76,7 @@ public class WxCpUser implements Serializable {
} }


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


public void setMobile(String mobile) { public void setMobile(String mobile) {
@@ -80,7 +84,7 @@ public class WxCpUser implements Serializable {
} }


public String getTel() { public String getTel() {
return tel;
return this.tel;
} }


public void setTel(String tel) { public void setTel(String tel) {
@@ -88,7 +92,7 @@ public class WxCpUser implements Serializable {
} }


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


public void setEmail(String email) { public void setEmail(String email) {
@@ -96,7 +100,7 @@ public class WxCpUser implements Serializable {
} }


public String getWeiXinId() { public String getWeiXinId() {
return weiXinId;
return this.weiXinId;
} }


public void setWeiXinId(String weiXinId) { public void setWeiXinId(String weiXinId) {
@@ -104,7 +108,7 @@ public class WxCpUser implements Serializable {
} }


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


public void setAvatar(String avatar) { public void setAvatar(String avatar) {
@@ -112,7 +116,7 @@ public class WxCpUser implements Serializable {
} }


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


public void setStatus(Integer status) { public void setStatus(Integer status) {
@@ -120,7 +124,7 @@ public class WxCpUser implements Serializable {
} }


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


public void setEnable(Integer enable) { public void setEnable(Integer enable) {
@@ -132,7 +136,7 @@ public class WxCpUser implements Serializable {
} }


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


public String toJson() { public String toJson() {
@@ -150,7 +154,7 @@ public class WxCpUser implements Serializable {
} }


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


public void setName(String name) { public void setName(String name) {
@@ -158,7 +162,7 @@ public class WxCpUser implements Serializable {
} }


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


public void setValue(String value) { public void setValue(String value) {


+ 83
- 78
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlMessage.java View File

@@ -32,6 +32,11 @@ public class WxCpXmlMessage implements Serializable {
// 以下都是微信推送过来的消息的xml的element所对应的属性 // 以下都是微信推送过来的消息的xml的element所对应的属性
/////////////////////// ///////////////////////


/**
*
*/
private static final long serialVersionUID = -1042994982179476410L;

@XStreamAlias("AgentID") @XStreamAlias("AgentID")
private Integer agentId; private Integer agentId;


@@ -200,7 +205,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setAgentId(Integer agentId) { public void setAgentId(Integer agentId) {
@@ -208,7 +213,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setToUserName(String toUserName) { public void setToUserName(String toUserName) {
@@ -216,7 +221,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setCreateTime(Long createTime) { public void setCreateTime(Long createTime) {
@@ -236,7 +241,7 @@ public class WxCpXmlMessage implements Serializable {
* </pre> * </pre>
*/ */
public String getMsgType() { public String getMsgType() {
return msgType;
return this.msgType;
} }


/** /**
@@ -256,7 +261,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setContent(String content) { public void setContent(String content) {
@@ -264,7 +269,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setMsgId(Long msgId) { public void setMsgId(Long msgId) {
@@ -272,7 +277,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setPicUrl(String picUrl) { public void setPicUrl(String picUrl) {
@@ -280,7 +285,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setMediaId(String mediaId) { public void setMediaId(String mediaId) {
@@ -288,7 +293,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setFormat(String format) { public void setFormat(String format) {
@@ -296,7 +301,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setThumbMediaId(String thumbMediaId) { public void setThumbMediaId(String thumbMediaId) {
@@ -304,7 +309,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setLocationX(Double locationX) { public void setLocationX(Double locationX) {
@@ -312,7 +317,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setLocationY(Double locationY) { public void setLocationY(Double locationY) {
@@ -320,7 +325,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setScale(Double scale) { public void setScale(Double scale) {
@@ -328,7 +333,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setLabel(String label) { public void setLabel(String label) {
@@ -336,7 +341,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setTitle(String title) { public void setTitle(String title) {
@@ -344,7 +349,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setDescription(String description) { public void setDescription(String description) {
@@ -352,7 +357,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setUrl(String url) { public void setUrl(String url) {
@@ -360,7 +365,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setEvent(String event) { public void setEvent(String event) {
@@ -368,7 +373,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setEventKey(String eventKey) { public void setEventKey(String eventKey) {
@@ -376,7 +381,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setTicket(String ticket) { public void setTicket(String ticket) {
@@ -384,7 +389,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setLatitude(Double latitude) { public void setLatitude(Double latitude) {
@@ -392,7 +397,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setLongitude(Double longitude) { public void setLongitude(Double longitude) {
@@ -400,7 +405,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setPrecision(Double precision) { public void setPrecision(Double precision) {
@@ -408,7 +413,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setRecognition(String recognition) { public void setRecognition(String recognition) {
@@ -416,7 +421,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setFromUserName(String fromUserName) { public void setFromUserName(String fromUserName) {
@@ -424,7 +429,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setStatus(String status) { public void setStatus(String status) {
@@ -432,7 +437,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setTotalCount(Integer totalCount) { public void setTotalCount(Integer totalCount) {
@@ -440,7 +445,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setFilterCount(Integer filterCount) { public void setFilterCount(Integer filterCount) {
@@ -448,7 +453,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setSentCount(Integer sentCount) { public void setSentCount(Integer sentCount) {
@@ -456,7 +461,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setErrorCount(Integer errorCount) { public void setErrorCount(Integer errorCount) {
@@ -464,7 +469,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setScanCodeInfo(WxCpXmlMessage.ScanCodeInfo scanCodeInfo) { public void setScanCodeInfo(WxCpXmlMessage.ScanCodeInfo scanCodeInfo) {
@@ -472,7 +477,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setSendPicsInfo(WxCpXmlMessage.SendPicsInfo sendPicsInfo) { public void setSendPicsInfo(WxCpXmlMessage.SendPicsInfo sendPicsInfo) {
@@ -480,7 +485,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setSendLocationInfo(WxCpXmlMessage.SendLocationInfo sendLocationInfo) { public void setSendLocationInfo(WxCpXmlMessage.SendLocationInfo sendLocationInfo) {
@@ -490,39 +495,39 @@ public class WxCpXmlMessage implements Serializable {
@Override @Override
public String toString() { public String toString() {
return "WxCpXmlMessage{" + return "WxCpXmlMessage{" +
"agentId=" + agentId +
", toUserName='" + toUserName + '\'' +
", fromUserName='" + fromUserName + '\'' +
", createTime=" + createTime +
", msgType='" + msgType + '\'' +
", content='" + content + '\'' +
", msgId=" + msgId +
", picUrl='" + picUrl + '\'' +
", mediaId='" + mediaId + '\'' +
", format='" + format + '\'' +
", thumbMediaId='" + thumbMediaId + '\'' +
", locationX=" + locationX +
", locationY=" + locationY +
", scale=" + scale +
", label='" + label + '\'' +
", title='" + title + '\'' +
", description='" + description + '\'' +
", url='" + url + '\'' +
", event='" + event + '\'' +
", eventKey='" + eventKey + '\'' +
", ticket='" + ticket + '\'' +
", latitude=" + latitude +
", longitude=" + longitude +
", precision=" + precision +
", recognition='" + recognition + '\'' +
", status='" + status + '\'' +
", totalCount=" + totalCount +
", filterCount=" + filterCount +
", sentCount=" + sentCount +
", errorCount=" + errorCount +
", scanCodeInfo=" + scanCodeInfo +
", sendPicsInfo=" + sendPicsInfo +
", sendLocationInfo=" + sendLocationInfo +
"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 +
'}'; '}';
} }


@@ -542,7 +547,7 @@ public class WxCpXmlMessage implements Serializable {
*/ */
public String getScanType() { public String getScanType() {


return scanType;
return this.scanType;
} }


public void setScanType(String scanType) { public void setScanType(String scanType) {
@@ -553,7 +558,7 @@ public class WxCpXmlMessage implements Serializable {
* 扫描结果,即二维码对应的字符串信息 * 扫描结果,即二维码对应的字符串信息
*/ */
public String getScanResult() { public String getScanResult() {
return scanResult;
return this.scanResult;
} }


public void setScanResult(String scanResult) { public void setScanResult(String scanResult) {
@@ -566,12 +571,12 @@ public class WxCpXmlMessage implements Serializable {
public static class SendPicsInfo { public static class SendPicsInfo {


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


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


public void setCount(Long count) { public void setCount(Long count) {
@@ -579,7 +584,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


@XStreamAlias("item") @XStreamAlias("item")
@@ -590,11 +595,11 @@ public class WxCpXmlMessage implements Serializable {
private String PicMd5Sum; private String PicMd5Sum;


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


public void setPicMd5Sum(String picMd5Sum) { public void setPicMd5Sum(String picMd5Sum) {
PicMd5Sum = picMd5Sum;
this.PicMd5Sum = picMd5Sum;
} }
} }
} }
@@ -623,7 +628,7 @@ public class WxCpXmlMessage implements Serializable {
private String poiname; private String poiname;


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


public void setLocationX(String locationX) { public void setLocationX(String locationX) {
@@ -631,7 +636,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setLocationY(String locationY) { public void setLocationY(String locationY) {
@@ -639,7 +644,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setScale(String scale) { public void setScale(String scale) {
@@ -647,7 +652,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setLabel(String label) { public void setLabel(String label) {
@@ -655,7 +660,7 @@ public class WxCpXmlMessage implements Serializable {
} }


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


public void setPoiname(String poiname) { public void setPoiname(String poiname) {


+ 1
- 1
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutImageMessage.java View File

@@ -17,7 +17,7 @@ public class WxCpXmlOutImageMessage extends WxCpXmlOutMessage {
} }


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


public void setMediaId(String mediaId) { public void setMediaId(String mediaId) {


+ 4
- 4
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutMessage.java View File

@@ -62,7 +62,7 @@ public abstract class WxCpXmlOutMessage {
} }


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


public void setToUserName(String toUserName) { public void setToUserName(String toUserName) {
@@ -70,7 +70,7 @@ public abstract class WxCpXmlOutMessage {
} }


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


public void setFromUserName(String fromUserName) { public void setFromUserName(String fromUserName) {
@@ -78,7 +78,7 @@ public abstract class WxCpXmlOutMessage {
} }


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


public void setCreateTime(Long createTime) { public void setCreateTime(Long createTime) {
@@ -86,7 +86,7 @@ public abstract class WxCpXmlOutMessage {
} }


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


public void setMsgType(String msgType) { public void setMsgType(String msgType) {


+ 11
- 11
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutNewsMessage.java View File

@@ -12,7 +12,7 @@ import java.util.List;
public class WxCpXmlOutNewsMessage extends WxCpXmlOutMessage { public class WxCpXmlOutNewsMessage extends WxCpXmlOutMessage {


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


@@ -21,7 +21,7 @@ public class WxCpXmlOutNewsMessage extends WxCpXmlOutMessage {
} }


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


public void addArticle(Item item) { public void addArticle(Item item) {
@@ -30,7 +30,7 @@ public class WxCpXmlOutNewsMessage extends WxCpXmlOutMessage {
} }


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




@@ -54,35 +54,35 @@ public class WxCpXmlOutNewsMessage extends WxCpXmlOutMessage {
private String Url; private String Url;


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


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


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


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


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


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


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


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


} }


+ 1
- 1
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutTextMessage.java View File

@@ -17,7 +17,7 @@ public class WxCpXmlOutTextMessage extends WxCpXmlOutMessage {
} }


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


public void setContent(String content) { public void setContent(String content) {


+ 9
- 9
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVideoMessage.java View File

@@ -16,27 +16,27 @@ public class WxCpXmlOutVideoMessage extends WxCpXmlOutMessage {
} }


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


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


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


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


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


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




@@ -56,7 +56,7 @@ public class WxCpXmlOutVideoMessage extends WxCpXmlOutMessage {
private String description; private String description;


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


public void setMediaId(String mediaId) { public void setMediaId(String mediaId) {
@@ -64,7 +64,7 @@ public class WxCpXmlOutVideoMessage extends WxCpXmlOutMessage {
} }


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


public void setTitle(String title) { public void setTitle(String title) {
@@ -72,7 +72,7 @@ public class WxCpXmlOutVideoMessage extends WxCpXmlOutMessage {
} }


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


public void setDescription(String description) { public void setDescription(String description) {


+ 1
- 1
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/WxCpXmlOutVoiceMessage.java View File

@@ -17,7 +17,7 @@ public class WxCpXmlOutVoiceMessage extends WxCpXmlOutMessage {
} }


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


public void setMediaId(String mediaId) { public void setMediaId(String mediaId) {


+ 1
- 0
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/FileBuilder.java View File

@@ -23,6 +23,7 @@ public final class FileBuilder extends BaseBuilder<FileBuilder> {
return this; return this;
} }


@Override
public WxCpMessage build() { public WxCpMessage build() {
WxCpMessage m = super.build(); WxCpMessage m = super.build();
m.setMediaId(this.mediaId); m.setMediaId(this.mediaId);


+ 1
- 0
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/ImageBuilder.java View File

@@ -23,6 +23,7 @@ public final class ImageBuilder extends BaseBuilder<ImageBuilder> {
return this; return this;
} }


@Override
public WxCpMessage build() { public WxCpMessage build() {
WxCpMessage m = super.build(); WxCpMessage m = super.build();
m.setMediaId(this.mediaId); m.setMediaId(this.mediaId);


+ 2
- 1
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/NewsBuilder.java View File

@@ -17,7 +17,7 @@ import java.util.List;
*/ */
public final class NewsBuilder extends BaseBuilder<NewsBuilder> { public final class NewsBuilder extends BaseBuilder<NewsBuilder> {


private List<WxCpMessage.WxArticle> articles = new ArrayList<WxCpMessage.WxArticle>();
private List<WxCpMessage.WxArticle> articles = new ArrayList<>();


public NewsBuilder() { public NewsBuilder() {
this.msgType = WxConsts.CUSTOM_MSG_NEWS; this.msgType = WxConsts.CUSTOM_MSG_NEWS;
@@ -28,6 +28,7 @@ public final class NewsBuilder extends BaseBuilder<NewsBuilder> {
return this; return this;
} }


@Override
public WxCpMessage build() { public WxCpMessage build() {
WxCpMessage m = super.build(); WxCpMessage m = super.build();
m.setArticles(this.articles); m.setArticles(this.articles);


+ 1
- 0
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/TextBuilder.java View File

@@ -23,6 +23,7 @@ public final class TextBuilder extends BaseBuilder<TextBuilder> {
return this; return this;
} }


@Override
public WxCpMessage build() { public WxCpMessage build() {
WxCpMessage m = super.build(); WxCpMessage m = super.build();
m.setContent(this.content); m.setContent(this.content);


+ 4
- 3
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VideoBuilder.java View File

@@ -47,12 +47,13 @@ public final class VideoBuilder extends BaseBuilder<VideoBuilder> {
return this; return this;
} }


@Override
public WxCpMessage build() { public WxCpMessage build() {
WxCpMessage m = super.build(); WxCpMessage m = super.build();
m.setMediaId(this.mediaId); m.setMediaId(this.mediaId);
m.setTitle(title);
m.setDescription(description);
m.setThumbMediaId(thumbMediaId);
m.setTitle(this.title);
m.setDescription(this.description);
m.setThumbMediaId(this.thumbMediaId);
return m; return m;
} }
} }

+ 1
- 0
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/messagebuilder/VoiceBuilder.java View File

@@ -23,6 +23,7 @@ public final class VoiceBuilder extends BaseBuilder<VoiceBuilder> {
return this; return this;
} }


@Override
public WxCpMessage build() { public WxCpMessage build() {
WxCpMessage m = super.build(); WxCpMessage m = super.build();
m.setMediaId(this.mediaId); m.setMediaId(this.mediaId);


+ 1
- 0
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/ImageBuilder.java View File

@@ -16,6 +16,7 @@ public final class ImageBuilder extends BaseBuilder<ImageBuilder, WxCpXmlOutImag
return this; return this;
} }


@Override
public WxCpXmlOutImageMessage build() { public WxCpXmlOutImageMessage build() {
WxCpXmlOutImageMessage m = new WxCpXmlOutImageMessage(); WxCpXmlOutImageMessage m = new WxCpXmlOutImageMessage();
setCommon(m); setCommon(m);


+ 3
- 2
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/NewsBuilder.java View File

@@ -13,16 +13,17 @@ import java.util.List;
*/ */
public final class NewsBuilder extends BaseBuilder<NewsBuilder, WxCpXmlOutNewsMessage> { public final class NewsBuilder extends BaseBuilder<NewsBuilder, WxCpXmlOutNewsMessage> {


protected final List<Item> articles = new ArrayList<Item>();
protected final List<Item> articles = new ArrayList<>();


public NewsBuilder addArticle(Item item) { public NewsBuilder addArticle(Item item) {
this.articles.add(item); this.articles.add(item);
return this; return this;
} }


@Override
public WxCpXmlOutNewsMessage build() { public WxCpXmlOutNewsMessage build() {
WxCpXmlOutNewsMessage m = new WxCpXmlOutNewsMessage(); WxCpXmlOutNewsMessage m = new WxCpXmlOutNewsMessage();
for (Item item : articles) {
for (Item item : this.articles) {
m.addArticle(item); m.addArticle(item);
} }
setCommon(m); setCommon(m);


+ 1
- 0
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/TextBuilder.java View File

@@ -15,6 +15,7 @@ public final class TextBuilder extends BaseBuilder<TextBuilder, WxCpXmlOutTextMe
return this; return this;
} }


@Override
public WxCpXmlOutTextMessage build() { public WxCpXmlOutTextMessage build() {
WxCpXmlOutTextMessage m = new WxCpXmlOutTextMessage(); WxCpXmlOutTextMessage m = new WxCpXmlOutTextMessage();
setCommon(m); setCommon(m);


+ 4
- 3
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/VideoBuilder.java View File

@@ -28,12 +28,13 @@ public final class VideoBuilder extends BaseBuilder<VideoBuilder, WxCpXmlOutVide
return this; return this;
} }


@Override
public WxCpXmlOutVideoMessage build() { public WxCpXmlOutVideoMessage build() {
WxCpXmlOutVideoMessage m = new WxCpXmlOutVideoMessage(); WxCpXmlOutVideoMessage m = new WxCpXmlOutVideoMessage();
setCommon(m); setCommon(m);
m.setTitle(title);
m.setDescription(description);
m.setMediaId(mediaId);
m.setTitle(this.title);
m.setDescription(this.description);
m.setMediaId(this.mediaId);
return m; return m;
} }




+ 2
- 1
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/bean/outxmlbuilder/VoiceBuilder.java View File

@@ -16,10 +16,11 @@ public final class VoiceBuilder extends BaseBuilder<VoiceBuilder, WxCpXmlOutVoic
return this; return this;
} }


@Override
public WxCpXmlOutVoiceMessage build() { public WxCpXmlOutVoiceMessage build() {
WxCpXmlOutVoiceMessage m = new WxCpXmlOutVoiceMessage(); WxCpXmlOutVoiceMessage m = new WxCpXmlOutVoiceMessage();
setCommon(m); setCommon(m);
m.setMediaId(mediaId);
m.setMediaId(this.mediaId);
return m; return m;
} }




+ 2
- 0
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpDepartGsonAdapter.java View File

@@ -19,6 +19,7 @@ import java.lang.reflect.Type;
*/ */
public class WxCpDepartGsonAdapter implements JsonSerializer<WxCpDepart>, JsonDeserializer<WxCpDepart> { public class WxCpDepartGsonAdapter implements JsonSerializer<WxCpDepart>, JsonDeserializer<WxCpDepart> {


@Override
public JsonElement serialize(WxCpDepart group, Type typeOfSrc, JsonSerializationContext context) { public JsonElement serialize(WxCpDepart group, Type typeOfSrc, JsonSerializationContext context) {
JsonObject json = new JsonObject(); JsonObject json = new JsonObject();
if (group.getId() != null) { if (group.getId() != null) {
@@ -36,6 +37,7 @@ public class WxCpDepartGsonAdapter implements JsonSerializer<WxCpDepart>, JsonDe
return json; return json;
} }


@Override
public WxCpDepart deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) public WxCpDepart deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException { throws JsonParseException {
WxCpDepart depart = new WxCpDepart(); WxCpDepart depart = new WxCpDepart();


+ 1
- 0
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpMessageGsonAdapter.java View File

@@ -20,6 +20,7 @@ import java.lang.reflect.Type;
*/ */
public class WxCpMessageGsonAdapter implements JsonSerializer<WxCpMessage> { public class WxCpMessageGsonAdapter implements JsonSerializer<WxCpMessage> {


@Override
public JsonElement serialize(WxCpMessage message, Type typeOfSrc, JsonSerializationContext context) { public JsonElement serialize(WxCpMessage message, Type typeOfSrc, JsonSerializationContext context) {
JsonObject messageJson = new JsonObject(); JsonObject messageJson = new JsonObject();
messageJson.addProperty("agentid", message.getAgentId()); messageJson.addProperty("agentid", message.getAgentId());


+ 2
- 0
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpTagGsonAdapter.java View File

@@ -19,6 +19,7 @@ import java.lang.reflect.Type;
*/ */
public class WxCpTagGsonAdapter implements JsonSerializer<WxCpTag>, JsonDeserializer<WxCpTag> { public class WxCpTagGsonAdapter implements JsonSerializer<WxCpTag>, JsonDeserializer<WxCpTag> {


@Override
public JsonElement serialize(WxCpTag tag, Type typeOfSrc, JsonSerializationContext context) { public JsonElement serialize(WxCpTag tag, Type typeOfSrc, JsonSerializationContext context) {
JsonObject o = new JsonObject(); JsonObject o = new JsonObject();
o.addProperty("tagid", tag.getId()); o.addProperty("tagid", tag.getId());
@@ -26,6 +27,7 @@ public class WxCpTagGsonAdapter implements JsonSerializer<WxCpTag>, JsonDeserial
return o; return o;
} }


@Override
public WxCpTag deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) public WxCpTag deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException { throws JsonParseException {
JsonObject jsonObject = json.getAsJsonObject(); JsonObject jsonObject = json.getAsJsonObject();


+ 1
- 0
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/json/WxCpUserGsonAdapter.java View File

@@ -19,6 +19,7 @@ import java.lang.reflect.Type;
*/ */
public class WxCpUserGsonAdapter implements JsonDeserializer<WxCpUser>, JsonSerializer<WxCpUser> { public class WxCpUserGsonAdapter implements JsonDeserializer<WxCpUser>, JsonSerializer<WxCpUser> {


@Override
public WxCpUser deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) public WxCpUser deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException { throws JsonParseException {
JsonObject o = json.getAsJsonObject(); JsonObject o = json.getAsJsonObject();


+ 1
- 1
weixin-java-cp/src/main/java/me/chanjar/weixin/cp/util/xml/XStreamTransformer.java View File

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


private static Map<Class, XStream> configXStreamInstance() { private static Map<Class, XStream> configXStreamInstance() {
Map<Class, XStream> map = new HashMap<Class, XStream>();
Map<Class, XStream> map = new HashMap<>();
map.put(WxCpXmlMessage.class, config_WxCpXmlMessage()); map.put(WxCpXmlMessage.class, config_WxCpXmlMessage());
map.put(WxCpXmlOutNewsMessage.class, config_WxCpXmlOutNewsMessage()); map.put(WxCpXmlOutNewsMessage.class, config_WxCpXmlOutNewsMessage());
map.put(WxCpXmlOutTextMessage.class, config_WxCpXmlOutTextMessage()); map.put(WxCpXmlOutTextMessage.class, config_WxCpXmlOutTextMessage());


+ 22
- 15
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/ApiTestModule.java View File

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


import java.io.IOException;
import java.io.InputStream;

import com.google.inject.Binder; import com.google.inject.Binder;
import com.google.inject.Module; import com.google.inject.Module;
import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.XStream;
import com.thoughtworks.xstream.annotations.XStreamAlias; import com.thoughtworks.xstream.annotations.XStreamAlias;
import me.chanjar.weixin.common.util.xml.XStreamInitializer;


import java.io.InputStream;
import me.chanjar.weixin.common.util.xml.XStreamInitializer;


public class ApiTestModule implements Module { public class ApiTestModule implements Module {


@@ -19,13 +21,18 @@ public class ApiTestModule implements Module {


@Override @Override
public void configure(Binder binder) { public void configure(Binder binder) {
InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml");
WxXmlCpInMemoryConfigStorage config = fromXml(WxXmlCpInMemoryConfigStorage.class, is1);
WxCpServiceImpl wxService = new WxCpServiceImpl();
wxService.setWxCpConfigStorage(config);

binder.bind(WxCpServiceImpl.class).toInstance(wxService);
binder.bind(WxCpConfigStorage.class).toInstance(config);
try (InputStream is1 = ClassLoader
.getSystemResourceAsStream("test-config.xml")) {
WxXmlCpInMemoryConfigStorage config = fromXml(
WxXmlCpInMemoryConfigStorage.class, is1);
WxCpServiceImpl wxService = new WxCpServiceImpl();
wxService.setWxCpConfigStorage(config);

binder.bind(WxCpServiceImpl.class).toInstance(wxService);
binder.bind(WxCpConfigStorage.class).toInstance(config);
} catch (IOException e) {
e.printStackTrace();
}
} }


@XStreamAlias("xml") @XStreamAlias("xml")
@@ -38,7 +45,7 @@ public class ApiTestModule implements Module {
protected String tagId; protected String tagId;


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


public void setUserId(String userId) { public void setUserId(String userId) {
@@ -46,7 +53,7 @@ public class ApiTestModule implements Module {
} }


public String getDepartmentId() { public String getDepartmentId() {
return departmentId;
return this.departmentId;
} }


public void setDepartmentId(String departmentId) { public void setDepartmentId(String departmentId) {
@@ -54,7 +61,7 @@ public class ApiTestModule implements Module {
} }


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


public void setTagId(String tagId) { public void setTagId(String tagId) {
@@ -64,9 +71,9 @@ public class ApiTestModule implements Module {
@Override @Override
public String toString() { public String toString() {
return super.toString() + " > WxXmlCpConfigStorage{" + return super.toString() + " > WxXmlCpConfigStorage{" +
"userId='" + userId + '\'' +
", departmentId='" + departmentId + '\'' +
", tagId='" + tagId + '\'' +
"userId='" + this.userId + '\'' +
", departmentId='" + this.departmentId + '\'' +
", tagId='" + this.tagId + '\'' +
'}'; '}';
} }
} }


+ 7
- 5
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBaseAPITest.java View File

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


import com.google.inject.Inject;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.StringUtils;
import org.testng.Assert; import org.testng.Assert;
import org.testng.annotations.Guice; import org.testng.annotations.Guice;
import org.testng.annotations.Test; import org.testng.annotations.Test;


import com.google.inject.Inject;

import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.StringUtils;

/** /**
* 基础API测试 * 基础API测试
* *
@@ -20,9 +22,9 @@ public class WxCpBaseAPITest {
protected WxCpServiceImpl wxService; protected WxCpServiceImpl wxService;


public void testRefreshAccessToken() throws WxErrorException { public void testRefreshAccessToken() throws WxErrorException {
WxCpConfigStorage configStorage = wxService.wxCpConfigStorage;
WxCpConfigStorage configStorage = this.wxService.configStorage;
String before = configStorage.getAccessToken(); String before = configStorage.getAccessToken();
wxService.getAccessToken(false);
this.wxService.getAccessToken(false);


String after = configStorage.getAccessToken(); String after = configStorage.getAccessToken();




+ 10
- 7
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpBusyRetryTest.java View File

@@ -1,16 +1,17 @@
package me.chanjar.weixin.cp.api; package me.chanjar.weixin.cp.api;


import me.chanjar.weixin.common.bean.result.WxError;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.http.RequestExecutor;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; import java.util.concurrent.Executors;
import java.util.concurrent.Future; import java.util.concurrent.Future;


import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import me.chanjar.weixin.common.bean.result.WxError;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.common.util.http.RequestExecutor;

@Test @Test
public class WxCpBusyRetryTest { public class WxCpBusyRetryTest {


@@ -19,7 +20,9 @@ public class WxCpBusyRetryTest {
WxCpService service = new WxCpServiceImpl() { WxCpService service = new WxCpServiceImpl() {


@Override @Override
protected <T, E> T executeInternal(RequestExecutor<T, E> executor, String uri, E data) throws WxErrorException {
protected synchronized <T, E> T executeInternal(
RequestExecutor<T, E> executor, String uri, E data)
throws WxErrorException {
WxError error = new WxError(); WxError error = new WxError();
error.setErrorCode(-1); error.setErrorCode(-1);
throw new WxErrorException(error); throw new WxErrorException(error);


+ 19
- 16
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpDepartAPITest.java View File

@@ -1,13 +1,15 @@
package me.chanjar.weixin.cp.api; package me.chanjar.weixin.cp.api;


import com.google.inject.Inject;
import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.cp.bean.WxCpDepart;
import java.util.List;

import org.testng.Assert; import org.testng.Assert;
import org.testng.annotations.Guice; import org.testng.annotations.Guice;
import org.testng.annotations.Test; import org.testng.annotations.Test;


import java.util.List;
import com.google.inject.Inject;

import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.cp.bean.WxCpDepart;


/** /**
* 测试部门接口 * 测试部门接口
@@ -24,22 +26,23 @@ public class WxCpDepartAPITest {
protected WxCpDepart depart; protected WxCpDepart depart;


public void testDepartCreate() throws WxErrorException { public void testDepartCreate() throws WxErrorException {
WxCpDepart depart = new WxCpDepart();
depart.setName("子部门" + System.currentTimeMillis());
depart.setParentId(1);
depart.setOrder(1);
Integer departId = wxCpService.departCreate(depart);
WxCpDepart cpDepart = new WxCpDepart();
cpDepart.setName("子部门" + System.currentTimeMillis());
cpDepart.setParentId(1);
cpDepart.setOrder(1);
Integer departId = this.wxCpService.departCreate(cpDepart);
System.out.println(departId);
} }


@Test(dependsOnMethods = "testDepartCreate") @Test(dependsOnMethods = "testDepartCreate")
public void testDepartGet() throws WxErrorException { public void testDepartGet() throws WxErrorException {
System.out.println("=================获取部门"); System.out.println("=================获取部门");
List<WxCpDepart> departList = wxCpService.departGet();
List<WxCpDepart> departList = this.wxCpService.departGet();
Assert.assertNotNull(departList); Assert.assertNotNull(departList);
Assert.assertTrue(departList.size() > 0); Assert.assertTrue(departList.size() > 0);
for (WxCpDepart g : departList) { for (WxCpDepart g : departList) {
depart = g;
System.out.println(depart.getId() + ":" + depart.getName());
this.depart = g;
System.out.println(this.depart.getId() + ":" + this.depart.getName());
Assert.assertNotNull(g.getName()); Assert.assertNotNull(g.getName());
} }
} }
@@ -47,15 +50,15 @@ public class WxCpDepartAPITest {
@Test(dependsOnMethods = {"testDepartGet", "testDepartCreate"}) @Test(dependsOnMethods = {"testDepartGet", "testDepartCreate"})
public void testDepartUpdate() throws WxErrorException { public void testDepartUpdate() throws WxErrorException {
System.out.println("=================更新部门"); System.out.println("=================更新部门");
depart.setName("子部门改名" + System.currentTimeMillis());
wxCpService.departUpdate(depart);
this.depart.setName("子部门改名" + System.currentTimeMillis());
this.wxCpService.departUpdate(this.depart);
} }


@Test(dependsOnMethods = "testDepartUpdate") @Test(dependsOnMethods = "testDepartUpdate")
public void testDepartDelete() throws WxErrorException { public void testDepartDelete() throws WxErrorException {
System.out.println("=================删除部门"); System.out.println("=================删除部门");
System.out.println(depart.getId() + ":" + depart.getName());
wxCpService.departDelete(depart.getId());
System.out.println(this.depart.getId() + ":" + this.depart.getName());
this.wxCpService.departDelete(this.depart.getId());
} }


} }

+ 26
- 20
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMediaAPITest.java View File

@@ -1,18 +1,20 @@
package me.chanjar.weixin.cp.api; package me.chanjar.weixin.cp.api;


import com.google.inject.Inject;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import me.chanjar.weixin.common.exception.WxErrorException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

import org.testng.Assert; import org.testng.Assert;
import org.testng.annotations.DataProvider; import org.testng.annotations.DataProvider;
import org.testng.annotations.Guice; import org.testng.annotations.Guice;
import org.testng.annotations.Test; import org.testng.annotations.Test;


import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import com.google.inject.Inject;

import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import me.chanjar.weixin.common.exception.WxErrorException;


/** /**
* 测试多媒体文件上传下载 * 测试多媒体文件上传下载
@@ -27,21 +29,25 @@ public class WxCpMediaAPITest {
@Inject @Inject
protected WxCpServiceImpl wxService; protected WxCpServiceImpl wxService;


private List<String> media_ids = new ArrayList<String>();
private List<String> media_ids = new ArrayList<>();


@Test(dataProvider = "uploadMedia") @Test(dataProvider = "uploadMedia")
public void testUploadMedia(String mediaType, String fileType, String fileName) throws WxErrorException, IOException { public void testUploadMedia(String mediaType, String fileType, String fileName) throws WxErrorException, IOException {
InputStream inputStream = ClassLoader.getSystemResourceAsStream(fileName);
WxMediaUploadResult res = wxService.mediaUpload(mediaType, fileType, inputStream);
Assert.assertNotNull(res.getType());
Assert.assertNotNull(res.getCreatedAt());
Assert.assertTrue(res.getMediaId() != null || res.getThumbMediaId() != null);
try (InputStream inputStream = ClassLoader
.getSystemResourceAsStream(fileName);) {
WxMediaUploadResult res = this.wxService.mediaUpload(mediaType, fileType,
inputStream);
Assert.assertNotNull(res.getType());
Assert.assertNotNull(res.getCreatedAt());
Assert.assertTrue(
res.getMediaId() != null || res.getThumbMediaId() != null);


if (res.getMediaId() != null) {
media_ids.add(res.getMediaId());
}
if (res.getThumbMediaId() != null) {
media_ids.add(res.getThumbMediaId());
if (res.getMediaId() != null) {
this.media_ids.add(res.getMediaId());
}
if (res.getThumbMediaId() != null) {
this.media_ids.add(res.getThumbMediaId());
}
} }
} }


@@ -57,7 +63,7 @@ public class WxCpMediaAPITest {


@Test(dependsOnMethods = {"testUploadMedia"}, dataProvider = "downloadMedia") @Test(dependsOnMethods = {"testUploadMedia"}, dataProvider = "downloadMedia")
public void testDownloadMedia(String media_id) throws WxErrorException { public void testDownloadMedia(String media_id) throws WxErrorException {
wxService.mediaDownload(media_id);
this.wxService.mediaDownload(media_id);
} }


@DataProvider @DataProvider


+ 8
- 6
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageAPITest.java View File

@@ -1,11 +1,13 @@
package me.chanjar.weixin.cp.api; package me.chanjar.weixin.cp.api;


import org.testng.annotations.Guice;
import org.testng.annotations.Test;

import com.google.inject.Inject; import com.google.inject.Inject;

import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.exception.WxErrorException; import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.cp.bean.WxCpMessage; import me.chanjar.weixin.cp.bean.WxCpMessage;
import org.testng.annotations.Guice;
import org.testng.annotations.Test;


/*** /***
* 测试发送消息 * 测试发送消息
@@ -20,21 +22,21 @@ public class WxCpMessageAPITest {
protected WxCpServiceImpl wxService; protected WxCpServiceImpl wxService;


public void testSendCustomMessage() throws WxErrorException { public void testSendCustomMessage() throws WxErrorException {
ApiTestModule.WxXmlCpInMemoryConfigStorage configStorage = (ApiTestModule.WxXmlCpInMemoryConfigStorage) wxService.wxCpConfigStorage;
ApiTestModule.WxXmlCpInMemoryConfigStorage configStorage = (ApiTestModule.WxXmlCpInMemoryConfigStorage) this.wxService.configStorage;
WxCpMessage message1 = new WxCpMessage(); WxCpMessage message1 = new WxCpMessage();
message1.setAgentId(configStorage.getAgentId()); message1.setAgentId(configStorage.getAgentId());
message1.setMsgType(WxConsts.CUSTOM_MSG_TEXT); message1.setMsgType(WxConsts.CUSTOM_MSG_TEXT);
message1.setToUser(configStorage.getUserId()); message1.setToUser(configStorage.getUserId());
message1.setContent("欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>"); message1.setContent("欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>");
wxService.messageSend(message1);
this.wxService.messageSend(message1);


WxCpMessage message2 = WxCpMessage WxCpMessage message2 = WxCpMessage
.TEXT() .TEXT()
.agentId(configStorage.getAgentId()) .agentId(configStorage.getAgentId())
.toUser(configStorage.getUserId()) .toUser(configStorage.getUserId())
.content("欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>")
.content("欢迎欢迎,热烈欢迎\n换行测试\n超链接:<a href=\"http://www.baidu.com\">Hello World</a>")
.build(); .build();
wxService.messageSend(message2);
this.wxService.messageSend(message2);


} }




+ 1
- 1
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpMessageRouterTest.java View File

@@ -286,7 +286,7 @@ public class WxCpMessageRouterTest {
@Override @Override
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService wxCpService, public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context, WxCpService wxCpService,
WxSessionManager sessionManager) { WxSessionManager sessionManager) {
sb.append(this.echoStr).append(',');
this.sb.append(this.echoStr).append(',');
return null; return null;
} }




+ 12
- 12
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpTagAPITest.java View File

@@ -23,44 +23,44 @@ public class WxCpTagAPITest {
protected String tagId; protected String tagId;


public void testTagCreate() throws Exception { public void testTagCreate() throws Exception {
tagId = wxService.tagCreate("测试标签4");
System.out.println(tagId);
this.tagId = this.wxService.tagCreate("测试标签4");
System.out.println(this.tagId);
} }


@Test(dependsOnMethods = "testTagCreate") @Test(dependsOnMethods = "testTagCreate")
public void testTagUpdate() throws Exception { public void testTagUpdate() throws Exception {
wxService.tagUpdate(tagId, "测试标签-改名");
this.wxService.tagUpdate(this.tagId, "测试标签-改名");
} }


@Test(dependsOnMethods = "testTagUpdate") @Test(dependsOnMethods = "testTagUpdate")
public void testTagGet() throws Exception { public void testTagGet() throws Exception {
List<WxCpTag> tags = wxService.tagGet();
List<WxCpTag> tags = this.wxService.tagGet();
Assert.assertNotEquals(tags.size(), 0); Assert.assertNotEquals(tags.size(), 0);
} }


@Test(dependsOnMethods = "testTagGet") @Test(dependsOnMethods = "testTagGet")
public void testTagAddUsers() throws Exception { public void testTagAddUsers() throws Exception {
List<String> userIds = new ArrayList<String>();
userIds.add(((ApiTestModule.WxXmlCpInMemoryConfigStorage) configStorage).getUserId());
wxService.tagAddUsers(tagId, userIds, null);
List<String> userIds = new ArrayList<>();
userIds.add(((ApiTestModule.WxXmlCpInMemoryConfigStorage) this.configStorage).getUserId());
this.wxService.tagAddUsers(this.tagId, userIds, null);
} }


@Test(dependsOnMethods = "testTagAddUsers") @Test(dependsOnMethods = "testTagAddUsers")
public void testTagGetUsers() throws Exception { public void testTagGetUsers() throws Exception {
List<WxCpUser> users = wxService.tagGetUsers(tagId);
List<WxCpUser> users = this.wxService.tagGetUsers(this.tagId);
Assert.assertNotEquals(users.size(), 0); Assert.assertNotEquals(users.size(), 0);
} }


@Test(dependsOnMethods = "testTagGetUsers") @Test(dependsOnMethods = "testTagGetUsers")
public void testTagRemoveUsers() throws Exception { public void testTagRemoveUsers() throws Exception {
List<String> userIds = new ArrayList<String>();
userIds.add(((ApiTestModule.WxXmlCpInMemoryConfigStorage) configStorage).getUserId());
wxService.tagRemoveUsers(tagId, userIds);
List<String> userIds = new ArrayList<>();
userIds.add(((ApiTestModule.WxXmlCpInMemoryConfigStorage) this.configStorage).getUserId());
this.wxService.tagRemoveUsers(this.tagId, userIds);
} }


@Test(dependsOnMethods = "testTagRemoveUsers") @Test(dependsOnMethods = "testTagRemoveUsers")
public void testTagDelete() throws Exception { public void testTagDelete() throws Exception {
wxService.tagDelete(tagId);
this.wxService.tagDelete(this.tagId);
} }


} }

+ 5
- 5
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxCpUserAPITest.java View File

@@ -35,7 +35,7 @@ public class WxCpUserAPITest {
user.setPosition("woman"); user.setPosition("woman");
user.setTel("3300393"); user.setTel("3300393");
user.addExtAttr("爱好", "table"); user.addExtAttr("爱好", "table");
wxCpService.userCreate(user);
this.wxCpService.userCreate(user);
} }


@Test(dependsOnMethods = "testUserCreate") @Test(dependsOnMethods = "testUserCreate")
@@ -44,23 +44,23 @@ public class WxCpUserAPITest {
user.setUserId("some.woman"); user.setUserId("some.woman");
user.setName("Some Woman"); user.setName("Some Woman");
user.addExtAttr("爱好", "table2"); user.addExtAttr("爱好", "table2");
wxCpService.userUpdate(user);
this.wxCpService.userUpdate(user);
} }


@Test(dependsOnMethods = "testUserUpdate") @Test(dependsOnMethods = "testUserUpdate")
public void testUserGet() throws WxErrorException { public void testUserGet() throws WxErrorException {
WxCpUser user = wxCpService.userGet("some.woman");
WxCpUser user = this.wxCpService.userGet("some.woman");
Assert.assertNotNull(user); Assert.assertNotNull(user);
} }


@Test(dependsOnMethods = "testUserGet") @Test(dependsOnMethods = "testUserGet")
public void testDepartGetUsers() throws WxErrorException { public void testDepartGetUsers() throws WxErrorException {
List<WxCpUser> users = wxCpService.departGetUsers(1, true, 0);
List<WxCpUser> users = this.wxCpService.departGetUsers(1, true, 0);
Assert.assertNotEquals(users.size(), 0); Assert.assertNotEquals(users.size(), 0);
} }


@Test(dependsOnMethods = "testDepartGetUsers") @Test(dependsOnMethods = "testDepartGetUsers")
public void testUserDelete() throws WxErrorException { public void testUserDelete() throws WxErrorException {
wxCpService.userDelete("some.woman");
this.wxCpService.userDelete("some.woman");
} }
} }

+ 3
- 3
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/api/WxMenuAPITest.java View File

@@ -24,17 +24,17 @@ public class WxMenuAPITest {


@Test(dataProvider = "menu") @Test(dataProvider = "menu")
public void testCreateMenu(WxMenu wxMenu) throws WxErrorException { public void testCreateMenu(WxMenu wxMenu) throws WxErrorException {
wxService.menuCreate(wxMenu);
this.wxService.menuCreate(wxMenu);
} }


@Test(dependsOnMethods = {"testCreateMenu"}) @Test(dependsOnMethods = {"testCreateMenu"})
public void testGetMenu() throws WxErrorException { public void testGetMenu() throws WxErrorException {
Assert.assertNotNull(wxService.menuGet());
Assert.assertNotNull(this.wxService.menuGet());
} }


@Test(dependsOnMethods = {"testGetMenu"}) @Test(dependsOnMethods = {"testGetMenu"})
public void testDeleteMenu() throws WxErrorException { public void testDeleteMenu() throws WxErrorException {
wxService.menuDelete();
this.wxService.menuDelete();
} }


@DataProvider(name = "menu") @DataProvider(name = "menu")


+ 2
- 2
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoInMemoryConfigStorage.java View File

@@ -21,8 +21,8 @@ class WxCpDemoInMemoryConfigStorage extends WxCpInMemoryConfigStorage {


@Override @Override
public String toString() { public String toString() {
return "SimpleWxConfigProvider [appidOrCorpid=" + corpId + ", corpSecret=" + corpSecret + ", accessToken=" + accessToken
+ ", expiresTime=" + expiresTime + ", token=" + token + ", aesKey=" + aesKey + "]";
return "SimpleWxConfigProvider [appidOrCorpid=" + this.corpId + ", corpSecret=" + this.corpSecret + ", accessToken=" + this.accessToken
+ ", expiresTime=" + this.expiresTime + ", token=" + this.token + ", aesKey=" + this.aesKey + "]";
} }


} }

+ 56
- 57
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpDemoServer.java View File

@@ -1,16 +1,22 @@
package me.chanjar.weixin.cp.demo; package me.chanjar.weixin.cp.demo;


import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.cp.api.*;
import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
import me.chanjar.weixin.cp.bean.WxCpXmlOutTextMessage;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;

import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletHandler; import org.eclipse.jetty.servlet.ServletHandler;
import org.eclipse.jetty.servlet.ServletHolder; import org.eclipse.jetty.servlet.ServletHolder;


import java.io.InputStream;
import java.util.Map;
import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.cp.api.WxCpConfigStorage;
import me.chanjar.weixin.cp.api.WxCpMessageHandler;
import me.chanjar.weixin.cp.api.WxCpMessageRouter;
import me.chanjar.weixin.cp.api.WxCpService;
import me.chanjar.weixin.cp.api.WxCpServiceImpl;
import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
import me.chanjar.weixin.cp.bean.WxCpXmlOutTextMessage;


public class WxCpDemoServer { public class WxCpDemoServer {


@@ -36,55 +42,48 @@ public class WxCpDemoServer {
server.join(); server.join();
} }


private static void initWeixin() {
InputStream is1 = ClassLoader.getSystemResourceAsStream("test-config.xml");
WxCpDemoInMemoryConfigStorage config = WxCpDemoInMemoryConfigStorage.fromXml(is1);

wxCpConfigStorage = config;
wxCpService = new WxCpServiceImpl();
wxCpService.setWxCpConfigStorage(config);

WxCpMessageHandler handler = new WxCpMessageHandler() {
@Override
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context,
WxCpService wxCpService, WxSessionManager sessionManager) {
WxCpXmlOutTextMessage m = WxCpXmlOutMessage
.TEXT()
.content("测试加密消息")
.fromUser(wxMessage.getToUserName())
.toUser(wxMessage.getFromUserName())
.build();
return m;
}
};

WxCpMessageHandler oauth2handler = new WxCpMessageHandler() {
@Override
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage, Map<String, Object> context,
WxCpService wxCpService, WxSessionManager sessionManager) {
String href = "<a href=\"" + wxCpService.oauth2buildAuthorizationUrl(wxCpConfigStorage.getOauth2redirectUri(), null)
+ "\">测试oauth2</a>";
return WxCpXmlOutMessage
.TEXT()
.content(href)
.fromUser(wxMessage.getToUserName())
.toUser(wxMessage.getFromUserName()).build();
}
};

wxCpMessageRouter = new WxCpMessageRouter(wxCpService);
wxCpMessageRouter
.rule()
.async(false)
.content("哈哈") // 拦截内容为“哈哈”的消息
.handler(handler)
.end()
.rule()
.async(false)
.content("oauth")
.handler(oauth2handler)
.end()
;

private static void initWeixin() throws IOException {
try (InputStream is1 = ClassLoader
.getSystemResourceAsStream("test-config.xml")) {
WxCpDemoInMemoryConfigStorage config = WxCpDemoInMemoryConfigStorage
.fromXml(is1);

wxCpConfigStorage = config;
wxCpService = new WxCpServiceImpl();
wxCpService.setWxCpConfigStorage(config);

WxCpMessageHandler handler = new WxCpMessageHandler() {
@Override
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage,
Map<String, Object> context, WxCpService wxService,
WxSessionManager sessionManager) {
WxCpXmlOutTextMessage m = WxCpXmlOutMessage.TEXT().content("测试加密消息")
.fromUser(wxMessage.getToUserName())
.toUser(wxMessage.getFromUserName()).build();
return m;
}
};

WxCpMessageHandler oauth2handler = new WxCpMessageHandler() {
@Override
public WxCpXmlOutMessage handle(WxCpXmlMessage wxMessage,
Map<String, Object> context, WxCpService wxService,
WxSessionManager sessionManager) {
String href = "<a href=\""
+ wxService.oauth2buildAuthorizationUrl(
wxCpConfigStorage.getOauth2redirectUri(), null)
+ "\">测试oauth2</a>";
return WxCpXmlOutMessage.TEXT().content(href)
.fromUser(wxMessage.getToUserName())
.toUser(wxMessage.getFromUserName()).build();
}
};

wxCpMessageRouter = new WxCpMessageRouter(wxCpService);
wxCpMessageRouter.rule().async(false).content("哈哈") // 拦截内容为“哈哈”的消息
.handler(handler).end().rule().async(false).content("oauth")
.handler(oauth2handler).end();

}
} }
} }

+ 13
- 13
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpEndpointServlet.java View File

@@ -1,5 +1,11 @@
package me.chanjar.weixin.cp.demo; package me.chanjar.weixin.cp.demo;


import java.io.IOException;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import me.chanjar.weixin.common.util.StringUtils; import me.chanjar.weixin.common.util.StringUtils;
import me.chanjar.weixin.cp.api.WxCpConfigStorage; import me.chanjar.weixin.cp.api.WxCpConfigStorage;
import me.chanjar.weixin.cp.api.WxCpMessageRouter; import me.chanjar.weixin.cp.api.WxCpMessageRouter;
@@ -8,17 +14,11 @@ import me.chanjar.weixin.cp.bean.WxCpXmlMessage;
import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage; import me.chanjar.weixin.cp.bean.WxCpXmlOutMessage;
import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil; import me.chanjar.weixin.cp.util.crypto.WxCpCryptUtil;


import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/** /**
* @author Daniel Qian * @author Daniel Qian
*/ */
public class WxCpEndpointServlet extends HttpServlet { public class WxCpEndpointServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected WxCpConfigStorage wxCpConfigStorage; protected WxCpConfigStorage wxCpConfigStorage;
protected WxCpService wxCpService; protected WxCpService wxCpService;
protected WxCpMessageRouter wxCpMessageRouter; protected WxCpMessageRouter wxCpMessageRouter;
@@ -32,7 +32,7 @@ public class WxCpEndpointServlet extends HttpServlet {


@Override @Override
protected void service(HttpServletRequest request, HttpServletResponse response) protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
throws IOException {


response.setContentType("text/html;charset=utf-8"); response.setContentType("text/html;charset=utf-8");
response.setStatus(HttpServletResponse.SC_OK); response.setStatus(HttpServletResponse.SC_OK);
@@ -43,12 +43,12 @@ public class WxCpEndpointServlet extends HttpServlet {
String echostr = request.getParameter("echostr"); String echostr = request.getParameter("echostr");


if (StringUtils.isNotBlank(echostr)) { if (StringUtils.isNotBlank(echostr)) {
if (!wxCpService.checkSignature(msgSignature, timestamp, nonce, echostr)) {
if (!this.wxCpService.checkSignature(msgSignature, timestamp, nonce, echostr)) {
// 消息签名不正确,说明不是公众平台发过来的消息 // 消息签名不正确,说明不是公众平台发过来的消息
response.getWriter().println("非法请求"); response.getWriter().println("非法请求");
return; return;
} }
WxCpCryptUtil cryptUtil = new WxCpCryptUtil(wxCpConfigStorage);
WxCpCryptUtil cryptUtil = new WxCpCryptUtil(this.wxCpConfigStorage);
String plainText = cryptUtil.decrypt(echostr); String plainText = cryptUtil.decrypt(echostr);
// 说明是一个仅仅用来验证的请求,回显echostr // 说明是一个仅仅用来验证的请求,回显echostr
response.getWriter().println(plainText); response.getWriter().println(plainText);
@@ -56,10 +56,10 @@ public class WxCpEndpointServlet extends HttpServlet {
} }


WxCpXmlMessage inMessage = WxCpXmlMessage WxCpXmlMessage inMessage = WxCpXmlMessage
.fromEncryptedXml(request.getInputStream(), wxCpConfigStorage, timestamp, nonce, msgSignature);
WxCpXmlOutMessage outMessage = wxCpMessageRouter.route(inMessage);
.fromEncryptedXml(request.getInputStream(), this.wxCpConfigStorage, timestamp, nonce, msgSignature);
WxCpXmlOutMessage outMessage = this.wxCpMessageRouter.route(inMessage);
if (outMessage != null) { if (outMessage != null) {
response.getWriter().write(outMessage.toEncryptedXml(wxCpConfigStorage));
response.getWriter().write(outMessage.toEncryptedXml(this.wxCpConfigStorage));
} }


return; return;


+ 8
- 7
weixin-java-cp/src/test/java/me/chanjar/weixin/cp/demo/WxCpOAuth2Servlet.java View File

@@ -1,16 +1,17 @@
package me.chanjar.weixin.cp.demo; package me.chanjar.weixin.cp.demo;


import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.cp.api.WxCpService;
import java.io.IOException;
import java.util.Arrays;


import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;

import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.cp.api.WxCpService;


public class WxCpOAuth2Servlet extends HttpServlet { public class WxCpOAuth2Servlet extends HttpServlet {
private static final long serialVersionUID = 1L;


protected WxCpService wxCpService; protected WxCpService wxCpService;


@@ -20,7 +21,7 @@ public class WxCpOAuth2Servlet extends HttpServlet {


@Override @Override
protected void service(HttpServletRequest request, HttpServletResponse response) protected void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
throws IOException {


response.setContentType("text/html;charset=utf-8"); response.setContentType("text/html;charset=utf-8");
response.setStatus(HttpServletResponse.SC_OK); response.setStatus(HttpServletResponse.SC_OK);
@@ -30,7 +31,7 @@ public class WxCpOAuth2Servlet extends HttpServlet {
response.getWriter().println("<h1>code</h1>"); response.getWriter().println("<h1>code</h1>");
response.getWriter().println(code); response.getWriter().println(code);


String[] res = wxCpService.oauth2getUserInfo(code);
String[] res = this.wxCpService.oauth2getUserInfo(code);
response.getWriter().println("<h1>result</h1>"); response.getWriter().println("<h1>result</h1>");
response.getWriter().println(Arrays.toString(res)); response.getWriter().println(Arrays.toString(res));
} catch (WxErrorException e) { } catch (WxErrorException e) {


+ 4
- 4
weixin-java-mp/pom.xml View File

@@ -1,12 +1,12 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<project <project
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<parent> <parent>
<groupId>com.github.binarywang</groupId> <groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-parent</artifactId> <artifactId>weixin-java-parent</artifactId>
<version>2.1.0</version>
<version>2.2.0</version>
</parent> </parent>
<artifactId>weixin-java-mp</artifactId> <artifactId>weixin-java-mp</artifactId>
<name>WeiXin Java Tools - MP</name> <name>WeiXin Java Tools - MP</name>
@@ -47,7 +47,7 @@
<groupId>org.eclipse.jetty</groupId> <groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId> <artifactId>jetty-servlet</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency><!-- https://mvnrepository.com/artifact/joda-time/joda-time -->
</dependency>
<dependency> <dependency>
<groupId>joda-time</groupId> <groupId>joda-time</groupId>
<artifactId>joda-time</artifactId> <artifactId>joda-time</artifactId>


+ 1
- 2
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpCardService.java View File

@@ -6,8 +6,7 @@ import me.chanjar.weixin.mp.bean.result.WxMpCardResult;


/** /**
* 卡券相关接口 * 卡券相关接口
* Created by Binary Wang on 2016/7/27.
* @author binarywang(https://github.com/binarywang)
* @author YuJian(mgcnrx11@hotmail.com) on 01/11/2016
*/ */
public interface WxMpCardService { public interface WxMpCardService {




+ 0
- 69
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpGroupService.java View File

@@ -1,69 +0,0 @@
package me.chanjar.weixin.mp.api;

import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.bean.WxMpGroup;

import java.util.List;

/**
* 用户分组相关操作接口
* @author Binary Wang
*
*/
public interface WxMpGroupService {


/**
* <pre>
* 分组管理接口 - 创建分组
* 最多支持创建500个分组
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=分组管理接口
* </pre>
*
* @param name 分组名字(30个字符以内)
*/
WxMpGroup groupCreate(String name) throws WxErrorException;

/**
* <pre>
* 分组管理接口 - 查询所有分组
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=分组管理接口
* </pre>
*/
List<WxMpGroup> groupGet() throws WxErrorException;

/**
* <pre>
* 分组管理接口 - 查询用户所在分组
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=分组管理接口
* </pre>
*
* @param openid 微信用户的openid
*/
long userGetGroup(String openid) throws WxErrorException;

/**
* <pre>
* 分组管理接口 - 修改分组名
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=分组管理接口
*
* 如果id为0(未分组),1(黑名单),2(星标组),或者不存在的id,微信会返回系统繁忙的错误
* </pre>
*
* @param group 要更新的group,group的id,name必须设置
*/
void groupUpdate(WxMpGroup group) throws WxErrorException;

/**
* <pre>
* 分组管理接口 - 移动用户分组
* 详情请见: http://mp.weixin.qq.com/wiki/index.php?title=分组管理接口
*
* 如果to_groupid为0(未分组),1(黑名单),2(星标组),或者不存在的id,微信会返回系统繁忙的错误
* </pre>
*
* @param openid 用户openid
* @param to_groupid 移动到的分组id
*/
void userUpdateGroup(String openid, long to_groupid) throws WxErrorException;
}

+ 18
- 4
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpKefuService.java View File

@@ -1,12 +1,18 @@
package me.chanjar.weixin.mp.api; package me.chanjar.weixin.mp.api;


import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfAccountRequest;
import me.chanjar.weixin.mp.bean.kefu.result.*;

import java.io.File; import java.io.File;
import java.util.Date; import java.util.Date;


import me.chanjar.weixin.common.exception.WxErrorException;
import me.chanjar.weixin.mp.bean.WxMpCustomMessage;
import me.chanjar.weixin.mp.bean.kefu.request.WxMpKfAccountRequest;
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfList;
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfMsgList;
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfOnlineList;
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionGetResult;
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionList;
import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfSessionWaitCaseList;

/** /**
* 客服接口 , * 客服接口 ,
* 命名采用kefu拼音的原因是: * 命名采用kefu拼音的原因是:
@@ -17,6 +23,14 @@ import java.util.Date;
*/ */
public interface WxMpKefuService { public interface WxMpKefuService {


/**
* <pre>
* 发送客服消息
* 详情请见: <a href="http://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140547&token=&lang=zh_CN">发送客服消息</a>
* </pre>
*/
boolean customMessageSend(WxMpCustomMessage message) throws WxErrorException;

//*******************客服管理接口***********************// //*******************客服管理接口***********************//


/** /**


+ 2
- 0
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMaterialService.java View File

@@ -10,10 +10,12 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;


/** /**
* <pre>
* Created by Binary Wang on 2016/7/21. * Created by Binary Wang on 2016/7/21.
* 素材管理的相关接口,包括媒体管理的接口, * 素材管理的相关接口,包括媒体管理的接口,
* 即以https://api.weixin.qq.com/cgi-bin/material * 即以https://api.weixin.qq.com/cgi-bin/material
* 和 https://api.weixin.qq.com/cgi-bin/media开头的接口 * 和 https://api.weixin.qq.com/cgi-bin/media开头的接口
* </pre>
*/ */
public interface WxMpMaterialService { public interface WxMpMaterialService {




+ 19
- 18
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouter.java View File

@@ -1,24 +1,25 @@
package me.chanjar.weixin.mp.api; package me.chanjar.weixin.mp.api;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import me.chanjar.weixin.common.api.WxErrorExceptionHandler;
import me.chanjar.weixin.common.api.WxMessageDuplicateChecker;
import me.chanjar.weixin.common.api.WxMessageInMemoryDuplicateChecker;
import me.chanjar.weixin.common.session.InternalSession; import me.chanjar.weixin.common.session.InternalSession;
import me.chanjar.weixin.common.session.InternalSessionManager; import me.chanjar.weixin.common.session.InternalSessionManager;
import me.chanjar.weixin.common.session.StandardSessionManager; import me.chanjar.weixin.common.session.StandardSessionManager;
import me.chanjar.weixin.common.session.WxSessionManager; import me.chanjar.weixin.common.session.WxSessionManager;
import me.chanjar.weixin.common.util.LogExceptionHandler; import me.chanjar.weixin.common.util.LogExceptionHandler;
import me.chanjar.weixin.common.api.WxErrorExceptionHandler;
import me.chanjar.weixin.common.api.WxMessageDuplicateChecker;
import me.chanjar.weixin.common.api.WxMessageInMemoryDuplicateChecker;
import me.chanjar.weixin.mp.bean.WxMpXmlMessage; import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/** /**
* <pre> * <pre>
@@ -155,7 +156,7 @@ public class WxMpMessageRouter {
} }
WxMpXmlOutMessage res = null; WxMpXmlOutMessage res = null;
final List<Future> futures = new ArrayList<>();
final List<Future<?>> futures = new ArrayList<>();
for (final WxMpMessageRouterRule rule : matchRules) { for (final WxMpMessageRouterRule rule : matchRules) {
// 返回最后一个非异步的rule的执行结果 // 返回最后一个非异步的rule的执行结果
if(rule.isAsync()) { if(rule.isAsync()) {
@@ -170,7 +171,7 @@ public class WxMpMessageRouter {
} else { } else {
res = rule.service(wxMessage, this.wxMpService, this.sessionManager, this.exceptionHandler); res = rule.service(wxMessage, this.wxMpService, this.sessionManager, this.exceptionHandler);
// 在同步操作结束,session访问结束 // 在同步操作结束,session访问结束
this.log.debug("End session access: async=false, sessionId={}", wxMessage.getFromUserName());
this.log.debug("End session access: async=false, sessionId={}", wxMessage.getFromUser());
sessionEndAccess(wxMessage); sessionEndAccess(wxMessage);
} }
} }
@@ -179,10 +180,10 @@ public class WxMpMessageRouter {
this.executorService.submit(new Runnable() { this.executorService.submit(new Runnable() {
@Override @Override
public void run() { public void run() {
for (Future future : futures) {
for (Future<?> future : futures) {
try { try {
future.get(); future.get();
WxMpMessageRouter.this.log.debug("End session access: async=true, sessionId={}", wxMessage.getFromUserName());
WxMpMessageRouter.this.log.debug("End session access: async=true, sessionId={}", wxMessage.getFromUser());
// 异步操作结束,session访问结束 // 异步操作结束,session访问结束
sessionEndAccess(wxMessage); sessionEndAccess(wxMessage);
} catch (InterruptedException e) { } catch (InterruptedException e) {
@@ -202,7 +203,7 @@ public class WxMpMessageRouter {
StringBuffer messageId = new StringBuffer(); StringBuffer messageId = new StringBuffer();
if (wxMessage.getMsgId() == null) { if (wxMessage.getMsgId() == null) {
messageId.append(wxMessage.getCreateTime()) messageId.append(wxMessage.getCreateTime())
.append("-").append(wxMessage.getFromUserName())
.append("-").append(wxMessage.getFromUser())
.append("-").append(wxMessage.getEventKey() == null ? "" : wxMessage.getEventKey()) .append("-").append(wxMessage.getEventKey() == null ? "" : wxMessage.getEventKey())
.append("-").append(wxMessage.getEvent() == null ? "" : wxMessage.getEvent()) .append("-").append(wxMessage.getEvent() == null ? "" : wxMessage.getEvent())
; ;
@@ -220,7 +221,7 @@ public class WxMpMessageRouter {
*/ */
protected void sessionEndAccess(WxMpXmlMessage wxMessage) { protected void sessionEndAccess(WxMpXmlMessage wxMessage) {
InternalSession session = ((InternalSessionManager)this.sessionManager).findSession(wxMessage.getFromUserName());
InternalSession session = ((InternalSessionManager)this.sessionManager).findSession(wxMessage.getFromUser());
if (session != null) { if (session != null) {
session.endAccess(); session.endAccess();
} }


+ 1
- 1
weixin-java-mp/src/main/java/me/chanjar/weixin/mp/api/WxMpMessageRouterRule.java View File

@@ -168,7 +168,7 @@ public class WxMpMessageRouterRule {
*/ */
protected boolean test(WxMpXmlMessage wxMessage) { protected boolean test(WxMpXmlMessage wxMessage) {
return return
(this.fromUser == null || this.fromUser.equals(wxMessage.getFromUserName()))
(this.fromUser == null || this.fromUser.equals(wxMessage.getFromUser()))
&& &&
(this.msgType == null || this.msgType.toLowerCase().equals((wxMessage.getMsgType()==null?null:wxMessage.getMsgType().toLowerCase()))) (this.msgType == null || this.msgType.toLowerCase().equals((wxMessage.getMsgType()==null?null:wxMessage.getMsgType().toLowerCase())))
&& &&


Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save