Compare commits

..

No commits in common. "main" and "rxjava" have entirely different histories.
main ... rxjava

1226 changed files with 9672 additions and 10784 deletions

10
.idea/.gitignore generated vendored Normal file
View File

@ -0,0 +1,10 @@
# Default ignored files
/shelf/
/workspace.xml
# Editor-based HTTP Client requests
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml
# Zeppelin ignored files
/ZeppelinRemoteNotebooks/

View File

@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CheckStyle-IDEA" serialisationVersion="2">
<checkstyleVersion>10.22.0</checkstyleVersion>
<scanScope>JavaOnly</scanScope>
<copyLibs>true</copyLibs>
<option name="thirdPartyClasspath" />
<option name="activeLocationIds" />
<option name="locations">
<list>
<ConfigurationLocation id="bundled-sun-checks" type="BUNDLED" scope="All" description="Sun Checks">(bundled)</ConfigurationLocation>
<ConfigurationLocation id="bundled-google-checks" type="BUNDLED" scope="All" description="Google Checks">(bundled)</ConfigurationLocation>
</list>
</option>
</component>
</project>

22
.idea/compiler.xml generated
View File

@ -2,17 +2,37 @@
<project version="4"> <project version="4">
<component name="CompilerConfiguration"> <component name="CompilerConfiguration">
<annotationProcessing> <annotationProcessing>
<profile default="true" name="Default" enabled="true" />
<profile name="Maven default annotation processors profile" enabled="true"> <profile name="Maven default annotation processors profile" enabled="true">
<sourceOutputDir name="target/generated-sources/annotations" /> <sourceOutputDir name="target/generated-sources/annotations" />
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" /> <sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
<outputRelativeToContentRoot value="true" /> <outputRelativeToContentRoot value="true" />
<module name="wechat-j-open" /> <module name="wechat-j-open" />
<module name="wechat-j-pay" /> <module name="wechat-j-pay" />
<module name="wechat-j-work" />
<module name="wechat-j-common" /> <module name="wechat-j-common" />
<module name="wechat-j-mp" /> <module name="wechat-j-mp" />
<module name="wechat-j-oa" /> <module name="wechat-j-oa" />
</profile> </profile>
</annotationProcessing> </annotationProcessing>
<bytecodeTargetLevel>
<module name="wechat-j-oa (1)" target="11" />
<module name="wechat-j-oa (2)" target="1.8" />
<module name="weixin-graal" target="1.8" />
<module name="weixin-java-common" target="1.8" />
<module name="weixin-java-cp" target="1.8" />
<module name="weixin-java-miniapp" target="1.8" />
<module name="weixin-java-mp" target="1.8" />
<module name="weixin-java-open" target="1.8" />
<module name="weixin-java-pay" target="1.8" />
<module name="weixin-java-qidian" target="1.8" />
<module name="wx-java" target="1.8" />
<module name="wx-java-cp-spring-boot-starter" target="1.8" />
<module name="wx-java-miniapp-spring-boot-starter" target="1.8" />
<module name="wx-java-mp-spring-boot-starter" target="1.8" />
<module name="wx-java-open-spring-boot-starter" target="1.8" />
<module name="wx-java-pay-spring-boot-starter" target="1.8" />
<module name="wx-java-qidian-spring-boot-starter" target="1.8" />
<module name="wx-java-spring-boot-starters" target="1.8" />
</bytecodeTargetLevel>
</component> </component>
</project> </project>

26
.idea/encodings.xml generated
View File

@ -11,9 +11,31 @@
<file url="file://$PROJECT_DIR$/open/src/main/resources" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/open/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/pay/src/main/java" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/pay/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/pay/src/main/resources" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/pay/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/spring-boot-starters/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/spring-boot-starters/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/spring-boot-starters/wx-java-cp-spring-boot-starter/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/spring-boot-starters/wx-java-miniapp-spring-boot-starter/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/spring-boot-starters/wx-java-mp-spring-boot-starter/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/spring-boot-starters/wx-java-open-spring-boot-starter/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/spring-boot-starters/wx-java-open-spring-boot-starter/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/spring-boot-starters/wx-java-pay-spring-boot-starter/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/spring-boot-starters/wx-java-pay-spring-boot-starter/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/spring-boot-starters/wx-java-qidian-spring-boot-starter/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/spring-boot-starters/wx-java-qidian-spring-boot-starter/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/work/src/main/java" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/weixin-graal/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/work/src/main/resources" charset="UTF-8" /> <file url="file://$PROJECT_DIR$/weixin-graal/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/weixin-java-cp/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/weixin-java-cp/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/weixin-java-miniapp/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/weixin-java-miniapp/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/weixin-java-mp/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/weixin-java-mp/src/main/resources" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/weixin-java-qidian/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/weixin-java-qidian/src/main/resources" charset="UTF-8" />
</component> </component>
</project> </project>

View File

@ -1,20 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="RemoteRepositoriesConfiguration"> <component name="RemoteRepositoriesConfiguration">
<remote-repository>
<option name="id" value="ossez-repo-snapshots" />
<option name="name" value="OSSEZ Private Snapshots" />
<option name="url" value="https://repo.ossez.com/repository/maven-snapshots/" />
</remote-repository>
<remote-repository> <remote-repository>
<option name="id" value="ossez-repo-releases" /> <option name="id" value="ossez-repo-releases" />
<option name="name" value="iSharkFly Private Releases" /> <option name="name" value="OSSEZ Private Releases" />
<option name="url" value="https://repo.isharkfly.com/repository/isharkfly-maven-releases/" /> <option name="url" value="https://repo.ossez.com/repository/maven-releases/" />
</remote-repository> </remote-repository>
<remote-repository> <remote-repository>
<option name="id" value="central" /> <option name="id" value="central" />
<option name="name" value="Central Repository" /> <option name="name" value="Central Repository" />
<option name="url" value="https://repo.isharkfly.com/repository/maven/" /> <option name="url" value="https://repo.ossez.com/repository/maven-public/" />
</remote-repository>
<remote-repository>
<option name="id" value="ossez-repo-snapshots" />
<option name="name" value="iSharkFly Private Snapshots" />
<option name="url" value="https://repo.isharkfly.com/repository/isharkfly-maven-snapshots/" />
</remote-repository> </remote-repository>
<remote-repository> <remote-repository>
<option name="id" value="central" /> <option name="id" value="central" />

6
.idea/jpa-buddy.xml generated Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="JpaBuddyIdeaProjectConfig">
<option name="renamerInitialized" value="true" />
</component>
</project>

12
.idea/php.xml generated Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="MessDetectorOptionsConfiguration">
<option name="transferred" value="true" />
</component>
<component name="PHPCSFixerOptionsConfiguration">
<option name="transferred" value="true" />
</component>
<component name="PHPCodeSnifferOptionsConfiguration">
<option name="transferred" value="true" />
</component>
</project>

View File

@ -14,34 +14,28 @@ WeChat-J 开发使用的库。
我们旨在提供一个初始化的开发框架,能够让应用在使用 Spring Boot 框架的基础上让你的微信公众号快速接入微信平台。 我们旨在提供一个初始化的开发框架,能够让应用在使用 Spring Boot 框架的基础上让你的微信公众号快速接入微信平台。
# 项目说明 # 项目说明
我们在网上找了一些微信相关的 SDK要不就是缺少维护要不就是集成了非常多的功能因我们的公众号希望能够尽量的自动化处理所以我们在已有的基础上进行了一些修改和整合。 我们在网上找了一些微信相关的 SDK要不就是缺少维护要不就是集成了非常多的功能因我们的公众号希望能够尽量的自动化处理所以我们在已有的基础上进行了一些修改和整合。
## 必要的准备 ## 必要的准备
因微信开发 Java SDK 的开发其实并不非常复杂,主要是通过 HTTP 发送请求并且将获得的返回数据进行一些处理返回对象就可以了。 因微信开发 Java SDK 的开发其实并不非常复杂,主要是通过 HTTP 发送请求并且将获得的返回数据进行一些处理返回对象就可以了。
我们需要调用微信的 HTTP 接口,所以我们需要在 Java 中使用一个 Http 客户端,在当前我们的环境中,我们只使用 OkHttp 来进行实现。 我们需要调用微信的 HTTP 接口,所以我们需要在 Java 中使用一个 Http 客户端,在当前我们的环境中,我们只使用 OkHttp 来进行实现。
在老的项目中,可能不少人会使用 Apache 的 HttpClient 来进行实现,但因为 OkHttp 广泛的被使用在安卓的手机上,所以使用 OkHttp 在老的项目中,可能不少人会使用 Apache 的 HttpClient 来进行实现,但因为 OkHttp 广泛的被使用在安卓的手机上,所以使用 OkHttp 会更加简便。
会更加简便。
* [Retrofit 是什么](https://www.ossez.com/t/retrofit/14302) * [Retrofit 是什么](https://www.ossez.com/t/retrofit/14302)
* [RxJava 是什么](https://www.ossez.com/t/rxjava/14305) * [RxJava 是什么](https://www.ossez.com/t/rxjava/14305)
* [微信测试平台获得测试账号](https://www.ossez.com/t/topic/14281) * [微信测试平台获得测试账号](https://www.ossez.com/t/topic/14281)
### Maven 和依赖 ### Maven 和依赖
当前我们还没有把正式版发布到仓库中,我们还在使用 0.0.1-SNAPSHOT 版本进行内部测试。 当前我们还没有把正式版发布到仓库中,我们还在使用 0.0.1-SNAPSHOT 版本进行内部测试。
最好的版本就是下载我们的源代码后 Fork 到你本地,然后直接使用 Maven 来进行编译。 最好的版本就是下载我们的源代码后 Fork 到你本地,然后直接使用 Maven 来进行编译。
#### 微信公众号WeChat Java Official Account #### 微信公众号WeChat Java Official Account
模块名wechat-j-oa 模块名wechat-j-oa
```xml ```xml
<dependency> <dependency>
<groupId>com.ossez.wechat</groupId> <groupId>com.ossez.wechat</groupId>
<artifactId>wechat-j-oa</artifactId> <artifactId>wechat-j-oa</artifactId>
@ -50,11 +44,9 @@ WeChat-J 开发使用的库。
``` ```
#### 微信小程序WeChat Java Mini Programs #### 微信小程序WeChat Java Mini Programs
模块名wechat-j-mp 模块名wechat-j-mp
```xml ```xml
<dependency> <dependency>
<groupId>com.ossez.wechat</groupId> <groupId>com.ossez.wechat</groupId>
<artifactId>wechat-j-mp</artifactId> <artifactId>wechat-j-mp</artifactId>
@ -63,37 +55,16 @@ WeChat-J 开发使用的库。
``` ```
#### 微信支付WeChat Java Pay #### 微信支付WeChat Java Pay
模块名wechat-j-pay (模块还在开发,无实际内容,请不要使用。)
模块名wechat-j-pay
```xml
<dependency>
<groupId>com.ossez.wechat</groupId>
<artifactId>wechat-j-pay</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
```
#### 企业微信WeChat Java WeCom #### 企业微信WeChat Java WeCom
模块名wechat-j-work (模块还在开发,无实际内容,请不要使用。)
模块名wechat-j-work
```xml
<dependency>
<groupId>com.ossez.wechat</groupId>
<artifactId>wechat-j-work</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
```
#### 微信开放平台WeChat Java Open #### 微信开放平台WeChat Java Open
模块名wechat-j-open 模块名wechat-j-open
```xml ```xml
<dependency> <dependency>
<groupId>com.ossez.wechat</groupId> <groupId>com.ossez.wechat</groupId>
<artifactId>wechat-j-open</artifactId> <artifactId>wechat-j-open</artifactId>
@ -102,18 +73,17 @@ WeChat-J 开发使用的库。
``` ```
### 其他内容 ### 其他内容
* 任何有关讨论,请访问 [社区](https://www.ossez.com/tag/wechat)您可以在这里提出功能需求Bug 修复,问题解答。 * 任何有关讨论,请访问 [社区](https://www.ossez.com/tag/wechat)您可以在这里提出功能需求Bug 修复,问题解答。
* 可以考虑使用 http://paste.ubuntu.com 来对你在提交问题的时候出现的为代码进行简化。 * 可以考虑使用 http://paste.ubuntu.com 来对你在提交问题的时候出现的为代码进行简化。
### 框架和案例 ### 框架和案例
如果你想登记你的项目,请[访问这里](https://www.ossez.com/t/wechat-j-demo/14303)。 如果你想登记你的项目,请[访问这里](https://www.ossez.com/t/wechat-j-demo/14303)。
同时,我们也提供了一些开发框架,能够让你直接检出项目就可以直接对微信 SDK 进行接入和测试。 同时,我们也提供了一些开发框架,能够让你直接检出项目就可以直接对微信 SDK 进行接入和测试。
* [公众号 Spring Boot 测试程序](https://github.com/honeymoose/WeChat-Official-Account-Spring) * [公众号 Spring Boot 测试程序](https://github.com/honeymoose/WeChat-Official-Account-Spring)
# 联系方式 # 联系方式
请使用下面的联系方式和我们联系。 请使用下面的联系方式和我们联系。

View File

@ -2,185 +2,195 @@
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <project 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" 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="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.ossez.wechat</groupId>
<artifactId>wechat-j-common</artifactId>
<packaging>jar</packaging>
<parent>
<groupId>com.ossez.wechat</groupId> <groupId>com.ossez.wechat</groupId>
<artifactId>wechat-j-common</artifactId> <artifactId>wechat-j</artifactId>
<packaging>jar</packaging> <version>0.0.1-SNAPSHOT</version>
</parent>
<parent> <name>WeChat Java Common</name>
<groupId>com.ossez.wechat</groupId> <description>The module is common for all other package</description>
<artifactId>wechat-j</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<name>WeChat Java Common</name> <dependencies>
<description>The module is common for all other package</description> <dependency>
<groupId>org.jodd</groupId>
<artifactId>jodd-http</artifactId>
<scope>provided</scope>
</dependency>
<dependencies> <dependency>
<dependency> <groupId>org.slf4j</groupId>
<groupId>org.jodd</groupId> <artifactId>slf4j-api</artifactId>
<artifactId>jodd-http</artifactId> </dependency>
<scope>provided</scope> <dependency>
</dependency> <groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.36</version>
</dependency>
<dependency> <dependency>
<groupId>org.slf4j</groupId> <groupId>com.google.code.gson</groupId>
<artifactId>slf4j-api</artifactId> <artifactId>gson</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.thoughtworks.xstream</groupId> <groupId>commons-codec</groupId>
<artifactId>xstream</artifactId> <artifactId>commons-codec</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.apache.httpcomponents</groupId> <groupId>commons-io</groupId>
<artifactId>httpclient</artifactId> <artifactId>commons-io</artifactId>
<exclusions> </dependency>
<exclusion> <dependency>
<artifactId>commons-logging</artifactId> <groupId>org.apache.commons</groupId>
<groupId>commons-logging</groupId> <artifactId>commons-lang3</artifactId>
</exclusion> </dependency>
</exclusions> <dependency>
</dependency> <groupId>com.google.guava</groupId>
<dependency> <artifactId>guava</artifactId>
<groupId>org.apache.httpcomponents</groupId> </dependency>
<artifactId>httpmime</artifactId> <dependency>
</dependency> <groupId>org.projectlombok</groupId>
<dependency> <artifactId>lombok</artifactId>
<groupId>org.slf4j</groupId> </dependency>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.36</version>
</dependency>
<dependency> <dependency>
<groupId>com.google.code.gson</groupId> <groupId>ch.qos.logback</groupId>
<artifactId>gson</artifactId> <artifactId>logback-classic</artifactId>
</dependency> <scope>test</scope>
<dependency> </dependency>
<groupId>commons-codec</groupId> <dependency>
<artifactId>commons-codec</artifactId> <groupId>org.testng</groupId>
</dependency> <artifactId>testng</artifactId>
<dependency> <scope>test</scope>
<groupId>commons-io</groupId> </dependency>
<artifactId>commons-io</artifactId> <dependency>
</dependency> <groupId>org.mockito</groupId>
<dependency> <artifactId>mockito-all</artifactId>
<groupId>org.apache.commons</groupId> <scope>test</scope>
<artifactId>commons-lang3</artifactId> </dependency>
</dependency> <dependency>
<dependency> <groupId>com.google.inject</groupId>
<groupId>com.google.guava</groupId> <artifactId>guice</artifactId>
<artifactId>guava</artifactId> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.projectlombok</groupId> <groupId>org.eclipse.jetty</groupId>
<artifactId>lombok</artifactId> <artifactId>jetty-server</artifactId>
</dependency> <scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-guava</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.3</version>
<exclusions>
<exclusion>
<groupId>pull-parser</groupId>
<artifactId>pull-parser</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>com.github.jedis-lock</groupId>
<artifactId>jedis-lock</artifactId>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
<dependency> <build>
<groupId>ch.qos.logback</groupId> <plugins>
<artifactId>logback-classic</artifactId> <plugin>
<scope>test</scope> <groupId>org.apache.maven.plugins</groupId>
</dependency> <artifactId>maven-surefire-plugin</artifactId>
<dependency> <configuration>
<groupId>com.google.inject</groupId> <suiteXmlFiles>
<artifactId>guice</artifactId> <suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
<scope>test</scope> </suiteXmlFiles>
</dependency> </configuration>
<dependency> </plugin>
<groupId>org.eclipse.jetty</groupId> </plugins>
<artifactId>jetty-server</artifactId> </build>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-guava</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.3</version>
<exclusions>
<exclusion>
<groupId>pull-parser</groupId>
<artifactId>pull-parser</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>com.github.jedis-lock</groupId>
<artifactId>jedis-lock</artifactId>
</dependency>
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.jetbrains</groupId>
<artifactId>annotations</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build> <profiles>
<profile>
<id>native-image</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<configuration> <version>3.5.1</version>
<suiteXmlFiles> <configuration>
<suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile> <annotationProcessors>
</suiteXmlFiles> com.github.binarywang.wx.graal.GraalProcessor,lombok.launch.AnnotationProcessorHider$AnnotationProcessor,lombok.launch.AnnotationProcessorHider$ClaimingProcessor
</configuration> </annotationProcessors>
</plugin> <annotationProcessorPaths>
<path>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-graal</artifactId>
<version>${project.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins> </plugins>
</build> </build>
<profiles> </profile>
<profile> </profiles>
<id>native-image</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<annotationProcessors>
com.github.binarywang.wx.graal.GraalProcessor,lombok.launch.AnnotationProcessorHider$AnnotationProcessor,lombok.launch.AnnotationProcessorHider$ClaimingProcessor
</annotationProcessors>
<annotationProcessorPaths>
<path>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-graal</artifactId>
<version>${project.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project> </project>

View File

@ -1,32 +0,0 @@
package com.ossez.wechat.common.api;
import com.ossez.wechat.common.model.WeChatAccessToken;
import com.ossez.wechat.common.model.WeChatApiDomainIp;
import com.ossez.wechat.common.model.req.NetworkCheck;
import com.ossez.wechat.common.model.req.QueryQuota;
import com.ossez.wechat.common.model.res.NetworkCheckResponse;
import com.ossez.wechat.common.model.res.QueryQuotaResponse;
import io.reactivex.Single;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Query;
public interface WeChatOfficialAccountApi {
@GET("/cgi-bin/token")
Single<WeChatAccessToken> getAccessToken(@Query("grant_type") String grantType, @Query("appid") String appId, @Query("secret") String secret);
@GET("/cgi-bin/get_api_domain_ip")
Single<WeChatApiDomainIp> getDomainIPs();
@POST("/cgi-bin/callback/check")
Single<NetworkCheckResponse> checkNetwork(@Body NetworkCheck request);
@POST("/cgi-bin/clear_quota")
Single<NetworkCheckResponse> clearQuota(@Body NetworkCheck request);
@POST("/cgi-bin/openapi/quota/get")
Single<QueryQuotaResponse> queryQuota(@Body QueryQuota request);
}

View File

@ -1,26 +0,0 @@
package com.ossez.wechat.common.api;
import com.ossez.wechat.common.model.WeChatAccessToken;
import com.ossez.wechat.common.model.WeChatApiDomainIp;
import com.ossez.wechat.common.model.WeChatOAuth2AccessToken;
import com.ossez.wechat.common.model.entity.WeChatOAuth2UserInfo;
import com.ossez.wechat.common.model.req.NetworkCheck;
import com.ossez.wechat.common.model.req.QueryQuota;
import com.ossez.wechat.common.model.res.NetworkCheckResponse;
import com.ossez.wechat.common.model.res.QueryQuotaResponse;
import io.reactivex.Single;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Query;
public interface WeChatOpenApi {
@GET("/sns/oauth2/access_token")
Single<WeChatOAuth2AccessToken> getAccessToken(@Query("grant_type") String grantType, @Query("appid") String appId, @Query("secret") String secret, @Query("code") String code);
@GET("/sns/userinfo")
Single<WeChatOAuth2UserInfo> getWeChatUserInfo(@Query("access_token") String accessToken, @Query("openid") String openId);
}

View File

@ -0,0 +1,70 @@
package com.ossez.wechat.common.bean;
import com.google.gson.annotations.SerializedName;
import com.ossez.wechat.common.util.json.WxGsonBuilder;
import lombok.Data;
import java.io.Serializable;
/**
* oauth2用户个人信息.
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
* created on 2020-10-11
*/
@Data
public class WxOAuth2UserInfo implements Serializable {
private static final long serialVersionUID = 3181943506448954725L;
/**
* openid 普通用户的标识对当前开发者帐号唯一
*/
private String openid;
/**
* nickname 普通用户昵称
*/
private String nickname;
/**
* sex 普通用户性别1为男性2为女性
*/
private Integer sex;
/**
* city 普通用户个人资料填写的城市
*/
private String city;
/**
* province 普通用户个人资料填写的省份
*/
private String province;
/**
* country 国家如中国为CN
*/
private String country;
/**
* headimgurl 用户头像最后一个数值代表正方形头像大小有0466496132数值可选0代表640*640正方形头像
* 用户没有头像时该项为空
*/
@SerializedName("headimgurl")
private String headImgUrl;
/**
* unionid 用户统一标识针对一个微信开放平台帐号下的应用同一用户的unionid是唯一的
*/
@SerializedName("unionid")
private String unionId;
/**
* privilege 用户特权信息json数组如微信沃卡用户为chinaunicom
*/
@SerializedName("privilege")
private String[] privileges;
/**
* is_snapshotuser 是否为快照页模式虚拟账号值为0时是普通用户1时是虚拟帐号
*/
@SerializedName("is_snapshotuser")
private Integer snapshotUser;
public static WxOAuth2UserInfo fromJson(String json) {
return WxGsonBuilder.create().fromJson(json, WxOAuth2UserInfo.class);
}
}

View File

@ -1,4 +1,4 @@
package com.ossez.wechat.common.model.entity.menu; package com.ossez.wechat.common.bean.menu;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
@ -19,7 +19,7 @@ import lombok.Data;
public class WxMenu implements Serializable { public class WxMenu implements Serializable {
private static final long serialVersionUID = -7083914585539687746L; private static final long serialVersionUID = -7083914585539687746L;
private List<MenuButton> buttons = new ArrayList<>(); private List<WxMenuButton> buttons = new ArrayList<>();
private WxMenuRule matchRule; private WxMenuRule matchRule;

View File

@ -0,0 +1,96 @@
package com.ossez.wechat.common.bean.menu;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import com.google.gson.annotations.SerializedName;
import com.ossez.wechat.common.util.json.WxGsonBuilder;
import lombok.Data;
/**
* menu button.
*
* @author Daniel Qian
*/
@Data
public class WxMenuButton implements Serializable {
private static final long serialVersionUID = -1070939403109776555L;
/**
* <pre>
* 菜单的响应动作类型.
* view表示网页类型
* click表示点击类型
* miniprogram表示小程序类型
* </pre>
*/
private String type;
/**
* 菜单标题不超过16个字节子菜单不超过60个字节.
*/
private String name;
/**
* <pre>
* 菜单KEY值用于消息接口推送不超过128字节.
* click等点击类型必须
* </pre>
*/
private String key;
/**
* <pre>
* 网页链接.
* 用户点击菜单可打开链接不超过1024字节type为miniprogram时不支持小程序的老版本客户端将打开本url
* viewminiprogram类型必须
* </pre>
*/
private String url;
/**
* <pre>
* 调用新增永久素材接口返回的合法media_id.
* media_id类型和view_limited类型必须
* </pre>
*/
@SerializedName("media_id")
private String mediaId;
/**
* <pre>
* 调用发布图文接口获得的article_id.
* article_id类型和article_view_limited类型必须
* </pre>
*/
@SerializedName("article_id")
private String articleId;
/**
* <pre>
* 小程序的appid.
* miniprogram类型必须
* </pre>
*/
@SerializedName("appid")
private String appId;
/**
* <pre>
* 小程序的页面路径.
* miniprogram类型必须
* </pre>
*/
@SerializedName("pagepath")
private String pagePath;
@SerializedName("sub_button")
private List<WxMenuButton> subButtons = new ArrayList<>();
@Override
public String toString() {
return WxGsonBuilder.create().toJson(this);
}
}

View File

@ -1,4 +1,4 @@
package com.ossez.wechat.common.model.entity.menu; package com.ossez.wechat.common.bean.menu;
import java.io.Serializable; import java.io.Serializable;

View File

@ -0,0 +1,51 @@
package com.ossez.wechat.common.bean.oauth2;
import com.google.gson.annotations.SerializedName;
import com.ossez.wechat.common.util.json.WxGsonBuilder;
import lombok.Data;
import java.io.Serializable;
/**
* https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842
*
* @author Daniel Qian
*/
@Data
public class WxOAuth2AccessToken implements Serializable {
private static final long serialVersionUID = -1345910558078620805L;
@SerializedName("access_token")
private String accessToken;
@SerializedName("expires_in")
private int expiresIn = -1;
@SerializedName("refresh_token")
private String refreshToken;
@SerializedName("openid")
private String openId;
@SerializedName("scope")
private String scope;
@SerializedName("is_snapshotuser")
private Integer snapshotUser;
/**
* https://mp.weixin.qq.com/cgi-bin/announce?action=getannouncement&announce_id=11513156443eZYea&version=&lang=zh_CN.
* 本接口在scope参数为snsapi_base时不再提供unionID字段
*/
@SerializedName("unionid")
private String unionId;
public static WxOAuth2AccessToken fromJson(String json) {
return WxGsonBuilder.create().fromJson(json, WxOAuth2AccessToken.class);
}
@Override
public String toString() {
return WxGsonBuilder.create().toJson(this);
}
}

View File

@ -1,68 +0,0 @@
package com.ossez.wechat.common.config;
import com.ossez.wechat.common.constant.WeChatConstant;
/**
* 微信接口地址域名部分的自定义设置信息.
*/
public class WxMpHostConfig {
/**
* 对应于https://api.weixin.qq.com
*/
private String apiHost;
/**
* 对应于https://open.weixin.qq.com
*/
private String openHost;
/**
* 对应于https://mp.weixin.qq.com
*/
private String mpHost;
public static String buildUrl(WxMpHostConfig hostConfig, String prefix, String path) {
if (hostConfig == null) {
return prefix + path;
}
if (hostConfig.getApiHost() != null && prefix.equals(WeChatConstant.ENDPOINT_WECHAT)) {
return hostConfig.getApiHost() + path;
}
if (hostConfig.getMpHost() != null && prefix.equals(WeChatConstant.ENDPOINT_MP)) {
return hostConfig.getMpHost() + path;
}
if (hostConfig.getOpenHost() != null && prefix.equals(WeChatConstant.ENDPOINT_OPEN)) {
return hostConfig.getOpenHost() + path;
}
return prefix + path;
}
public String getApiHost() {
return apiHost;
}
public void setApiHost(String apiHost) {
this.apiHost = apiHost;
}
public String getOpenHost() {
return openHost;
}
public void setOpenHost(String openHost) {
this.openHost = openHost;
}
public String getMpHost() {
return mpHost;
}
public void setMpHost(String mpHost) {
this.mpHost = mpHost;
}
}

View File

@ -1,7 +1,6 @@
package com.ossez.wechat.common.constant; package com.ossez.wechat.common.constant;
import com.ossez.wechat.common.enums.WeChatErrorCode; import com.ossez.wechat.common.enums.WeChatErrorCode;
import java.util.*; import java.util.*;
/** /**
@ -11,10 +10,7 @@ import java.util.*;
*/ */
public class WeChatConstant { public class WeChatConstant {
public static final String ENDPOINT_WECHAT = "https://api.weixin.qq.com"; public static final String ENDPOINT_OFFICIAL_ACCOUNT = "https://api.weixin.qq.com/cgi-bin/";
public static final String ENDPOINT_MP = "https://mp.weixin.qq.com";
public static final String ENDPOINT_OPEN = "https://open.weixin.qq.com";
/** /**
* access_token 相关错误代码 * access_token 相关错误代码
@ -58,33 +54,51 @@ public class WeChatConstant {
/** /**
* 主动发送消息(即客服消息)的消息类型. * 主动发送消息(即客服消息)的消息类型.
*/ */
public static class MsgType { public static class KefuMsgType {
/** /**
* 消息类型: * 文本消息.
* text(文本)
* image(图片)
* voice(语音)
* video(视频)
* music(音乐)
* news(图文消息 - 点击跳转到外链)
* mpnews(图文消息 - 点击跳转到图文消息页面)
* wxcard(卡券)
* miniprogrampage(小程序)
* markdown(目前仅支持markdown语法的子集微工作台原企业号不支持展示markdown消息)
* file(发送文件 - CP专用)
* textcard(文本卡片消息 - CP专用)
* wxcard(卡券消息)
*/ */
public static final String TEXT = "text"; public static final String TEXT = "text";
/**
* 图片消息.
*/
public static final String IMAGE = "image"; public static final String IMAGE = "image";
/**
* 语音消息.
*/
public static final String VOICE = "voice"; public static final String VOICE = "voice";
/**
* 视频消息.
*/
public static final String VIDEO = "video"; public static final String VIDEO = "video";
/**
* 音乐消息.
*/
public static final String MUSIC = "music"; public static final String MUSIC = "music";
/**
* 图文消息点击跳转到外链.
*/
public static final String NEWS = "news"; public static final String NEWS = "news";
/**
* 图文消息点击跳转到图文消息页面.
*/
public static final String MPNEWS = "mpnews"; public static final String MPNEWS = "mpnews";
/**
* markdown消息.
* 目前仅支持markdown语法的子集微工作台原企业号不支持展示markdown消息
*/
public static final String MARKDOWN = "markdown"; public static final String MARKDOWN = "markdown";
/**
* 发送文件CP专用.
*/
public static final String FILE = "file"; public static final String FILE = "file";
/**
* 文本卡片消息CP专用.
*/
public static final String TEXTCARD = "textcard"; public static final String TEXTCARD = "textcard";
/**
* 卡券消息.
*/
public static final String WXCARD = "wxcard"; public static final String WXCARD = "wxcard";
/** /**
* 转发到客服的消息. * 转发到客服的消息.

View File

@ -1,20 +0,0 @@
package com.ossez.wechat.common.enums;
/**
* The language for WeChat API can support
*
* @author YuCheng Hu
*/
public enum Language {
ZH_CN("zh_CN"), EN_US("en_US");
private String code;
Language(String code) {
this.code = code;
}
public String getCode() {
return code;
}
}

View File

@ -1,12 +0,0 @@
package com.ossez.wechat.common.enums;
/**
* WeChat's Storage Category
*
* We provide implement for MEM(RAM) and REDIS
*
* @author YuCheng Hu
*/
public enum WeChatStorageCategory {
MEM, REDIS
}

View File

@ -1,25 +0,0 @@
package com.ossez.wechat.common.enums;
/**
* 微信卡券
*
* @author YuCheng
*/
public enum WxCardType {
MEMBER_CARD("MEMBER_CARD"),
GROUPON("GROUPON"),
CASH("CASH"),
DISCOUNT("DISCOUNT"),
GIFT("GIFT"),
GENERAL_COUPON("GENERAL_COUPON");
private String code;
WxCardType(String code) {
this.code = code;
}
public String getCode() {
return code;
}
}

View File

@ -1,26 +0,0 @@
package com.ossez.wechat.common.exception;
/**
* @author Daniel Qian
*/
public class DataStructureException extends WxErrorException {
private static final long serialVersionUID = -6357149550353160810L;
private final WxError error;
private static final int DEFAULT_ERROR_CODE = -99;
public DataStructureException(String message) {
this(WxError.builder().errorCode(DEFAULT_ERROR_CODE).errorMsg(message).build());
}
public DataStructureException(WxError error) {
super(error.toString());
this.error = error;
}
public WxError getError() {
return this.error;
}
}

View File

@ -40,5 +40,4 @@ public class WeChatAccessToken {
public void setExpiresIn(int expiresIn) { public void setExpiresIn(int expiresIn) {
this.expiresIn = expiresIn; this.expiresIn = expiresIn;
} }
} }

View File

@ -1,27 +0,0 @@
package com.ossez.wechat.common.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.ossez.wechat.common.util.json.WxGsonBuilder;
import java.util.List;
/**
* WeChatAccessToken Response Object
*
* @author YuCheng Hu
*/
public class WeChatApiDomainIp {
@JsonProperty("ip_list")
private List<String> ipList;
public List<String> getIpList() {
return ipList;
}
public void setIpList(List<String> ipList) {
this.ipList = ipList;
}
}

View File

@ -1,16 +0,0 @@
package com.ossez.wechat.common.model;
import lombok.Data;
import lombok.experimental.Accessors;
import java.io.Serializable;
@Data
@Accessors(chain = true)
public class WeChatHost implements Serializable {
private static final long serialVersionUID = -7648920647310280817L;
private String apiHost;
private String openHost;
private String mpHost;
}

View File

@ -1,107 +0,0 @@
package com.ossez.wechat.common.model;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.gson.annotations.SerializedName;
import com.ossez.wechat.common.util.json.WxGsonBuilder;
import lombok.Data;
import java.io.Serializable;
/**
* https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842
*
* @author Daniel Qian
*/
public class WeChatOAuth2AccessToken implements Serializable {
private static final long serialVersionUID = 5755678830089329526L;
@JsonProperty("access_token")
private String accessToken;
@JsonProperty("expires_in")
private int expiresIn = -1;
@JsonProperty("refresh_token")
private String refreshToken;
@JsonProperty("openid")
private String openId;
@JsonProperty("scope")
private String scope;
@JsonProperty("is_snapshotuser")
private Integer snapshotUser;
/**
* https://mp.weixin.qq.com/cgi-bin/announce?action=getannouncement&announce_id=11513156443eZYea&version=&lang=zh_CN.
* 本接口在scope参数为snsapi_base时不再提供unionID字段
*/
@SerializedName("unionid")
private String unionId;
public static WeChatOAuth2AccessToken fromJson(String json) {
return WxGsonBuilder.create().fromJson(json, WeChatOAuth2AccessToken.class);
}
@Override
public String toString() {
return WxGsonBuilder.create().toJson(this);
}
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
public int getExpiresIn() {
return expiresIn;
}
public void setExpiresIn(int expiresIn) {
this.expiresIn = expiresIn;
}
public String getRefreshToken() {
return refreshToken;
}
public void setRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}
public String getOpenId() {
return openId;
}
public void setOpenId(String openId) {
this.openId = openId;
}
public String getScope() {
return scope;
}
public void setScope(String scope) {
this.scope = scope;
}
public Integer getSnapshotUser() {
return snapshotUser;
}
public void setSnapshotUser(Integer snapshotUser) {
this.snapshotUser = snapshotUser;
}
public String getUnionId() {
return unionId;
}
public void setUnionId(String unionId) {
this.unionId = unionId;
}
}

View File

@ -1,34 +0,0 @@
package com.ossez.wechat.common.model;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* WeChatStatus Response Object
*
* @author YuCheng Hu
*/
public class WeChatStatus {
@JsonProperty("errcode")
private int errCode = 0;
@JsonProperty("errmsg")
private String errMsg;
public int getErrCode() {
return errCode;
}
public void setErrCode(int errCode) {
this.errCode = errCode;
}
public String getErrMsg() {
return errMsg;
}
public void setErrMsg(String errMsg) {
this.errMsg = errMsg;
}
}

View File

@ -1,129 +0,0 @@
package com.ossez.wechat.common.model.entity;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.gson.annotations.SerializedName;
import com.ossez.wechat.common.util.json.WxGsonBuilder;
import lombok.Data;
import java.io.Serializable;
/**
* oauth2用户个人信息.
* <pre>
* {
* "openid":"OPENID",
* "nickname":"NICKNAME",
* "sex":1,
* "province":"PROVINCE",
* "city":"CITY",
* "country":"COUNTRY",
* "headimgurl": "https://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0",
* "privilege":[
* "PRIVILEGE1",
* "PRIVILEGE2"
* ],
* "unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"
*
* }
* </pre>
*
* @author YuCheng
*/
@Data
public class WeChatOAuth2UserInfo implements Serializable {
private static final long serialVersionUID = 3181943506448954725L;
@JsonProperty("openid")
private String openid;
@JsonProperty("nickname")
private String nickname;
@JsonProperty("sex")
private Integer sex;
@JsonProperty("city")
private String city;
@JsonProperty("province")
private String province;
@JsonProperty("country")
private String country;
@JsonProperty("headimgurl")
private String headImgUrl;
@JsonProperty("unionid")
private String unionId;
@JsonProperty("privilege")
private String[] privileges;
public String getOpenid() {
return openid;
}
public void setOpenid(String openid) {
this.openid = openid;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getHeadImgUrl() {
return headImgUrl;
}
public void setHeadImgUrl(String headImgUrl) {
this.headImgUrl = headImgUrl;
}
public String getUnionId() {
return unionId;
}
public void setUnionId(String unionId) {
this.unionId = unionId;
}
public String[] getPrivileges() {
return privileges;
}
public void setPrivileges(String[] privileges) {
this.privileges = privileges;
}
}

View File

@ -1,31 +0,0 @@
package com.ossez.wechat.common.model.entity;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* WeChatAccessToken Response Object
*
* @author YuCheng Hu
*/
public class WeChatResponseStatus {
@JsonProperty("errcode")
private Integer errorCode;
@JsonProperty("errmsg")
private String errorMsg;
public Integer getErrorCode() {
return errorCode;
}
public void setErrorCode(Integer errorCode) {
this.errorCode = errorCode;
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
}

View File

@ -1,104 +0,0 @@
package com.ossez.wechat.common.model.entity;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.experimental.Accessors;
@Accessors(chain = true)
public class WeChatUser {
@JsonProperty(value = "openid", required = true)
private String openId;
@JsonProperty(required = true)
private String nickname;
private Integer sex;
private String language;
private String city;
private String province;
private String country;
@JsonProperty(value = "headimgurl")
private String headImgURL;
@JsonProperty(value = "unionid", required = true)
private String unionId;
public String getOpenId() {
return openId;
}
public void setOpenId(String openId) {
this.openId = openId;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getHeadImgURL() {
return headImgURL;
}
public void setHeadImgURL(String headImgURL) {
this.headImgURL = headImgURL;
}
public String getUnionId() {
return unionId;
}
public void setUnionId(String unionId) {
this.unionId = unionId;
}
}

View File

@ -1,43 +0,0 @@
package com.ossez.wechat.common.model.entity.builder;
import com.ossez.wechat.common.model.entity.menu.MenuButton;
import com.ossez.wechat.common.model.req.MenuRequest;
import java.util.List;
public class MenuButtonBuilder {
private List<MenuButton> subButtonList;
private String type;
private String name;
private String key;
private String url;
public MenuButtonBuilder setSubButtonList(List<MenuButton> subButtonList) {
this.subButtonList = subButtonList;
return this;
}
public MenuButtonBuilder setType(String type) {
this.type = type;
return this;
}
public MenuButtonBuilder setName(String name) {
this.name = name;
return this;
}
public MenuButtonBuilder setKey(String key) {
this.key = key;
return this;
}
public MenuButtonBuilder setUrl(String url) {
this.url = url;
return this;
}
public MenuButton createMenuButton() {
return new MenuButton(subButtonList, type, name, key, url);
}
}

View File

@ -1,40 +0,0 @@
package com.ossez.wechat.common.model.entity.menu;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.gson.annotations.SerializedName;
import com.ossez.wechat.common.model.req.MenuRequest;
import com.ossez.wechat.common.util.json.WxGsonBuilder;
import lombok.Data;
/**
* menu button.
*
* @author Daniel Qian
*/
@Data
public class MenuButton implements Serializable {
private static final long serialVersionUID = -1070939403109776555L;
public MenuButton(List<MenuButton> subButtonList, String type, String name, String key, String url) {
this.subButtonList = subButtonList;
this.type = type;
this.name = name;
this.key = key;
this.url = url;
}
@JsonProperty(value = "sub_button")
private List<MenuButton> subButtonList;
@JsonProperty("type")
private String type;
@JsonProperty("name")
private String name;
@JsonProperty("key")
private String key;
@JsonProperty("url")
private String url;
}

View File

@ -1,128 +0,0 @@
package com.ossez.wechat.common.model.req;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.gson.annotations.SerializedName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import java.io.Serializable;
/**
* CustomMessage
*
* @author YuCheng
*/
public class CustomMessage implements Serializable {
private static final long serialVersionUID = -9196732086954365246L;
@JsonProperty("touser")
private String toUser;
@JsonProperty("msgtype")
private String msgType;
@JsonProperty("text")
private KfText text;
@JsonProperty("image")
private KfImage image;
@JsonProperty("link")
private KfLink link;
@JsonProperty("miniprogrampage")
private KfMaPage maPage;
@Data
@AllArgsConstructor
public static class KfText implements Serializable {
private static final long serialVersionUID = 151122958720941270L;
private String content;
}
@Data
@AllArgsConstructor
public static class KfImage implements Serializable {
private static final long serialVersionUID = -5409342945117300782L;
@SerializedName("media_id")
private String mediaId;
}
@Data
@Builder
public static class KfLink implements Serializable {
private static final long serialVersionUID = -6728776817556127413L;
private String title;
private String description;
private String url;
@SerializedName("thumb_url")
private String thumbUrl;
}
@Data
@Builder
public static class KfMaPage implements Serializable {
private static final long serialVersionUID = -5633492281871634466L;
private String title;
@SerializedName("pagepath")
private String pagePath;
@SerializedName("thumb_media_id")
private String thumbMediaId;
}
public String getToUser() {
return toUser;
}
public void setToUser(String toUser) {
this.toUser = toUser;
}
public String getMsgType() {
return msgType;
}
public void setMsgType(String msgType) {
this.msgType = msgType;
}
public KfText getText() {
return text;
}
public void setText(KfText text) {
this.text = text;
}
public KfImage getImage() {
return image;
}
public void setImage(KfImage image) {
this.image = image;
}
public KfLink getLink() {
return link;
}
public void setLink(KfLink link) {
this.link = link;
}
public KfMaPage getMaPage() {
return maPage;
}
public void setMaPage(KfMaPage maPage) {
this.maPage = maPage;
}
}

View File

@ -1,40 +0,0 @@
package com.ossez.wechat.common.model.req;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.gson.annotations.SerializedName;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import java.io.Serializable;
/**
* CustomMessage
*
* @author YuCheng
*/
public class DataCubeRequest implements Serializable {
private static final long serialVersionUID = -9196732086954365246L;
@JsonProperty(value = "begin_date", required = true)
private String beginDate;
@JsonProperty(value = "end_date", required = true)
private String endDate;
public String getBeginDate() {
return beginDate;
}
public void setBeginDate(String beginDate) {
this.beginDate = beginDate;
}
public String getEndDate() {
return endDate;
}
public void setEndDate(String endDate) {
this.endDate = endDate;
}
}

View File

@ -1,28 +0,0 @@
package com.ossez.wechat.common.model.req;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.ossez.wechat.common.model.entity.menu.MenuButton;
import com.ossez.wechat.common.model.res.DataCubeArticle;
import java.io.Serializable;
import java.util.List;
/**
* CustomMessage
*
* @author YuCheng
*/
public class MenuRequest implements Serializable {
private static final long serialVersionUID = -9196732086954365246L;
@JsonProperty(value = "button", required = true)
private List<MenuButton> buttonList;
public List<MenuButton> getButtonList() {
return buttonList;
}
public void setButtonList(List<MenuButton> buttonList) {
this.buttonList = buttonList;
}
}

View File

@ -1,33 +0,0 @@
package com.ossez.wechat.common.model.req;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.ossez.wechat.common.util.json.WxGsonBuilder;
import org.apache.commons.lang3.StringUtils;
/**
* WeChatAccessToken Response Object
*
* @author YuCheng Hu
*/
public class NetworkCheck {
@JsonProperty("action")
private String action = "all";
@JsonProperty("check_operator")
private String checkOperator = StringUtils.upperCase("DEFAULT");
public String getAction() {
return action;
}
public void setAction(String action) {
this.action = action;
}
public String getCheckOperator() {
return checkOperator;
}
public void setCheckOperator(String checkOperator) {
this.checkOperator = checkOperator;
}
}

View File

@ -1,22 +0,0 @@
package com.ossez.wechat.common.model.req;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.apache.commons.lang3.StringUtils;
/**
* WeChatAccessToken Response Object
*
* @author YuCheng Hu
*/
public class QueryQuota {
@JsonProperty("cgi_path")
private String cgiPath = "/cgi-bin/message/custom/send";
public String getCgiPath() {
return cgiPath;
}
public void setCgiPath(String cgiPath) {
this.cgiPath = cgiPath;
}
}

View File

@ -1,130 +0,0 @@
package com.ossez.wechat.common.model.res;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
/**
* UserSummaryResponse Object
*
* @author YuCheng Hu
*/
public class DataCubeArticle {
@JsonProperty("list")
private List<ArticleData> articleDataList;
public static class ArticleData {
@JsonProperty("ref_date")
private String refDate;
@JsonProperty("msgid")
private String msgId;
@JsonProperty("title")
private String title;
@JsonProperty("int_page_read_user")
private Long intPageReadUser;
@JsonProperty("ori_page_read_user")
private Long oriPageReadUser;
@JsonProperty("ori_page_read_count")
private Long oriPageReadCount;
@JsonProperty("share_user")
private Long shareUser;
@JsonProperty("shareCount")
private Long shareCount;
@JsonProperty("add_to_fav_user")
private Long addToFavUser;
@JsonProperty("add_to_fav_count")
private Long addToFavCount;
public String getRefDate() {
return refDate;
}
public void setRefDate(String refDate) {
this.refDate = refDate;
}
public String getMsgId() {
return msgId;
}
public void setMsgId(String msgId) {
this.msgId = msgId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Long getIntPageReadUser() {
return intPageReadUser;
}
public void setIntPageReadUser(Long intPageReadUser) {
this.intPageReadUser = intPageReadUser;
}
public Long getOriPageReadUser() {
return oriPageReadUser;
}
public void setOriPageReadUser(Long oriPageReadUser) {
this.oriPageReadUser = oriPageReadUser;
}
public Long getOriPageReadCount() {
return oriPageReadCount;
}
public void setOriPageReadCount(Long oriPageReadCount) {
this.oriPageReadCount = oriPageReadCount;
}
public Long getShareUser() {
return shareUser;
}
public void setShareUser(Long shareUser) {
this.shareUser = shareUser;
}
public Long getShareCount() {
return shareCount;
}
public void setShareCount(Long shareCount) {
this.shareCount = shareCount;
}
public Long getAddToFavUser() {
return addToFavUser;
}
public void setAddToFavUser(Long addToFavUser) {
this.addToFavUser = addToFavUser;
}
public Long getAddToFavCount() {
return addToFavCount;
}
public void setAddToFavCount(Long addToFavCount) {
this.addToFavCount = addToFavCount;
}
}
public List<ArticleData> getArticleDataList() {
return articleDataList;
}
public void setArticleDataList(List<ArticleData> articleDataList) {
this.articleDataList = articleDataList;
}
}

View File

@ -1,78 +0,0 @@
package com.ossez.wechat.common.model.res;
import com.fasterxml.jackson.annotation.JsonProperty;
import java.util.List;
/**
* UserSummaryResponse Object
*
* @author YuCheng Hu
*/
public class DataCubeUser {
@JsonProperty("list")
private List<UserData> userDataList;
public static class UserData {
@JsonProperty("ref_date")
private String refDate;
@JsonProperty("user_source")
private Long userSource;
@JsonProperty("new_user")
private Long newUser;
@JsonProperty("cancel_user")
private Long cancelUser;
@JsonProperty("cumulate_user")
private Long cumulateUser;
public String getRefDate() {
return refDate;
}
public void setRefDate(String refDate) {
this.refDate = refDate;
}
public Long getUserSource() {
return userSource;
}
public void setUserSource(Long userSource) {
this.userSource = userSource;
}
public Long getNewUser() {
return newUser;
}
public void setNewUser(Long newUser) {
this.newUser = newUser;
}
public Long getCancelUser() {
return cancelUser;
}
public void setCancelUser(Long cancelUser) {
this.cancelUser = cancelUser;
}
public Long getCumulateUser() {
return cumulateUser;
}
public void setCumulateUser(Long cumulateUser) {
this.cumulateUser = cumulateUser;
}
}
public List<UserData> getUserDataList() {
return userDataList;
}
public void setUserDataList(List<UserData> userDataList) {
this.userDataList = userDataList;
}
}

View File

@ -1,35 +0,0 @@
package com.ossez.wechat.common.model.res;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.ossez.wechat.common.api.WxMessageInMemoryDuplicateCheckerSingleton;
import org.apache.commons.lang3.StringUtils;
/**
* WeChatAccessToken Response Object
*
* @author YuCheng Hu
*/
public class NetworkCheckResponse {
@JsonProperty("dns")
private String dns;
@JsonProperty("ping")
private Ping ping;
private static class dns {
@JsonProperty("ip")
private String ip;
@JsonProperty("real_operator")
private String realOperator;
}
private static class Ping {
@JsonProperty("ip")
private String ip;
@JsonProperty("from_operator")
private String fromOperator;
@JsonProperty("package_loss")
private String packageLoss;
@JsonProperty("time")
private String time;
}
}

View File

@ -1,66 +0,0 @@
package com.ossez.wechat.common.model.res;
import com.fasterxml.jackson.annotation.JsonProperty;
/**
* WeChatAccessToken Response Object
*
* @author YuCheng Hu
*/
public class QueryQuotaResponse {
@JsonProperty("errcode")
private Integer errorCode;
@JsonProperty("errmsg")
private String errorMsg;
@JsonProperty("quota")
private Quota quota;
private static class Quota {
@JsonProperty("daily_limit")
private String dailyLimit;
@JsonProperty("used")
private String used;
@JsonProperty("remain")
private String remain;
public String getDailyLimit() {
return dailyLimit;
}
public void setDailyLimit(String dailyLimit) {
this.dailyLimit = dailyLimit;
}
public String getUsed() {
return used;
}
public void setUsed(String used) {
this.used = used;
}
public String getRemain() {
return remain;
}
public void setRemain(String remain) {
this.remain = remain;
}
}
public Integer getErrorCode() {
return errorCode;
}
public void setErrorCode(Integer errorCode) {
this.errorCode = errorCode;
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
}

View File

@ -1,7 +1,7 @@
package com.ossez.wechat.common.service; package com.ossez.wechat.common.service;
import com.ossez.wechat.common.model.entity.WeChatOAuth2UserInfo; import com.ossez.wechat.common.bean.WxOAuth2UserInfo;
import com.ossez.wechat.common.model.WeChatOAuth2AccessToken; import com.ossez.wechat.common.bean.oauth2.WxOAuth2AccessToken;
import com.ossez.wechat.common.exception.WxErrorException; import com.ossez.wechat.common.exception.WxErrorException;
/** /**
@ -34,7 +34,7 @@ public interface WxOAuth2Service {
* @return token对象 * @return token对象
* @throws WxErrorException . * @throws WxErrorException .
*/ */
WeChatOAuth2AccessToken getAccessToken(String code) throws WxErrorException; WxOAuth2AccessToken getAccessToken(String code) throws WxErrorException;
/** /**
* 用code换取oauth2的access token. * 用code换取oauth2的access token.
@ -45,7 +45,7 @@ public interface WxOAuth2Service {
* @return token对象 * @return token对象
* @throws WxErrorException . * @throws WxErrorException .
*/ */
WeChatOAuth2AccessToken getAccessToken(String appId, String appSecret, String code) throws WxErrorException; WxOAuth2AccessToken getAccessToken(String appId, String appSecret, String code) throws WxErrorException;
/** /**
* <pre> * <pre>
@ -56,7 +56,7 @@ public interface WxOAuth2Service {
* @return 新的token对象 * @return 新的token对象
* @throws WxErrorException . * @throws WxErrorException .
*/ */
WeChatOAuth2AccessToken refreshAccessToken(String refreshToken) throws WxErrorException; WxOAuth2AccessToken refreshAccessToken(String refreshToken) throws WxErrorException;
/** /**
* <pre> * <pre>
@ -68,7 +68,7 @@ public interface WxOAuth2Service {
* @return 用户对象 * @return 用户对象
* @throws WxErrorException . * @throws WxErrorException .
*/ */
WeChatOAuth2UserInfo getUserInfo(WeChatOAuth2AccessToken oAuth2AccessToken, String lang) throws WxErrorException; WxOAuth2UserInfo getUserInfo(WxOAuth2AccessToken oAuth2AccessToken, String lang) throws WxErrorException;
/** /**
* <pre> * <pre>
@ -78,6 +78,6 @@ public interface WxOAuth2Service {
* @param oAuth2AccessToken token对象 * @param oAuth2AccessToken token对象
* @return 是否有效 * @return 是否有效
*/ */
boolean validateAccessToken(WeChatOAuth2AccessToken oAuth2AccessToken); boolean validateAccessToken(WxOAuth2AccessToken oAuth2AccessToken);
} }

View File

@ -1,16 +1,17 @@
package com.ossez.wechat.common.util; package com.ossez.wechat.common.util;
import com.ossez.wechat.common.api.WxErrorExceptionHandler;
import com.ossez.wechat.common.exception.WxErrorException; import com.ossez.wechat.common.exception.WxErrorException;
import org.slf4j.Logger; import lombok.extern.slf4j.Slf4j;
import org.slf4j.LoggerFactory; import com.ossez.wechat.common.api.WxErrorExceptionHandler;
/**
* @author Daniel Qian
*/
@Slf4j
public class LogExceptionHandler implements WxErrorExceptionHandler { public class LogExceptionHandler implements WxErrorExceptionHandler {
private final Logger log = LoggerFactory.getLogger(LogExceptionHandler.class); @Override
public void handle(WxErrorException e) {
@Override log.error("Error happens", e);
public void handle(WxErrorException e) { }
log.error("App Error", e);
}
} }

View File

@ -0,0 +1,17 @@
package com.ossez.wechat.common.util;
public class RandomUtils {
private static final String RANDOM_STR = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
private static final java.util.Random RANDOM = new java.util.Random();
public static String getRandomStr() {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 16; i++) {
sb.append(RANDOM_STR.charAt(RANDOM.nextInt(RANDOM_STR.length())));
}
return sb.toString();
}
}

View File

@ -5,7 +5,7 @@ import com.google.gson.GsonBuilder;
import com.ossez.wechat.common.exception.WxError; import com.ossez.wechat.common.exception.WxError;
import com.ossez.wechat.common.model.WeChatAccessToken; import com.ossez.wechat.common.model.WeChatAccessToken;
import com.ossez.wechat.common.bean.WxNetCheckResult; import com.ossez.wechat.common.bean.WxNetCheckResult;
import com.ossez.wechat.common.model.entity.menu.WxMenu; import com.ossez.wechat.common.bean.menu.WxMenu;
import com.ossez.wechat.common.bean.result.WxMediaUploadResult; import com.ossez.wechat.common.bean.result.WxMediaUploadResult;
import java.util.Objects; import java.util.Objects;

View File

@ -9,10 +9,9 @@
package com.ossez.wechat.common.util.json; package com.ossez.wechat.common.util.json;
import com.google.gson.*; import com.google.gson.*;
import com.ossez.wechat.common.model.entity.builder.MenuButtonBuilder; import com.ossez.wechat.common.bean.menu.WxMenu;
import com.ossez.wechat.common.model.entity.menu.WxMenu; import com.ossez.wechat.common.bean.menu.WxMenuButton;
import com.ossez.wechat.common.model.entity.menu.MenuButton; import com.ossez.wechat.common.bean.menu.WxMenuRule;
import com.ossez.wechat.common.model.entity.menu.WxMenuRule;
import java.lang.reflect.Type; import java.lang.reflect.Type;
@ -20,16 +19,16 @@ import java.lang.reflect.Type;
/** /**
* @author Daniel Qian * @author Daniel Qian
*/ */
public class WxMenuGsonAdapter { public class WxMenuGsonAdapter implements JsonSerializer<WxMenu>, JsonDeserializer<WxMenu> {
// @Override @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();
JsonArray buttonArray = new JsonArray(); JsonArray buttonArray = new JsonArray();
for (MenuButton button : menu.getButtons()) { for (WxMenuButton button : menu.getButtons()) {
// JsonObject buttonJson = convertToJson(button); JsonObject buttonJson = convertToJson(button);
// buttonArray.add(buttonJson); buttonArray.add(buttonJson);
} }
json.add("button", buttonArray); json.add("button", buttonArray);
@ -40,25 +39,25 @@ public class WxMenuGsonAdapter {
return json; return json;
} }
// protected JsonObject convertToJson(MenuButton button) { protected JsonObject convertToJson(WxMenuButton button) {
// JsonObject buttonJson = new JsonObject(); JsonObject buttonJson = new JsonObject();
// buttonJson.addProperty("type", button.getType()); buttonJson.addProperty("type", button.getType());
// buttonJson.addProperty("name", button.getName()); buttonJson.addProperty("name", button.getName());
// buttonJson.addProperty("key", button.getKey()); buttonJson.addProperty("key", button.getKey());
// buttonJson.addProperty("url", button.getUrl()); buttonJson.addProperty("url", button.getUrl());
// buttonJson.addProperty("media_id", button.getMediaId()); buttonJson.addProperty("media_id", button.getMediaId());
// buttonJson.addProperty("article_id", button.getArticleId()); buttonJson.addProperty("article_id", button.getArticleId());
// buttonJson.addProperty("appid", button.getAppId()); buttonJson.addProperty("appid", button.getAppId());
// buttonJson.addProperty("pagepath", button.getPagePath()); buttonJson.addProperty("pagepath", button.getPagePath());
// if (button.getSubButtons() != null && button.getSubButtons().size() > 0) { if (button.getSubButtons() != null && button.getSubButtons().size() > 0) {
// JsonArray buttonArray = new JsonArray(); JsonArray buttonArray = new JsonArray();
// for (MenuButton sub_button : button.getSubButtons()) { for (WxMenuButton sub_button : button.getSubButtons()) {
// buttonArray.add(convertToJson(sub_button)); buttonArray.add(convertToJson(sub_button));
// } }
// buttonJson.add("sub_button", buttonArray); buttonJson.add("sub_button", buttonArray);
// } }
// return buttonJson; return buttonJson;
// } }
protected JsonObject convertToJson(WxMenuRule menuRule) { protected JsonObject convertToJson(WxMenuRule menuRule) {
JsonObject matchRule = new JsonObject(); JsonObject matchRule = new JsonObject();
@ -87,47 +86,47 @@ public class WxMenuGsonAdapter {
return menuRule; return menuRule;
} }
// @Override @Override
// public WxMenu deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { public WxMenu deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
// /* /*
// * 操蛋的微信 * 操蛋的微信
// * 创建菜单时是 { button : ... } * 创建菜单时是 { button : ... }
// * 查询菜单时是 { menu : { button : ... } } * 查询菜单时是 { menu : { button : ... } }
// * 现在企业号升级为企业微信后没有此问题因此需要单独处理 * 现在企业号升级为企业微信后没有此问题因此需要单独处理
// */ */
// JsonArray buttonsJson = json.getAsJsonObject().get("menu").getAsJsonObject().get("button").getAsJsonArray(); JsonArray buttonsJson = json.getAsJsonObject().get("menu").getAsJsonObject().get("button").getAsJsonArray();
// return this.buildMenuFromJson(buttonsJson); return this.buildMenuFromJson(buttonsJson);
// } }
// protected WxMenu buildMenuFromJson(JsonArray buttonsJson) { protected WxMenu buildMenuFromJson(JsonArray buttonsJson) {
// WxMenu menu = new WxMenu(); WxMenu menu = new WxMenu();
// for (int i = 0; i < buttonsJson.size(); i++) { for (int i = 0; i < buttonsJson.size(); i++) {
// JsonObject buttonJson = buttonsJson.get(i).getAsJsonObject(); JsonObject buttonJson = buttonsJson.get(i).getAsJsonObject();
// MenuButton button = convertFromJson(buttonJson); WxMenuButton button = convertFromJson(buttonJson);
// menu.getButtons().add(button); menu.getButtons().add(button);
// if (buttonJson.get("sub_button") == null || buttonJson.get("sub_button").isJsonNull()) { if (buttonJson.get("sub_button") == null || buttonJson.get("sub_button").isJsonNull()) {
// continue; continue;
// } }
// JsonArray sub_buttonsJson = buttonJson.get("sub_button").getAsJsonArray(); JsonArray sub_buttonsJson = buttonJson.get("sub_button").getAsJsonArray();
// for (int j = 0; j < sub_buttonsJson.size(); j++) { for (int j = 0; j < sub_buttonsJson.size(); j++) {
// JsonObject sub_buttonJson = sub_buttonsJson.get(j).getAsJsonObject(); JsonObject sub_buttonJson = sub_buttonsJson.get(j).getAsJsonObject();
// button.getSubButtons().add(convertFromJson(sub_buttonJson)); button.getSubButtons().add(convertFromJson(sub_buttonJson));
// } }
// } }
// return menu; return menu;
// } }
// protected MenuButton convertFromJson(JsonObject json) { protected WxMenuButton convertFromJson(JsonObject json) {
// MenuButton button = new MenuButtonBuilder().createMenuButton(); WxMenuButton button = new WxMenuButton();
// button.setName(GsonHelper.getString(json, "name")); button.setName(GsonHelper.getString(json, "name"));
// button.setKey(GsonHelper.getString(json, "key")); button.setKey(GsonHelper.getString(json, "key"));
// button.setUrl(GsonHelper.getString(json, "url")); button.setUrl(GsonHelper.getString(json, "url"));
// button.setType(GsonHelper.getString(json, "type")); button.setType(GsonHelper.getString(json, "type"));
// button.setMediaId(GsonHelper.getString(json, "media_id")); button.setMediaId(GsonHelper.getString(json, "media_id"));
// button.setArticleId(GsonHelper.getString(json, "article_id")); button.setArticleId(GsonHelper.getString(json, "article_id"));
// button.setAppId(GsonHelper.getString(json, "appid")); button.setAppId(GsonHelper.getString(json, "appid"));
// button.setPagePath(GsonHelper.getString(json, "pagepath")); button.setPagePath(GsonHelper.getString(json, "pagepath"));
// return button; return button;
// } }
} }

View File

@ -1,14 +1,11 @@
package com.ossez.wechat.common.api; package com.ossez.wechat.common.api;
import lombok.extern.slf4j.Slf4j; import org.testng.annotations.Test;
import org.junit.jupiter.api.TestInstance;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import static org.assertj.core.api.Assertions.assertThat; import static org.testng.Assert.assertFalse;
import static org.junit.jupiter.api.Assertions.assertFalse; import static org.testng.Assert.assertTrue;
/** /**
* @author jiangby * @author jiangby
@ -16,8 +13,7 @@ import static org.junit.jupiter.api.Assertions.assertFalse;
* @description: 作用 * @description: 作用
* created on 2022/5/26 1:46 * created on 2022/5/26 1:46
*/ */
@TestInstance(TestInstance.Lifecycle.PER_CLASS) @Test
@Slf4j
public class WxMessageInMemoryDuplicateCheckerSingletonTest { public class WxMessageInMemoryDuplicateCheckerSingletonTest {
private static WxMessageInMemoryDuplicateCheckerSingleton checkerSingleton = WxMessageInMemoryDuplicateCheckerSingleton.getInstance(); private static WxMessageInMemoryDuplicateCheckerSingleton checkerSingleton = WxMessageInMemoryDuplicateCheckerSingleton.getInstance();
@ -28,14 +24,14 @@ public class WxMessageInMemoryDuplicateCheckerSingletonTest {
// 第一次检查 // 第一次检查
for (Long msgId : msgIds) { for (Long msgId : msgIds) {
boolean result = checkerSingleton.isDuplicate(String.valueOf(msgId)); boolean result = checkerSingleton.isDuplicate(String.valueOf(msgId));
assertThat(result).isFalse(); assertFalse(result);
} }
// 初始化后1S进行检查 每五秒检查一次过期时间为15秒过15秒再检查 // 初始化后1S进行检查 每五秒检查一次过期时间为15秒过15秒再检查
TimeUnit.SECONDS.sleep(15); TimeUnit.SECONDS.sleep(15);
for (Long msgId : msgIds) { for (Long msgId : msgIds) {
boolean result = checkerSingleton.isDuplicate(String.valueOf(msgId)); boolean result = checkerSingleton.isDuplicate(String.valueOf(msgId));
assertThat(result).isTrue(); assertTrue(result);
} }
// 过6秒再检查 // 过6秒再检查

View File

@ -1,41 +1,39 @@
package com.ossez.wechat.common.api; package com.ossez.wechat.common.api;
import lombok.extern.slf4j.Slf4j; import org.testng.annotations.Test;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import static org.assertj.core.api.Assertions.assertThat; import static org.testng.Assert.assertFalse;
import static org.testng.Assert.assertTrue;
@TestInstance(Lifecycle.PER_CLASS) @Test
@Slf4j
public class WxMessageInMemoryDuplicateCheckerTest { public class WxMessageInMemoryDuplicateCheckerTest {
private WxMessageInMemoryDuplicateChecker checker = new WxMessageInMemoryDuplicateChecker(2000L, 1000L); private WxMessageInMemoryDuplicateChecker checker = new WxMessageInMemoryDuplicateChecker(2000L, 1000L);
@Test public void test() throws InterruptedException {
public void test() throws InterruptedException { Long[] msgIds = new Long[]{1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L};
Long[] msgIds = new Long[]{1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L};
// 第一次检查 // 第一次检查
for (Long msgId : msgIds) { for (Long msgId : msgIds) {
boolean result = checker.isDuplicate(String.valueOf(msgId)); boolean result = checker.isDuplicate(String.valueOf(msgId));
assertThat(result).isFalse(); assertFalse(result);
}
// 过1秒再检查
TimeUnit.SECONDS.sleep(1);
for (Long msgId : msgIds) {
boolean result = checker.isDuplicate(String.valueOf(msgId));
assertThat(result).isTrue();
}
// 过1.5秒再检查
TimeUnit.MILLISECONDS.sleep(1500L);
for (Long msgId : msgIds) {
boolean result = checker.isDuplicate(String.valueOf(msgId));
assertThat(result).isFalse();
}
} }
// 过1秒再检查
TimeUnit.SECONDS.sleep(1);
for (Long msgId : msgIds) {
boolean result = checker.isDuplicate(String.valueOf(msgId));
assertTrue(result);
}
// 过1.5秒再检查
TimeUnit.MILLISECONDS.sleep(1500L);
for (Long msgId : msgIds) {
boolean result = checker.isDuplicate(String.valueOf(msgId));
assertFalse(result);
}
}
} }

View File

@ -1,40 +1,35 @@
package com.ossez.wechat.common.exception; package com.ossez.wechat.common.exception;
import com.ossez.wechat.common.enums.WxType; import com.ossez.wechat.common.enums.WxType;
import lombok.extern.slf4j.Slf4j; import org.testng.annotations.Test;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import static org.assertj.core.api.Assertions.assertThat; import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
@TestInstance(TestInstance.Lifecycle.PER_CLASS) @Test
@Slf4j
public class WxErrorTest { public class WxErrorTest {
@Test
public void testFromJson() { public void testFromJson() {
String json = "{ \"errcode\": 40003, \"errmsg\": \"invalid openid\" }"; String json = "{ \"errcode\": 40003, \"errmsg\": \"invalid openid\" }";
WxError wxError = WxError.fromJson(json, WxType.MP); WxError wxError = WxError.fromJson(json, WxType.MP);
assertThat(40003).isEqualTo(wxError.getErrorCode()); assertEquals(40003, wxError.getErrorCode());
// assertEquals(wxError.getErrorMsgEn(), "invalid openid"); assertEquals(wxError.getErrorMsgEn(), "invalid openid");
} }
// @Test public void testFromBadJson1() {
// public void testFromBadJson1() { String json = "{ \"errcode\": 40003, \"errmsg\": \"invalid openid\", \"media_id\": \"12323423dsfafsf232f\" }";
// String json = "{ \"errcode\": 40003, \"errmsg\": \"invalid openid\", \"media_id\": \"12323423dsfafsf232f\" }"; WxError wxError = WxError.fromJson(json, WxType.MP);
// WxError wxError = WxError.fromJson(json, WxType.MP); assertEquals(40003, wxError.getErrorCode());
// assertEquals(40003, wxError.getErrorCode()); assertEquals(wxError.getErrorMsgEn(), "invalid openid");
// assertEquals(wxError.getErrorMsgEn(), "invalid openid");
// }
// }
// public void testFromBadJson2() {
// @Test String json = "{\"access_token\":\"ACCESS_TOKEN\",\"expires_in\":7200}";
// public void testFromBadJson2() { WxError wxError = WxError.fromJson(json, WxType.MP);
// String json = "{\"access_token\":\"ACCESS_TOKEN\",\"expires_in\":7200}"; assertEquals(0, wxError.getErrorCode());
// WxError wxError = WxError.fromJson(json, WxType.MP); assertNull(wxError.getErrorMsg());
// assertEquals(0, wxError.getErrorCode());
// assertNull(wxError.getErrorMsg()); }
//
// }
} }

View File

@ -1,9 +1,8 @@
package com.ossez.wechat.common.model; package com.ossez.wechat.common.model;
import com.ossez.wechat.common.model.entity.builder.MenuButtonBuilder; import com.ossez.wechat.common.bean.menu.WxMenu;
import com.ossez.wechat.common.model.entity.menu.WxMenu; import com.ossez.wechat.common.bean.menu.WxMenuButton;
import com.ossez.wechat.common.model.entity.menu.MenuButton; import com.ossez.wechat.common.bean.menu.WxMenuRule;
import com.ossez.wechat.common.model.entity.menu.WxMenuRule;
import org.testng.*; import org.testng.*;
import org.testng.annotations.*; import org.testng.annotations.*;
@ -19,41 +18,41 @@ public class WxMenuTest {
@Test(dataProvider = "wxPushMenu") @Test(dataProvider = "wxPushMenu")
public void testToJson(String json) { public void testToJson(String json) {
WxMenu menu = new WxMenu(); WxMenu menu = new WxMenu();
MenuButton button1 = new MenuButtonBuilder().createMenuButton(); WxMenuButton button1 = new WxMenuButton();
button1.setType("click"); button1.setType("click");
button1.setName("今日歌曲"); button1.setName("今日歌曲");
button1.setKey("V1001_TODAY_MUSIC"); button1.setKey("V1001_TODAY_MUSIC");
MenuButton button2 = new MenuButtonBuilder().createMenuButton(); WxMenuButton button2 = new WxMenuButton();
button2.setType("click"); button2.setType("click");
button2.setName("歌手简介"); button2.setName("歌手简介");
button2.setKey("V1001_TODAY_SINGER"); button2.setKey("V1001_TODAY_SINGER");
MenuButton button3 = new MenuButtonBuilder().createMenuButton(); WxMenuButton button3 = new WxMenuButton();
button3.setName("菜单"); button3.setName("菜单");
menu.getButtons().add(button1); menu.getButtons().add(button1);
menu.getButtons().add(button2); menu.getButtons().add(button2);
menu.getButtons().add(button3); menu.getButtons().add(button3);
MenuButton button31 = new MenuButtonBuilder().createMenuButton(); WxMenuButton button31 = new WxMenuButton();
button31.setType("view"); button31.setType("view");
button31.setName("搜索"); button31.setName("搜索");
button31.setUrl("http://www.soso.com/"); button31.setUrl("http://www.soso.com/");
MenuButton button32 = new MenuButtonBuilder().createMenuButton(); WxMenuButton button32 = new WxMenuButton();
button32.setType("view"); button32.setType("view");
button32.setName("视频"); button32.setName("视频");
button32.setUrl("http://v.qq.com/"); button32.setUrl("http://v.qq.com/");
MenuButton button33 = new MenuButtonBuilder().createMenuButton(); WxMenuButton button33 = new WxMenuButton();
button33.setType("click"); button33.setType("click");
button33.setName("赞一下我们"); button33.setName("赞一下我们");
button33.setKey("V1001_GOOD"); button33.setKey("V1001_GOOD");
// button3.getSubButtons().add(button31); button3.getSubButtons().add(button31);
// button3.getSubButtons().add(button32); button3.getSubButtons().add(button32);
// button3.getSubButtons().add(button33); button3.getSubButtons().add(button33);
Assert.assertEquals(menu.toJson(), json); Assert.assertEquals(menu.toJson(), json);
} }
@ -61,7 +60,7 @@ public class WxMenuTest {
@Test(dataProvider = "wxAddConditionalMenu") @Test(dataProvider = "wxAddConditionalMenu")
public void testAddConditionalToJson(String json) { public void testAddConditionalToJson(String json) {
WxMenu menu = new WxMenu(); WxMenu menu = new WxMenu();
MenuButton button1 = new MenuButtonBuilder().createMenuButton(); WxMenuButton button1 = new WxMenuButton();
button1.setType("click"); button1.setType("click");
button1.setName("今日歌曲"); button1.setName("今日歌曲");
button1.setKey("V1001_TODAY_MUSIC"); button1.setKey("V1001_TODAY_MUSIC");

View File

@ -1,141 +1,151 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<project <project
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 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" 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="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.ossez.wechat</groupId>
<artifactId>wechat-j-mp</artifactId>
<packaging>jar</packaging>
<parent>
<groupId>com.ossez.wechat</groupId> <groupId>com.ossez.wechat</groupId>
<artifactId>wechat-j-mp</artifactId> <artifactId>wechat-j</artifactId>
<packaging>jar</packaging> <version>0.0.1-SNAPSHOT</version>
</parent>
<parent> <name>WeChat Java Mini Program</name>
<groupId>com.ossez.wechat</groupId> <description>The module is WeChat Mini Program</description>
<artifactId>wechat-j</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<name>WeChat Java Mini Program</name>
<description>The module is WeChat Mini Program</description>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>com.ossez.wechat</groupId> <groupId>com.ossez.wechat</groupId>
<artifactId>wechat-j-common</artifactId> <artifactId>wechat-j-common</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.jodd</groupId> <groupId>org.jodd</groupId>
<artifactId>jodd-http</artifactId> <artifactId>jodd-http</artifactId>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>com.google.inject</groupId> <groupId>org.testng</groupId>
<artifactId>guice</artifactId> <artifactId>testng</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.eclipse.jetty</groupId> <groupId>org.mockito</groupId>
<artifactId>jetty-server</artifactId> <artifactId>mockito-all</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.eclipse.jetty</groupId> <groupId>com.google.inject</groupId>
<artifactId>jetty-servlet</artifactId> <artifactId>guice</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>joda-time</groupId> <groupId>org.eclipse.jetty</groupId>
<artifactId>joda-time</artifactId> <artifactId>jetty-server</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
<groupId>redis.clients</groupId> <groupId>org.eclipse.jetty</groupId>
<artifactId>jedis</artifactId> <artifactId>jetty-servlet</artifactId>
</dependency> <scope>test</scope>
<dependency> </dependency>
<groupId>ch.qos.logback</groupId> <dependency>
<artifactId>logback-classic</artifactId> <groupId>joda-time</groupId>
<scope>test</scope> <artifactId>joda-time</artifactId>
</dependency> <scope>test</scope>
<dependency> </dependency>
<groupId>org.assertj</groupId> <dependency>
<artifactId>assertj-guava</artifactId> <groupId>redis.clients</groupId>
<scope>test</scope> <artifactId>jedis</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.projectlombok</groupId> <groupId>ch.qos.logback</groupId>
<artifactId>lombok</artifactId> <artifactId>logback-classic</artifactId>
</dependency> <scope>test</scope>
<dependency> </dependency>
<groupId>org.redisson</groupId> <dependency>
<artifactId>redisson</artifactId> <groupId>org.assertj</groupId>
</dependency> <artifactId>assertj-guava</artifactId>
<dependency> <scope>test</scope>
<groupId>com.fasterxml.jackson.dataformat</groupId> </dependency>
<artifactId>jackson-dataformat-xml</artifactId> <dependency>
<optional>true</optional> <groupId>org.projectlombok</groupId>
</dependency> <artifactId>lombok</artifactId>
<dependency> </dependency>
<groupId>org.bouncycastle</groupId> <dependency>
<artifactId>bcprov-jdk15on</artifactId> <groupId>org.redisson</groupId>
<version>1.70</version> <artifactId>redisson</artifactId>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.mockito</groupId> <groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>mockito-core</artifactId> <artifactId>jackson-dataformat-xml</artifactId>
<version>4.11.0</version> <optional>true</optional>
<scope>test</scope> </dependency>
</dependency> <dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcprov-jdk15on</artifactId>
<version>1.70</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>4.11.0</version>
<scope>test</scope>
</dependency>
</dependencies> </dependencies>
<build> <build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>native-image</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId> <artifactId>maven-compiler-plugin</artifactId>
<configuration> <version>3.5.1</version>
<suiteXmlFiles> <configuration>
<suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile> <annotationProcessors>
</suiteXmlFiles> com.github.binarywang.wx.graal.GraalProcessor,lombok.launch.AnnotationProcessorHider$AnnotationProcessor,lombok.launch.AnnotationProcessorHider$ClaimingProcessor
</configuration> </annotationProcessors>
</plugin> <annotationProcessorPaths>
<path>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-graal</artifactId>
<version>${project.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins> </plugins>
</build> </build>
</profile>
<profiles> </profiles>
<profile>
<id>native-image</id>
<activation>
<activeByDefault>false</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<annotationProcessors>
com.github.binarywang.wx.graal.GraalProcessor,lombok.launch.AnnotationProcessorHider$AnnotationProcessor,lombok.launch.AnnotationProcessorHider$ClaimingProcessor
</annotationProcessors>
<annotationProcessorPaths>
<path>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-graal</artifactId>
<version>${project.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project> </project>

View File

@ -6,9 +6,9 @@ import com.google.gson.JsonObject;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import com.ossez.wechat.common.bean.WxJsapiSignature; import com.ossez.wechat.common.bean.WxJsapiSignature;
import com.ossez.wechat.common.exception.WxErrorException; import com.ossez.wechat.common.exception.WxErrorException;
import com.ossez.wechat.common.util.RandomUtils;
import com.ossez.wechat.common.util.crypto.SHA1; import com.ossez.wechat.common.util.crypto.SHA1;
import com.ossez.wechat.common.util.json.GsonParser; import com.ossez.wechat.common.util.json.GsonParser;
import org.apache.commons.lang3.RandomStringUtils;
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock;
@ -84,7 +84,7 @@ public class WxMaJsapiServiceImpl implements WxMaJsapiService {
@Override @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 randomStr = RandomStringUtils.randomAlphanumeric(16); String randomStr = RandomUtils.getRandomStr();
String jsapiTicket = getJsapiTicket(false); String jsapiTicket = getJsapiTicket(false);
String signature = SHA1.genWithAmple("jsapi_ticket=" + jsapiTicket, String signature = SHA1.genWithAmple("jsapi_ticket=" + jsapiTicket,
"noncestr=" + randomStr, "timestamp=" + timestamp, "url=" + url); "noncestr=" + randomStr, "timestamp=" + timestamp, "url=" + url);

View File

@ -31,6 +31,21 @@
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.inject</groupId>
<artifactId>guice</artifactId>
<scope>test</scope>
</dependency>
<dependency> <dependency>
<groupId>org.eclipse.jetty</groupId> <groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId> <artifactId>jetty-server</artifactId>
@ -84,6 +99,10 @@
<version>4.11.0</version> <version>4.11.0</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>retrofit</artifactId>
</dependency>
</dependencies> </dependencies>

View File

@ -16,8 +16,8 @@ import com.ossez.wechat.oa.bean.WxMpSemanticQuery;
import com.ossez.wechat.oa.bean.result.WxMpCurrentAutoReplyInfo; import com.ossez.wechat.oa.bean.result.WxMpCurrentAutoReplyInfo;
import com.ossez.wechat.oa.bean.result.WxMpShortKeyResult; import com.ossez.wechat.oa.bean.result.WxMpShortKeyResult;
import com.ossez.wechat.oa.bean.result.WxMpSemanticQueryResult; import com.ossez.wechat.oa.bean.result.WxMpSemanticQueryResult;
import com.ossez.wechat.common.config.ConfigStorage; import com.ossez.wechat.oa.config.ConfigStorage;
import com.ossez.wechat.common.enums.WxMpApiUrl; import com.ossez.wechat.oa.enums.WxMpApiUrl;
import java.util.Map; import java.util.Map;

View File

@ -3,7 +3,7 @@ package com.ossez.wechat.oa.api;
import java.io.File; import java.io.File;
import com.ossez.wechat.common.exception.WxErrorException; import com.ossez.wechat.common.exception.WxErrorException;
import com.ossez.wechat.common.enums.Language; import com.ossez.wechat.oa.enums.AiLangType;
/** /**
* <pre> * <pre>
@ -27,7 +27,7 @@ public interface WxMpAiOpenService {
* @param voiceFile 语音文件 * @param voiceFile 语音文件
* @param voiceId 语音唯一标识 * @param voiceId 语音唯一标识
*/ */
void uploadVoice(String voiceId, Language lang, File voiceFile) throws WxErrorException; void uploadVoice(String voiceId, AiLangType lang, File voiceFile) throws WxErrorException;
/** /**
* <pre> * <pre>
@ -42,7 +42,7 @@ public interface WxMpAiOpenService {
* @param lang 语言zh_CN en_US默认中文 * @param lang 语言zh_CN en_US默认中文
* @param voiceId 语音唯一标识 * @param voiceId 语音唯一标识
*/ */
String queryRecognitionResult(String voiceId, Language lang) throws WxErrorException; String queryRecognitionResult(String voiceId, AiLangType lang) throws WxErrorException;
/** /**
* 识别指定语音文件内容. * 识别指定语音文件内容.
@ -52,7 +52,7 @@ public interface WxMpAiOpenService {
* @param voiceFile 语音文件 * @param voiceFile 语音文件
* @param voiceId 语音唯一标识 * @param voiceId 语音唯一标识
*/ */
String recogniseVoice(String voiceId, Language lang, File voiceFile) throws WxErrorException; String recogniseVoice(String voiceId, AiLangType lang, File voiceFile) throws WxErrorException;
/** /**
* <pre> * <pre>
@ -68,5 +68,5 @@ public interface WxMpAiOpenService {
* @param langTo 目标语言zh_CN en_US * @param langTo 目标语言zh_CN en_US
* @param content 要翻译的文本内容 * @param content 要翻译的文本内容
*/ */
String translate(Language langFrom, Language langTo, String content) throws WxErrorException; String translate(AiLangType langFrom, AiLangType langTo, String content) throws WxErrorException;
} }

View File

@ -1,6 +1,6 @@
package com.ossez.wechat.oa.api; package com.ossez.wechat.oa.api;
import com.ossez.wechat.common.model.entity.menu.WxMenu; import com.ossez.wechat.common.bean.menu.WxMenu;
import com.ossez.wechat.common.exception.WxErrorException; import com.ossez.wechat.common.exception.WxErrorException;
import com.ossez.wechat.oa.bean.menu.WxMpGetSelfMenuInfoResult; import com.ossez.wechat.oa.bean.menu.WxMpGetSelfMenuInfoResult;
import com.ossez.wechat.oa.bean.menu.WxMpMenu; import com.ossez.wechat.oa.bean.menu.WxMpMenu;

View File

@ -4,7 +4,6 @@ import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
import com.google.gson.JsonArray; import com.google.gson.JsonArray;
import com.google.gson.JsonObject; import com.google.gson.JsonObject;
import com.ossez.wechat.common.config.ConfigStorage;
import com.ossez.wechat.common.constant.WeChatConstant; import com.ossez.wechat.common.constant.WeChatConstant;
import com.ossez.wechat.common.bean.ToJson; import com.ossez.wechat.common.bean.ToJson;
import com.ossez.wechat.common.model.WeChatAccessToken; import com.ossez.wechat.common.model.WeChatAccessToken;
@ -21,30 +20,29 @@ import com.ossez.wechat.common.service.WxOcrService;
import com.ossez.wechat.common.session.StandardSessionManager; import com.ossez.wechat.common.session.StandardSessionManager;
import com.ossez.wechat.common.session.WxSessionManager; import com.ossez.wechat.common.session.WxSessionManager;
import com.ossez.wechat.common.util.DataUtils; import com.ossez.wechat.common.util.DataUtils;
import com.ossez.wechat.common.util.RandomUtils;
import com.ossez.wechat.common.util.crypto.SHA1; import com.ossez.wechat.common.util.crypto.SHA1;
import com.ossez.wechat.common.util.http.*; import com.ossez.wechat.common.util.http.*;
import com.ossez.wechat.common.util.json.GsonParser; import com.ossez.wechat.common.util.json.GsonParser;
import com.ossez.wechat.common.util.json.WxGsonBuilder; import com.ossez.wechat.common.util.json.WxGsonBuilder;
import com.ossez.wechat.oa.api.*; import com.ossez.wechat.oa.api.*;
import com.ossez.wechat.oa.api.impl.okhttp.WeChatMsgService;
import com.ossez.wechat.oa.bean.WxMpSemanticQuery; import com.ossez.wechat.oa.bean.WxMpSemanticQuery;
import com.ossez.wechat.oa.bean.result.WxMpCurrentAutoReplyInfo; import com.ossez.wechat.oa.bean.result.WxMpCurrentAutoReplyInfo;
import com.ossez.wechat.oa.bean.result.WxMpSemanticQueryResult; import com.ossez.wechat.oa.bean.result.WxMpSemanticQueryResult;
import com.ossez.wechat.oa.bean.result.WxMpShortKeyResult; import com.ossez.wechat.oa.bean.result.WxMpShortKeyResult;
import com.ossez.wechat.common.enums.WxMpApiUrl; import com.ossez.wechat.oa.config.ConfigStorage;
import com.ossez.wechat.oa.enums.WxMpApiUrl;
import com.ossez.wechat.oa.util.WxMpConfigStorageHolder; import com.ossez.wechat.oa.util.WxMpConfigStorageHolder;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.Lock;
import static com.ossez.wechat.common.enums.WxMpApiUrl.Other.*; import static com.ossez.wechat.oa.enums.WxMpApiUrl.Other.*;
/** /**
* 基础实现类. * 基础实现类.
@ -56,8 +54,6 @@ public abstract class BaseWeChatOfficialAccountServiceImpl<H, P> implements WeCh
protected WxSessionManager sessionManager = new StandardSessionManager(); protected WxSessionManager sessionManager = new StandardSessionManager();
@Getter @Getter
@Setter @Setter
private WxMpKefuService kefuService = new WxMpKefuServiceImpl(this); private WxMpKefuService kefuService = new WxMpKefuServiceImpl(this);
@ -160,7 +156,7 @@ public abstract class BaseWeChatOfficialAccountServiceImpl<H, P> implements WeCh
@Setter @Setter
private WxMpFreePublishService freePublishService = new WxMpFreePublishServiceImpl(this); private WxMpFreePublishService freePublishService = new WxMpFreePublishServiceImpl(this);
private Map<String, ConfigStorage> configStorageMap = new HashMap<>(); private Map<String, ConfigStorage> configStorageMap;
private int retrySleepMillis = 1000; private int retrySleepMillis = 1000;
private int maxRetryTimes = 5; private int maxRetryTimes = 5;
@ -239,7 +235,7 @@ public abstract class BaseWeChatOfficialAccountServiceImpl<H, P> implements WeCh
@Override @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 randomStr = RandomStringUtils.randomAlphanumeric(16); String randomStr = RandomUtils.getRandomStr();
String jsapiTicket = getJsapiTicket(false); String jsapiTicket = getJsapiTicket(false);
String signature = SHA1.genWithAmple("jsapi_ticket=" + jsapiTicket, String signature = SHA1.genWithAmple("jsapi_ticket=" + jsapiTicket,
"noncestr=" + randomStr, "timestamp=" + timestamp, "url=" + url); "noncestr=" + randomStr, "timestamp=" + timestamp, "url=" + url);

View File

@ -0,0 +1,107 @@
package com.ossez.wechat.oa.api.impl;
import com.ossez.wechat.common.exception.WxErrorException;
import com.ossez.wechat.common.exception.WxRuntimeException;
import com.ossez.wechat.common.util.http.HttpType;
import com.ossez.wechat.common.util.http.apache.ApacheHttpClientBuilder;
import com.ossez.wechat.common.util.http.apache.DefaultApacheHttpClientBuilder;
import com.ossez.wechat.oa.config.ConfigStorage;
import org.apache.http.HttpHost;
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 java.io.IOException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import static com.ossez.wechat.oa.enums.WxMpApiUrl.Other.GET_ACCESS_TOKEN_URL;
/**
* apache http client方式实现.
*
* @author someone
*/
public class WeChatOfficialAccountServiceHttpClientImpl extends BaseWeChatOfficialAccountServiceImpl<CloseableHttpClient, HttpHost> {
private CloseableHttpClient httpClient;
private HttpHost httpProxy;
@Override
public CloseableHttpClient getRequestHttpClient() {
return httpClient;
}
@Override
public HttpHost getRequestHttpProxy() {
return httpProxy;
}
@Override
public HttpType getRequestType() {
return HttpType.APACHE_HTTP;
}
@Override
public void initHttp() {
ConfigStorage configStorage = this.getWxMpConfigStorage();
ApacheHttpClientBuilder apacheHttpClientBuilder = configStorage.getApacheHttpClientBuilder();
if (null == apacheHttpClientBuilder) {
apacheHttpClientBuilder = DefaultApacheHttpClientBuilder.get();
}
apacheHttpClientBuilder.httpProxyHost(configStorage.getHttpProxyHost())
.httpProxyPort(configStorage.getHttpProxyPort())
.httpProxyUsername(configStorage.getHttpProxyUsername())
.httpProxyPassword(configStorage.getHttpProxyPassword());
if (configStorage.getHttpProxyHost() != null && configStorage.getHttpProxyPort() > 0) {
this.httpProxy = new HttpHost(configStorage.getHttpProxyHost(), configStorage.getHttpProxyPort());
}
this.httpClient = apacheHttpClientBuilder.build();
}
@Override
public String getAccessToken(boolean forceRefresh) throws WxErrorException {
final ConfigStorage config = this.getWxMpConfigStorage();
if (!config.isAccessTokenExpired() && !forceRefresh) {
return config.getAccessToken();
}
Lock lock = config.getAccessTokenLock();
boolean locked = false;
try {
do {
locked = lock.tryLock(100, TimeUnit.MILLISECONDS);
if (!forceRefresh && !config.isAccessTokenExpired()) {
return config.getAccessToken();
}
} while (!locked);
String url = String.format(GET_ACCESS_TOKEN_URL.getUrl(config), config.getAppId(), config.getSecret());
try {
HttpGet httpGet = new HttpGet(url);
if (this.getRequestHttpProxy() != null) {
RequestConfig requestConfig = RequestConfig.custom().setProxy(this.getRequestHttpProxy()).build();
httpGet.setConfig(requestConfig);
}
try (CloseableHttpResponse response = getRequestHttpClient().execute(httpGet)) {
return this.extractAccessToken(new BasicResponseHandler().handleResponse(response));
} finally {
httpGet.releaseConnection();
}
} catch (IOException e) {
throw new WxRuntimeException(e);
}
} catch (InterruptedException e) {
throw new WxRuntimeException(e);
} finally {
if (locked) {
lock.unlock();
}
}
}
}

View File

@ -0,0 +1,12 @@
package com.ossez.wechat.oa.api.impl;
/**
* <pre>
* 默认接口实现类使用apache httpclient实现
* Created by Binary Wang on 2017-5-27.
* </pre>
*
* @author <a href="https://github.com/binarywang">Binary Wang</a>
*/
public class WeChatOfficialAccountServiceImpl extends WeChatOfficialAccountServiceHttpClientImpl {
}

View File

@ -7,12 +7,12 @@ import com.ossez.wechat.common.exception.WxErrorException;
import com.ossez.wechat.common.util.json.GsonParser; import com.ossez.wechat.common.util.json.GsonParser;
import com.ossez.wechat.oa.api.WxMpAiOpenService; import com.ossez.wechat.oa.api.WxMpAiOpenService;
import com.ossez.wechat.oa.api.WeChatOfficialAccountService; import com.ossez.wechat.oa.api.WeChatOfficialAccountService;
import com.ossez.wechat.common.enums.Language; import com.ossez.wechat.oa.enums.AiLangType;
import com.ossez.wechat.oa.util.requestexecuter.voice.VoiceUploadRequestExecutor; import com.ossez.wechat.oa.util.requestexecuter.voice.VoiceUploadRequestExecutor;
import java.io.File; import java.io.File;
import static com.ossez.wechat.common.enums.WxMpApiUrl.AiOpen.*; import static com.ossez.wechat.oa.enums.WxMpApiUrl.AiOpen.*;
/** /**
* <pre> * <pre>
@ -26,9 +26,9 @@ public class WxMpAiOpenServiceImpl implements WxMpAiOpenService {
private final WeChatOfficialAccountService weChatOfficialAccountService; private final WeChatOfficialAccountService weChatOfficialAccountService;
@Override @Override
public void uploadVoice(String voiceId, Language lang, File voiceFile) throws WxErrorException { public void uploadVoice(String voiceId, AiLangType lang, File voiceFile) throws WxErrorException {
if (lang == null) { if (lang == null) {
lang = Language.ZH_CN; lang = AiLangType.zh_CN;
} }
this.weChatOfficialAccountService.execute(VoiceUploadRequestExecutor.create(this.weChatOfficialAccountService.getRequestHttp()), this.weChatOfficialAccountService.execute(VoiceUploadRequestExecutor.create(this.weChatOfficialAccountService.getRequestHttp()),
@ -37,13 +37,13 @@ public class WxMpAiOpenServiceImpl implements WxMpAiOpenService {
} }
@Override @Override
public String recogniseVoice(String voiceId, Language lang, File voiceFile) throws WxErrorException { public String recogniseVoice(String voiceId, AiLangType lang, File voiceFile) throws WxErrorException {
this.uploadVoice(voiceId, lang, voiceFile); this.uploadVoice(voiceId, lang, voiceFile);
return this.queryRecognitionResult(voiceId, lang); return this.queryRecognitionResult(voiceId, lang);
} }
@Override @Override
public String translate(Language langFrom, Language langTo, String content) throws WxErrorException { public String translate(AiLangType langFrom, AiLangType langTo, String content) throws WxErrorException {
String response = this.weChatOfficialAccountService.post(String.format(TRANSLATE_URL.getUrl(this.weChatOfficialAccountService.getWxMpConfigStorage()), String response = this.weChatOfficialAccountService.post(String.format(TRANSLATE_URL.getUrl(this.weChatOfficialAccountService.getWxMpConfigStorage()),
langFrom.getCode(), langTo.getCode()), content); langFrom.getCode(), langTo.getCode()), content);
@ -56,9 +56,9 @@ public class WxMpAiOpenServiceImpl implements WxMpAiOpenService {
} }
@Override @Override
public String queryRecognitionResult(String voiceId, Language lang) throws WxErrorException { public String queryRecognitionResult(String voiceId, AiLangType lang) throws WxErrorException {
if (lang == null) { if (lang == null) {
lang = Language.ZH_CN; lang = AiLangType.zh_CN;
} }
final String response = this.weChatOfficialAccountService.get(VOICE_QUERY_RESULT_URL, final String response = this.weChatOfficialAccountService.get(VOICE_QUERY_RESULT_URL,

View File

@ -8,16 +8,16 @@ import lombok.extern.slf4j.Slf4j;
import com.ossez.wechat.common.bean.WxCardApiSignature; import com.ossez.wechat.common.bean.WxCardApiSignature;
import com.ossez.wechat.common.exception.WxError; import com.ossez.wechat.common.exception.WxError;
import com.ossez.wechat.common.exception.WxErrorException; import com.ossez.wechat.common.exception.WxErrorException;
import com.ossez.wechat.common.util.RandomUtils;
import com.ossez.wechat.common.util.http.SimpleGetRequestExecutor; import com.ossez.wechat.common.util.http.SimpleGetRequestExecutor;
import com.ossez.wechat.common.util.json.GsonParser; import com.ossez.wechat.common.util.json.GsonParser;
import com.ossez.wechat.common.util.json.WxGsonBuilder; import com.ossez.wechat.common.util.json.WxGsonBuilder;
import com.ossez.wechat.oa.api.WxMpCardService; import com.ossez.wechat.oa.api.WxMpCardService;
import com.ossez.wechat.oa.api.WeChatOfficialAccountService; import com.ossez.wechat.oa.api.WeChatOfficialAccountService;
import com.ossez.wechat.common.enums.TicketType; import com.ossez.wechat.common.enums.TicketType;
import com.ossez.wechat.common.enums.WxMpApiUrl; import com.ossez.wechat.oa.enums.WxMpApiUrl;
import com.ossez.wechat.oa.util.json.WxMpGsonBuilder; import com.ossez.wechat.oa.util.json.WxMpGsonBuilder;
import org.apache.commons.codec.digest.DigestUtils; import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import java.util.Arrays; import java.util.Arrays;
@ -74,7 +74,7 @@ public class WxMpCardServiceImpl implements WxMpCardService {
@Override @Override
public WxCardApiSignature createCardApiSignature(String... optionalSignParam) throws WxErrorException { public WxCardApiSignature createCardApiSignature(String... optionalSignParam) throws WxErrorException {
long timestamp = System.currentTimeMillis() / 1000; long timestamp = System.currentTimeMillis() / 1000;
String nonceStr = RandomStringUtils.randomAlphanumeric(16); String nonceStr = RandomUtils.getRandomStr();
String cardApiTicket = getCardApiTicket(false); String cardApiTicket = getCardApiTicket(false);
String[] signParams = Arrays.copyOf(optionalSignParam, optionalSignParam.length + 3); String[] signParams = Arrays.copyOf(optionalSignParam, optionalSignParam.length + 3);

View File

@ -7,7 +7,7 @@ import com.ossez.wechat.oa.api.WxMpCommentService;
import com.ossez.wechat.oa.api.WeChatOfficialAccountService; import com.ossez.wechat.oa.api.WeChatOfficialAccountService;
import com.ossez.wechat.oa.bean.comment.WxMpCommentListVo; import com.ossez.wechat.oa.bean.comment.WxMpCommentListVo;
import static com.ossez.wechat.common.enums.WxMpApiUrl.Comment.*; import static com.ossez.wechat.oa.enums.WxMpApiUrl.Comment.*;
/** /**
* @author <a href="https://github.com/binarywang">Binary Wang</a> * @author <a href="https://github.com/binarywang">Binary Wang</a>

View File

@ -6,14 +6,14 @@ import lombok.RequiredArgsConstructor;
import com.ossez.wechat.common.exception.WxErrorException; import com.ossez.wechat.common.exception.WxErrorException;
import com.ossez.wechat.oa.api.WxMpDataCubeService; import com.ossez.wechat.oa.api.WxMpDataCubeService;
import com.ossez.wechat.oa.api.WeChatOfficialAccountService; import com.ossez.wechat.oa.api.WeChatOfficialAccountService;
import com.ossez.wechat.common.enums.WxMpApiUrl; import com.ossez.wechat.oa.enums.WxMpApiUrl;
import org.apache.commons.lang3.time.FastDateFormat; import org.apache.commons.lang3.time.FastDateFormat;
import java.text.Format; import java.text.Format;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import static com.ossez.wechat.common.enums.WxMpApiUrl.DataCube.*; import static com.ossez.wechat.oa.enums.WxMpApiUrl.DataCube.*;
/** /**
* Created by Binary Wang on 2016/8/23. * Created by Binary Wang on 2016/8/23.

View File

@ -7,7 +7,7 @@ import com.ossez.wechat.common.exception.WxErrorException;
import com.ossez.wechat.oa.api.WxMpDeviceService; import com.ossez.wechat.oa.api.WxMpDeviceService;
import com.ossez.wechat.oa.api.WeChatOfficialAccountService; import com.ossez.wechat.oa.api.WeChatOfficialAccountService;
import static com.ossez.wechat.common.enums.WxMpApiUrl.Device.*; import static com.ossez.wechat.oa.enums.WxMpApiUrl.Device.*;
/** /**
* Created by keungtung on 10/12/2016. * Created by keungtung on 10/12/2016.

View File

@ -11,7 +11,7 @@ import com.ossez.wechat.oa.bean.draft.WxMpDraftArticles;
import com.ossez.wechat.oa.bean.draft.WxMpDraftInfo; import com.ossez.wechat.oa.bean.draft.WxMpDraftInfo;
import com.ossez.wechat.oa.bean.draft.WxMpDraftList; import com.ossez.wechat.oa.bean.draft.WxMpDraftList;
import com.ossez.wechat.oa.bean.draft.WxMpUpdateDraft; import com.ossez.wechat.oa.bean.draft.WxMpUpdateDraft;
import com.ossez.wechat.common.enums.WxMpApiUrl; import com.ossez.wechat.oa.enums.WxMpApiUrl;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;

View File

@ -9,7 +9,7 @@ import com.ossez.wechat.oa.api.WeChatOfficialAccountService;
import com.ossez.wechat.oa.bean.freepublish.WxMpFreePublishInfo; import com.ossez.wechat.oa.bean.freepublish.WxMpFreePublishInfo;
import com.ossez.wechat.oa.bean.freepublish.WxMpFreePublishList; import com.ossez.wechat.oa.bean.freepublish.WxMpFreePublishList;
import com.ossez.wechat.oa.bean.freepublish.WxMpFreePublishStatus; import com.ossez.wechat.oa.bean.freepublish.WxMpFreePublishStatus;
import com.ossez.wechat.common.enums.WxMpApiUrl; import com.ossez.wechat.oa.enums.WxMpApiUrl;
/** /**
* 发布能力-service实现类. * 发布能力-service实现类.

View File

@ -9,7 +9,7 @@ import com.ossez.wechat.common.util.json.GsonParser;
import com.ossez.wechat.common.util.json.WxGsonBuilder; import com.ossez.wechat.common.util.json.WxGsonBuilder;
import com.ossez.wechat.oa.api.WxMpGuideBuyerService; import com.ossez.wechat.oa.api.WxMpGuideBuyerService;
import com.ossez.wechat.oa.api.WeChatOfficialAccountService; import com.ossez.wechat.oa.api.WeChatOfficialAccountService;
import com.ossez.wechat.common.enums.WxMpApiUrl; import com.ossez.wechat.oa.enums.WxMpApiUrl;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;

View File

@ -11,7 +11,7 @@ import com.ossez.wechat.common.util.json.GsonParser;
import com.ossez.wechat.common.util.json.WxGsonBuilder; import com.ossez.wechat.common.util.json.WxGsonBuilder;
import com.ossez.wechat.oa.api.WxMpGuideMassedJobService; import com.ossez.wechat.oa.api.WxMpGuideMassedJobService;
import com.ossez.wechat.oa.api.WeChatOfficialAccountService; import com.ossez.wechat.oa.api.WeChatOfficialAccountService;
import com.ossez.wechat.common.enums.WxMpApiUrl; import com.ossez.wechat.oa.enums.WxMpApiUrl;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;

View File

@ -11,7 +11,7 @@ import com.ossez.wechat.common.util.json.GsonParser;
import com.ossez.wechat.common.util.json.WxGsonBuilder; import com.ossez.wechat.common.util.json.WxGsonBuilder;
import com.ossez.wechat.oa.api.WxMpGuideMaterialService; import com.ossez.wechat.oa.api.WxMpGuideMaterialService;
import com.ossez.wechat.oa.api.WeChatOfficialAccountService; import com.ossez.wechat.oa.api.WeChatOfficialAccountService;
import com.ossez.wechat.common.enums.WxMpApiUrl; import com.ossez.wechat.oa.enums.WxMpApiUrl;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;

View File

@ -11,7 +11,7 @@ import com.ossez.wechat.common.util.json.GsonParser;
import com.ossez.wechat.common.util.json.WxGsonBuilder; import com.ossez.wechat.common.util.json.WxGsonBuilder;
import com.ossez.wechat.oa.api.WxMpGuideService; import com.ossez.wechat.oa.api.WxMpGuideService;
import com.ossez.wechat.oa.api.WeChatOfficialAccountService; import com.ossez.wechat.oa.api.WeChatOfficialAccountService;
import com.ossez.wechat.common.enums.WxMpApiUrl; import com.ossez.wechat.oa.enums.WxMpApiUrl;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;

View File

@ -11,7 +11,7 @@ import com.ossez.wechat.common.util.json.GsonParser;
import com.ossez.wechat.common.util.json.WxGsonBuilder; import com.ossez.wechat.common.util.json.WxGsonBuilder;
import com.ossez.wechat.oa.api.WxMpGuideTagService; import com.ossez.wechat.oa.api.WxMpGuideTagService;
import com.ossez.wechat.oa.api.WeChatOfficialAccountService; import com.ossez.wechat.oa.api.WeChatOfficialAccountService;
import com.ossez.wechat.common.enums.WxMpApiUrl; import com.ossez.wechat.oa.enums.WxMpApiUrl;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;

View File

@ -15,12 +15,12 @@ import java.io.UnsupportedEncodingException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import static com.ossez.wechat.common.enums.WxMpApiUrl.ImgProc.AI_CROP; import static com.ossez.wechat.oa.enums.WxMpApiUrl.ImgProc.AI_CROP;
import static com.ossez.wechat.common.enums.WxMpApiUrl.ImgProc.FILE_AI_CROP; import static com.ossez.wechat.oa.enums.WxMpApiUrl.ImgProc.FILE_AI_CROP;
import static com.ossez.wechat.common.enums.WxMpApiUrl.ImgProc.FILE_QRCODE; import static com.ossez.wechat.oa.enums.WxMpApiUrl.ImgProc.FILE_QRCODE;
import static com.ossez.wechat.common.enums.WxMpApiUrl.ImgProc.FILE_SUPER_RESOLUTION; import static com.ossez.wechat.oa.enums.WxMpApiUrl.ImgProc.FILE_SUPER_RESOLUTION;
import static com.ossez.wechat.common.enums.WxMpApiUrl.ImgProc.QRCODE; import static com.ossez.wechat.oa.enums.WxMpApiUrl.ImgProc.QRCODE;
import static com.ossez.wechat.common.enums.WxMpApiUrl.ImgProc.SUPER_RESOLUTION; import static com.ossez.wechat.oa.enums.WxMpApiUrl.ImgProc.SUPER_RESOLUTION;
/** /**
* 图像处理接口实现. * 图像处理接口实现.

View File

@ -16,7 +16,7 @@ import com.ossez.wechat.oa.api.WeChatOfficialAccountService;
import java.io.File; import java.io.File;
import java.util.Date; import java.util.Date;
import static com.ossez.wechat.common.enums.WxMpApiUrl.Kefu.*; import static com.ossez.wechat.oa.enums.WxMpApiUrl.Kefu.*;
/** /**
* @author Binary Wang * @author Binary Wang

View File

@ -20,7 +20,7 @@ import java.nio.charset.StandardCharsets;
import java.util.Date; import java.util.Date;
import java.util.List; import java.util.List;
import static com.ossez.wechat.common.enums.WxMpApiUrl.Marketing.*; import static com.ossez.wechat.oa.enums.WxMpApiUrl.Marketing.*;
/** /**
* @author <a href="https://github.com/007gzs">007</a> * @author <a href="https://github.com/007gzs">007</a>

View File

@ -12,7 +12,7 @@ import com.ossez.wechat.oa.bean.result.WxMpMassUploadResult;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import static com.ossez.wechat.common.enums.WxMpApiUrl.MassMessage; import static com.ossez.wechat.oa.enums.WxMpApiUrl.MassMessage;
/** /**
* <pre> * <pre>

View File

@ -24,7 +24,7 @@ import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.UUID; import java.util.UUID;
import static com.ossez.wechat.common.enums.WxMpApiUrl.Material.*; import static com.ossez.wechat.oa.enums.WxMpApiUrl.Material.*;
/** /**

View File

@ -10,7 +10,7 @@ import com.ossez.wechat.oa.bean.card.enums.CardColor;
import com.ossez.wechat.oa.bean.card.enums.DateInfoType; import com.ossez.wechat.oa.bean.card.enums.DateInfoType;
import com.ossez.wechat.oa.bean.card.membercard.*; import com.ossez.wechat.oa.bean.card.membercard.*;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import com.ossez.wechat.common.enums.WxMpApiUrl; import com.ossez.wechat.oa.enums.WxMpApiUrl;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import com.google.gson.Gson; import com.google.gson.Gson;

View File

@ -5,14 +5,14 @@ import com.ossez.wechat.oa.bean.menu.WxMpGetSelfMenuInfoResult;
import com.ossez.wechat.oa.bean.menu.WxMpMenu; import com.ossez.wechat.oa.bean.menu.WxMpMenu;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import com.ossez.wechat.common.model.entity.menu.WxMenu; import com.ossez.wechat.common.bean.menu.WxMenu;
import com.ossez.wechat.common.exception.WxErrorException; import com.ossez.wechat.common.exception.WxErrorException;
import com.ossez.wechat.common.util.json.GsonParser; import com.ossez.wechat.common.util.json.GsonParser;
import com.ossez.wechat.oa.api.WxMpMenuService; import com.ossez.wechat.oa.api.WxMpMenuService;
import com.ossez.wechat.oa.api.WeChatOfficialAccountService; import com.ossez.wechat.oa.api.WeChatOfficialAccountService;
import com.ossez.wechat.common.enums.WxMpApiUrl; import com.ossez.wechat.oa.enums.WxMpApiUrl;
import static com.ossez.wechat.common.enums.WxMpApiUrl.Menu.*; import static com.ossez.wechat.oa.enums.WxMpApiUrl.Menu.*;
/** /**
* Created by Binary Wang on 2016/7/21. * Created by Binary Wang on 2016/7/21.

View File

@ -11,11 +11,11 @@ import com.ossez.wechat.common.exception.WxErrorException;
import com.ossez.wechat.oa.api.WxMpCardService; import com.ossez.wechat.oa.api.WxMpCardService;
import com.ossez.wechat.oa.api.WxMpMerchantInvoiceService; import com.ossez.wechat.oa.api.WxMpMerchantInvoiceService;
import com.ossez.wechat.oa.api.WeChatOfficialAccountService; import com.ossez.wechat.oa.api.WeChatOfficialAccountService;
import com.ossez.wechat.common.enums.WxMpApiUrl; import com.ossez.wechat.oa.enums.WxMpApiUrl;
import java.util.Map; import java.util.Map;
import static com.ossez.wechat.common.enums.WxMpApiUrl.Invoice.*; import static com.ossez.wechat.oa.enums.WxMpApiUrl.Invoice.*;
/** /**

View File

@ -1,8 +1,8 @@
package com.ossez.wechat.oa.api.impl; package com.ossez.wechat.oa.api.impl;
import com.ossez.wechat.common.model.WeChatOAuth2AccessToken;
import com.ossez.wechat.common.model.entity.WeChatOAuth2UserInfo;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import com.ossez.wechat.common.bean.WxOAuth2UserInfo;
import com.ossez.wechat.common.bean.oauth2.WxOAuth2AccessToken;
import com.ossez.wechat.common.enums.WxType; import com.ossez.wechat.common.enums.WxType;
import com.ossez.wechat.common.exception.WxError; import com.ossez.wechat.common.exception.WxError;
import com.ossez.wechat.common.exception.WxErrorException; import com.ossez.wechat.common.exception.WxErrorException;
@ -12,12 +12,12 @@ import com.ossez.wechat.common.util.http.SimpleGetRequestExecutor;
import com.ossez.wechat.common.util.http.URIUtil; import com.ossez.wechat.common.util.http.URIUtil;
import com.ossez.wechat.oa.api.WeChatOfficialAccountService; import com.ossez.wechat.oa.api.WeChatOfficialAccountService;
import com.ossez.wechat.common.service.WxOAuth2Service; import com.ossez.wechat.common.service.WxOAuth2Service;
import com.ossez.wechat.common.config.ConfigStorage; import com.ossez.wechat.oa.config.ConfigStorage;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import java.io.IOException; import java.io.IOException;
import static com.ossez.wechat.common.enums.WxMpApiUrl.OAuth2.*; import static com.ossez.wechat.oa.enums.WxMpApiUrl.OAuth2.*;
/** /**
* oauth2 相关接口实现类. * oauth2 相关接口实现类.
@ -35,28 +35,28 @@ public class WxMpOAuth2ServiceImpl implements WxOAuth2Service {
getMpConfigStorage().getAppId(), URIUtil.encodeURIComponent(redirectUri), scope, StringUtils.trimToEmpty(state)); getMpConfigStorage().getAppId(), URIUtil.encodeURIComponent(redirectUri), scope, StringUtils.trimToEmpty(state));
} }
private WeChatOAuth2AccessToken getOAuth2AccessToken(String url) throws WxErrorException { private WxOAuth2AccessToken getOAuth2AccessToken(String url) throws WxErrorException {
try { try {
RequestExecutor<String, String> executor = SimpleGetRequestExecutor.create(this.weChatOfficialAccountService.getRequestHttp()); RequestExecutor<String, String> executor = SimpleGetRequestExecutor.create(this.weChatOfficialAccountService.getRequestHttp());
String responseText = executor.execute(url, null, WxType.MP); String responseText = executor.execute(url, null, WxType.MP);
return WeChatOAuth2AccessToken.fromJson(responseText); return WxOAuth2AccessToken.fromJson(responseText);
} catch (IOException e) { } catch (IOException e) {
throw new WxErrorException(WxError.builder().errorCode(99999).errorMsg(e.getMessage()).build(), e); throw new WxErrorException(WxError.builder().errorCode(99999).errorMsg(e.getMessage()).build(), e);
} }
} }
@Override @Override
public WeChatOAuth2AccessToken getAccessToken(String code) throws WxErrorException { public WxOAuth2AccessToken getAccessToken(String code) throws WxErrorException {
return this.getAccessToken(getMpConfigStorage().getAppId(), getMpConfigStorage().getSecret(), code); return this.getAccessToken(getMpConfigStorage().getAppId(), getMpConfigStorage().getSecret(), code);
} }
@Override @Override
public WeChatOAuth2AccessToken getAccessToken(String appId, String appSecret, String code) throws WxErrorException { public WxOAuth2AccessToken getAccessToken(String appId, String appSecret, String code) throws WxErrorException {
return this.getOAuth2AccessToken(String.format(OAUTH2_ACCESS_TOKEN_URL.getUrl(getMpConfigStorage()), appId, appSecret, code)); return this.getOAuth2AccessToken(String.format(OAUTH2_ACCESS_TOKEN_URL.getUrl(getMpConfigStorage()), appId, appSecret, code));
} }
@Override @Override
public WeChatOAuth2AccessToken refreshAccessToken(String refreshToken) throws WxErrorException { public WxOAuth2AccessToken refreshAccessToken(String refreshToken) throws WxErrorException {
String url = String.format(OAUTH2_REFRESH_TOKEN_URL.getUrl(getMpConfigStorage()), getMpConfigStorage().getAppId(), refreshToken); String url = String.format(OAUTH2_REFRESH_TOKEN_URL.getUrl(getMpConfigStorage()), getMpConfigStorage().getAppId(), refreshToken);
return this.getOAuth2AccessToken(url); return this.getOAuth2AccessToken(url);
} }
@ -66,7 +66,7 @@ public class WxMpOAuth2ServiceImpl implements WxOAuth2Service {
} }
@Override @Override
public WeChatOAuth2UserInfo getUserInfo(WeChatOAuth2AccessToken token, String lang) throws WxErrorException { public WxOAuth2UserInfo getUserInfo(WxOAuth2AccessToken token, String lang) throws WxErrorException {
if (lang == null) { if (lang == null) {
lang = "zh_CN"; lang = "zh_CN";
} }
@ -76,14 +76,14 @@ public class WxMpOAuth2ServiceImpl implements WxOAuth2Service {
try { try {
RequestExecutor<String, String> executor = SimpleGetRequestExecutor.create(this.weChatOfficialAccountService.getRequestHttp()); RequestExecutor<String, String> executor = SimpleGetRequestExecutor.create(this.weChatOfficialAccountService.getRequestHttp());
String responseText = executor.execute(url, null, WxType.MP); String responseText = executor.execute(url, null, WxType.MP);
return null; return WxOAuth2UserInfo.fromJson(responseText);
} catch (IOException e) { } catch (IOException e) {
throw new WxRuntimeException(e); throw new WxRuntimeException(e);
} }
} }
@Override @Override
public boolean validateAccessToken(WeChatOAuth2AccessToken token) { public boolean validateAccessToken(WxOAuth2AccessToken token) {
String url = String.format(OAUTH2_VALIDATE_TOKEN_URL.getUrl(getMpConfigStorage()), token.getAccessToken(), token.getOpenId()); String url = String.format(OAUTH2_VALIDATE_TOKEN_URL.getUrl(getMpConfigStorage()), token.getAccessToken(), token.getOpenId());
try { try {

View File

@ -12,7 +12,7 @@ import java.io.UnsupportedEncodingException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import static com.ossez.wechat.common.enums.WxMpApiUrl.Ocr.*; import static com.ossez.wechat.oa.enums.WxMpApiUrl.Ocr.*;
/** /**
* ocr 接口实现. * ocr 接口实现.

View File

@ -14,7 +14,7 @@ import java.io.UnsupportedEncodingException;
import java.net.URLEncoder; import java.net.URLEncoder;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import static com.ossez.wechat.common.enums.WxMpApiUrl.Qrcode.*; import static com.ossez.wechat.oa.enums.WxMpApiUrl.Qrcode.*;
/** /**
* Created by Binary Wang on 2016/7/21. * Created by Binary Wang on 2016/7/21.

View File

@ -8,7 +8,7 @@ import com.ossez.wechat.oa.api.WeChatOfficialAccountService;
import java.util.List; import java.util.List;
import static com.ossez.wechat.common.enums.WxMpApiUrl.Invoice.*; import static com.ossez.wechat.oa.enums.WxMpApiUrl.Invoice.*;
/** /**
* 电子发票报销方相关接口实现 * 电子发票报销方相关接口实现

View File

@ -10,7 +10,7 @@ import com.ossez.wechat.common.exception.WxErrorException;
import com.ossez.wechat.oa.api.WeChatOfficialAccountService; import com.ossez.wechat.oa.api.WeChatOfficialAccountService;
import com.ossez.wechat.oa.api.WxMpShakeService; import com.ossez.wechat.oa.api.WxMpShakeService;
import static com.ossez.wechat.common.enums.WxMpApiUrl.ShakeAround.*; import static com.ossez.wechat.oa.enums.WxMpApiUrl.ShakeAround.*;
/** /**
* Created by rememberber on 2017/6/5. * Created by rememberber on 2017/6/5.

View File

@ -13,7 +13,7 @@ import com.ossez.wechat.common.util.BeanUtils;
import com.ossez.wechat.common.util.json.GsonParser; import com.ossez.wechat.common.util.json.GsonParser;
import com.ossez.wechat.oa.api.WeChatOfficialAccountService; import com.ossez.wechat.oa.api.WeChatOfficialAccountService;
import com.ossez.wechat.oa.api.WxMpStoreService; import com.ossez.wechat.oa.api.WxMpStoreService;
import com.ossez.wechat.common.enums.WxMpApiUrl; import com.ossez.wechat.oa.enums.WxMpApiUrl;
import com.ossez.wechat.oa.util.json.WxMpGsonBuilder; import com.ossez.wechat.oa.util.json.WxMpGsonBuilder;
import java.util.List; import java.util.List;

View File

@ -14,7 +14,7 @@ import com.ossez.wechat.common.exception.WxError;
import com.ossez.wechat.common.exception.WxErrorException; import com.ossez.wechat.common.exception.WxErrorException;
import com.ossez.wechat.common.util.http.URIUtil; import com.ossez.wechat.common.util.http.URIUtil;
import com.ossez.wechat.common.util.json.GsonParser; import com.ossez.wechat.common.util.json.GsonParser;
import com.ossez.wechat.common.config.ConfigStorage; import com.ossez.wechat.oa.config.ConfigStorage;
import com.ossez.wechat.oa.api.WeChatOfficialAccountService; import com.ossez.wechat.oa.api.WeChatOfficialAccountService;
import com.ossez.wechat.oa.api.WxMpSubscribeMsgService; import com.ossez.wechat.oa.api.WxMpSubscribeMsgService;
import com.ossez.wechat.oa.bean.subscribe.WxMpSubscribeMessage; import com.ossez.wechat.oa.bean.subscribe.WxMpSubscribeMessage;
@ -24,7 +24,7 @@ import org.apache.commons.lang3.StringUtils;
import java.io.Serializable; import java.io.Serializable;
import java.util.List; import java.util.List;
import static com.ossez.wechat.common.enums.WxMpApiUrl.SubscribeMsg.*; import static com.ossez.wechat.oa.enums.WxMpApiUrl.SubscribeMsg.*;
/** /**
* 订阅消息接口. * 订阅消息接口.

View File

@ -14,7 +14,7 @@ import com.ossez.wechat.oa.bean.template.WxMpTemplateMessage;
import java.util.List; import java.util.List;
import static com.ossez.wechat.common.enums.WxMpApiUrl.TemplateMsg.*; import static com.ossez.wechat.oa.enums.WxMpApiUrl.TemplateMsg.*;
/** /**
* <pre> * <pre>

View File

@ -13,7 +13,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static com.ossez.wechat.common.enums.WxMpApiUrl.UserBlacklist.*; import static com.ossez.wechat.oa.enums.WxMpApiUrl.UserBlacklist.*;
/** /**
* @author miller * @author miller

View File

@ -16,7 +16,7 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static com.ossez.wechat.common.enums.WxMpApiUrl.User.*; import static com.ossez.wechat.oa.enums.WxMpApiUrl.User.*;
/** /**
* Created by Binary Wang on 2016/7/21. * Created by Binary Wang on 2016/7/21.

View File

@ -17,7 +17,7 @@ import org.apache.commons.lang3.StringUtils;
import java.util.List; import java.util.List;
import static com.ossez.wechat.common.enums.WxMpApiUrl.UserTag.*; import static com.ossez.wechat.oa.enums.WxMpApiUrl.UserTag.*;
/** /**
* Created by Binary Wang on 2016/9/2. * Created by Binary Wang on 2016/9/2.

View File

@ -8,7 +8,7 @@ import com.ossez.wechat.common.exception.WxErrorException;
import com.ossez.wechat.oa.api.WeChatOfficialAccountService; import com.ossez.wechat.oa.api.WeChatOfficialAccountService;
import com.ossez.wechat.oa.api.WxMpWifiService; import com.ossez.wechat.oa.api.WxMpWifiService;
import static com.ossez.wechat.common.enums.WxMpApiUrl.Wifi.*; import static com.ossez.wechat.oa.enums.WxMpApiUrl.Wifi.*;
/** /**
* <pre> * <pre>

View File

@ -1,26 +1,28 @@
package com.ossez.wechat.oa.api.impl.okhttp.interceptor; package com.ossez.wechat.oa.api.impl.okhttp;
import okhttp3.HttpUrl;
import okhttp3.Interceptor; import okhttp3.Interceptor;
import okhttp3.Request; import okhttp3.Request;
import okhttp3.Response; import okhttp3.Response;
import java.io.IOException; import java.io.IOException;
/** /**
* OkHttp Interceptor that adds an authorization token header * OkHttp Interceptor that adds an authorization token header
*/ */
public class AuthenticationInterceptor implements Interceptor { public class AuthenticationInterceptor implements Interceptor {
private final String token; private final String token;
public AuthenticationInterceptor(String token) { AuthenticationInterceptor(String token) {
this.token = token; this.token = token;
} }
@Override @Override
public Response intercept(Chain chain) throws IOException { public Response intercept(Chain chain) throws IOException {
HttpUrl url = chain.request().url().newBuilder().addQueryParameter("access_token", token).build(); Request request = chain.request()
Request request = chain.request().newBuilder().url(url).build(); .newBuilder()
// .header("Authorization", "Bearer " + token) .header("Authorization", "Bearer " + token)
.build();
return chain.proceed(request); return chain.proceed(request);
} }
} }

View File

@ -1,149 +0,0 @@
package com.ossez.wechat.oa.api.impl.okhttp;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.ossez.wechat.common.constant.WeChatConstant;
import com.ossez.wechat.common.exception.DataStructureException;
import com.ossez.wechat.common.exception.WxErrorException;
import com.ossez.wechat.common.model.req.DataCubeRequest;
import com.ossez.wechat.common.model.res.DataCubeArticle;
import com.ossez.wechat.common.model.res.DataCubeUser;
import com.ossez.wechat.oa.api.WeChatOfficialAccountService;
import com.ossez.wechat.oa.api.impl.okhttp.interceptor.AuthenticationInterceptor;
import com.ossez.wechat.oa.api.impl.okhttp.interceptor.WeChatErrorInterceptor;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import retrofit2.HttpException;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.jackson.JacksonConverterFactory;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.TimeUnit;
/**
* WeChat Official Account Platform DataCube
*
* @author YuCheng
*/
public class WeChatDataCubeService {
private final Logger log = LoggerFactory.getLogger(WeChatDataCubeService.class);
private WeChatOfficialAccountApi weChatOfficialAccountApi;
public WeChatDataCubeService(WeChatOfficialAccountService weChatOfficialAccountService) {
String accessToken = null;
try {
accessToken = weChatOfficialAccountService.getAccessToken();
} catch (WxErrorException e) {
throw new RuntimeException(e);
}
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.setSerializationInclusion(Include.NON_NULL);
mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
OkHttpClient client = new OkHttpClient.Builder().addInterceptor(new AuthenticationInterceptor(accessToken)).addInterceptor(new WeChatErrorInterceptor()).connectionPool(new ConnectionPool(5, 1, TimeUnit.SECONDS)).readTimeout(1000, TimeUnit.SECONDS).build();
Retrofit retrofit = new Retrofit.Builder().baseUrl(WeChatConstant.ENDPOINT_WECHAT).client(client).addConverterFactory(JacksonConverterFactory.create(mapper)).addCallAdapterFactory(RxJava2CallAdapterFactory.create()).build();
this.weChatOfficialAccountApi = retrofit.create(WeChatOfficialAccountApi.class);
}
/**
* Get user summary
*
* @param beginDate
* @param endDate
* @return
* @throws WxErrorException
*/
public DataCubeUser getUserSummary(LocalDateTime beginDate, LocalDateTime endDate) throws WxErrorException {
if (!(ObjectUtils.isNotEmpty(beginDate) && ObjectUtils.isNotEmpty(endDate) && endDate.isAfter(beginDate))) {
log.warn("The begin date [{}] Or end date [{}] was null or ender date greater than begin date.", beginDate, endDate);
throw new DataStructureException("Query data range error ");
}
try {
DataCubeRequest dataCubeRequest = new DataCubeRequest();
dataCubeRequest.setBeginDate(beginDate.format(DateTimeFormatter.ISO_LOCAL_DATE));
dataCubeRequest.setEndDate(endDate.format(DateTimeFormatter.ISO_LOCAL_DATE));
return weChatOfficialAccountApi.getUserSummary(dataCubeRequest).blockingGet();
} catch (HttpException ex) {
log.warn("Call WeChat API with error: " + ex);
if (ex.code() == 400) {
throw new WxErrorException(ex);
}
}
return null;
}
public DataCubeUser getUserCumulate(LocalDateTime beginDate, LocalDateTime endDate) throws WxErrorException {
if (!(ObjectUtils.isNotEmpty(beginDate) && ObjectUtils.isNotEmpty(endDate) && endDate.isAfter(beginDate))) {
log.warn("The begin date [{}] Or end date [{}] was null or ender date greater than begin date.", beginDate, endDate);
throw new DataStructureException("Query data range error ");
}
try {
DataCubeRequest dataCubeRequest = new DataCubeRequest();
dataCubeRequest.setBeginDate(beginDate.format(DateTimeFormatter.ISO_LOCAL_DATE));
dataCubeRequest.setEndDate(endDate.format(DateTimeFormatter.ISO_LOCAL_DATE));
return weChatOfficialAccountApi.getUserCumulate(dataCubeRequest).blockingGet();
} catch (HttpException ex) {
log.warn("Call WeChat API with error: " + ex);
if (ex.code() == 400) {
throw new WxErrorException(ex);
}
}
return null;
}
/**
*
* @param beginDate
* @param endDate
* @return
* @throws WxErrorException
*/
public DataCubeArticle getArticleSummary(LocalDateTime beginDate, LocalDateTime endDate) throws WxErrorException {
try {
return weChatOfficialAccountApi.getarticlesummary(getDataCubeRequest(beginDate, endDate)).blockingGet();
} catch (HttpException ex) {
log.warn("Call WeChat API with error: " + ex);
if (ex.code() == 400) {
throw new WxErrorException(ex);
}
}
return null;
}
private DataCubeRequest getDataCubeRequest(LocalDateTime beginDate, LocalDateTime endDate) throws DataStructureException {
if (!(ObjectUtils.isNotEmpty(beginDate) && ObjectUtils.isNotEmpty(endDate) && endDate.isAfter(beginDate))) {
log.warn("The begin date [{}] Or end date [{}] was null or ender date greater than begin date.", beginDate, endDate);
throw new DataStructureException("Query data range error ");
}
DataCubeRequest dataCubeRequest = new DataCubeRequest();
dataCubeRequest.setBeginDate(beginDate.format(DateTimeFormatter.ISO_LOCAL_DATE));
dataCubeRequest.setEndDate(endDate.format(DateTimeFormatter.ISO_LOCAL_DATE));
return dataCubeRequest;
}
}

View File

@ -0,0 +1,43 @@
package com.ossez.wechat.oa.api.impl.okhttp;
import com.ossez.wechat.common.constant.HttpClientMediaType;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.MediaType;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
/**
* The reason we have Interceptor here was because will return code 200 with error message.
* <p>
* For example, if we have error secret and try to get access token.
* WeChat will return code 200 success with json error message like:
*
* <pre>
* {"errcode":40125,"errmsg":"invalid appsecret rid: 63cf14c3-1af7da21-37efbc86"}
* </pre>
* <p>
* We need to check the response content, if the response content has errcode.
* We Interceptor response with error code 400 and add error json format to response body.
*
* @author YuCheng Hu
*/
public class WeChatErrorInterceptor implements Interceptor {
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
String responseStr = response.body().string();
if (StringUtils.contains(responseStr, "errcode")) {
ResponseBody responseBody = ResponseBody.create(MediaType.get(HttpClientMediaType.APPLICATION_JSON), responseStr);
return response.newBuilder().code(400).body(responseBody).build();
}
return response;
}
}

View File

@ -1,90 +0,0 @@
package com.ossez.wechat.oa.api.impl.okhttp;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.ossez.wechat.common.constant.WeChatConstant;
import com.ossez.wechat.common.exception.DataStructureException;
import com.ossez.wechat.common.exception.WxErrorException;
import com.ossez.wechat.common.model.WeChatStatus;
import com.ossez.wechat.common.model.req.DataCubeRequest;
import com.ossez.wechat.common.model.req.MenuRequest;
import com.ossez.wechat.common.model.res.DataCubeArticle;
import com.ossez.wechat.common.model.res.DataCubeUser;
import com.ossez.wechat.oa.api.WeChatOfficialAccountService;
import com.ossez.wechat.oa.api.impl.okhttp.interceptor.AuthenticationInterceptor;
import com.ossez.wechat.oa.api.impl.okhttp.interceptor.WeChatErrorInterceptor;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import retrofit2.HttpException;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.jackson.JacksonConverterFactory;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.TimeUnit;
/**
* WeChat Official Account Platform DataCube
*
* @author YuCheng
*/
public class WeChatMenuService {
private final Logger log = LoggerFactory.getLogger(WeChatMenuService.class);
private WeChatOfficialAccountApi weChatOfficialAccountApi;
public WeChatMenuService(WeChatOfficialAccountService weChatOfficialAccountService) {
String accessToken = null;
try {
accessToken = weChatOfficialAccountService.getAccessToken();
} catch (WxErrorException e) {
throw new RuntimeException(e);
}
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.setSerializationInclusion(Include.NON_NULL);
mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new AuthenticationInterceptor(accessToken))
.addInterceptor(new WeChatErrorInterceptor())
.connectionPool(new ConnectionPool(5, 1, TimeUnit.SECONDS)).readTimeout(1000, TimeUnit.SECONDS)
.build();
Retrofit retrofit = new Retrofit.Builder().baseUrl(WeChatConstant.ENDPOINT_WECHAT).client(client)
.addConverterFactory(JacksonConverterFactory.create(mapper))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
this.weChatOfficialAccountApi = retrofit.create(WeChatOfficialAccountApi.class);
}
/**
* @param menuRequest
* @return
* @throws WxErrorException
*/
public WeChatStatus create(MenuRequest menuRequest) throws WxErrorException {
try {
return weChatOfficialAccountApi.createMenu(menuRequest).blockingGet();
} catch (HttpException ex) {
log.warn("Call WeChat API with error: " + ex);
if (ex.code() == 400) {
throw new WxErrorException(ex);
}
}
return null;
}
}

View File

@ -1,79 +0,0 @@
package com.ossez.wechat.oa.api.impl.okhttp;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.ossez.wechat.common.constant.WeChatConstant;
import com.ossez.wechat.common.exception.WxErrorException;
import com.ossez.wechat.common.model.req.CustomMessage;
import com.ossez.wechat.oa.api.WeChatOfficialAccountService;
import com.ossez.wechat.oa.api.impl.okhttp.interceptor.AuthenticationInterceptor;
import com.ossez.wechat.oa.api.impl.okhttp.interceptor.WeChatErrorInterceptor;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import retrofit2.HttpException;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.jackson.JacksonConverterFactory;
import java.util.concurrent.TimeUnit;
/**
* WeChat Official Account Platform related Service
*
* @author YuCheng
*/
public class WeChatMsgService {
private final Logger log = LoggerFactory.getLogger(WeChatMsgService.class);
private WeChatOfficialAccountApi weChatOfficialAccountApi;
public WeChatMsgService(WeChatOfficialAccountService weChatOfficialAccountService) {
String accessToken = null;
try {
accessToken = weChatOfficialAccountService.getAccessToken();
} catch (WxErrorException e) {
throw new RuntimeException(e);
}
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.setSerializationInclusion(Include.NON_NULL);
mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new AuthenticationInterceptor(accessToken))
.addInterceptor(new WeChatErrorInterceptor())
.connectionPool(new ConnectionPool(5, 1, TimeUnit.SECONDS)).readTimeout(1000, TimeUnit.SECONDS).build();
Retrofit retrofit = new Retrofit.Builder().baseUrl(WeChatConstant.ENDPOINT_WECHAT).client(client)
.addConverterFactory(JacksonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
this.weChatOfficialAccountApi = retrofit.create(WeChatOfficialAccountApi.class);
}
public String sendMessage(CustomMessage customMessage) throws WxErrorException {
try {
weChatOfficialAccountApi.sendMessage(customMessage).blockingGet();
} catch (HttpException ex) {
log.warn("Access WeChat API return error.", ex);
if (ex.code() == 400) {
throw new WxErrorException(ex);
}
System.out.println(">>>>>>>>>>>>>>>>>>>> " + ex.getMessage());
}
return "MSG";
}
}

View File

@ -1,68 +1,12 @@
package com.ossez.wechat.oa.api.impl.okhttp; package com.ossez.wechat.oa.api.impl.okhttp;
import com.ossez.wechat.common.model.WeChatAccessToken; import com.ossez.wechat.common.model.WeChatAccessToken;
import com.ossez.wechat.common.model.WeChatApiDomainIp;
import com.ossez.wechat.common.model.WeChatStatus;
import com.ossez.wechat.common.model.req.*;
import com.ossez.wechat.common.model.res.DataCubeArticle;
import com.ossez.wechat.common.model.res.NetworkCheckResponse;
import com.ossez.wechat.common.model.res.QueryQuotaResponse;
import com.ossez.wechat.common.model.res.DataCubeUser;
import io.reactivex.Single; import io.reactivex.Single;
import retrofit2.http.Body;
import retrofit2.http.GET; import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Query; import retrofit2.http.Query;
public interface WeChatOfficialAccountApi { public interface WeChatOfficialAccountApi {
@GET("/cgi-bin/token") @GET("token")
Single<WeChatAccessToken> getAccessToken(@Query("grant_type") String grantType, @Query("appid") String appId, @Query("secret") String secret); Single<WeChatAccessToken> getAccessToken(@Query("grant_type") String grantType, @Query("appid") String appId, @Query("secret") String secret);
}
@GET("/cgi-bin/get_api_domain_ip")
Single<WeChatApiDomainIp> getDomainIPs();
@POST("/cgi-bin/callback/check")
Single<NetworkCheckResponse> checkNetwork(@Body NetworkCheck request);
@POST("/cgi-bin/clear_quota")
Single<NetworkCheckResponse> clearQuota(@Body NetworkCheck request);
@POST("/cgi-bin/openapi/quota/get")
Single<QueryQuotaResponse> queryQuota(@Body QueryQuota request);
@POST("/cgi-bin/message/custom/send")
Single<WeChatStatus> sendMessage(@Body CustomMessage customMessage);
// MENU
@POST("/cgi-bin/menu/create")
Single<WeChatStatus> createMenu(@Body MenuRequest menuRequest);
@GET("/cgi-bin/get_current_selfmenu_info")
Single<WeChatStatus> getMenu();
// DATA ANALYST
@POST("/datacube/getusersummary")
Single<DataCubeUser> getUserSummary(@Body DataCubeRequest dataCubeRequest);
@POST("/datacube/getusercumulate")
Single<DataCubeUser> getUserCumulate(@Body DataCubeRequest dataCubeRequest);
@POST("/datacube/getarticlesummary")
Single<DataCubeArticle> getarticlesummary(@Body DataCubeRequest dataCubeRequest);
@POST("/datacube/getarticletotal")
Single<DataCubeUser> getarticletotal(@Body DataCubeRequest dataCubeRequest);
@POST("/datacube/getuserread")
Single<DataCubeUser> getuserread(@Body DataCubeRequest dataCubeRequest);
@POST("/datacube/getuserreadhour")
Single<DataCubeUser> getuserreadhour(@Body DataCubeRequest dataCubeRequest);
@POST("/datacube/getusershare")
Single<DataCubeUser> getusershare(@Body DataCubeRequest dataCubeRequest);
@POST("/datacube/getusersharehour")
Single<DataCubeUser> getusersharehour(@Body DataCubeRequest dataCubeRequest);
}

View File

@ -8,12 +8,10 @@ import com.ossez.wechat.common.constant.WeChatApiParameter;
import com.ossez.wechat.common.constant.WeChatConstant; import com.ossez.wechat.common.constant.WeChatConstant;
import com.ossez.wechat.common.exception.WxErrorException; import com.ossez.wechat.common.exception.WxErrorException;
import com.ossez.wechat.common.model.WeChatAccessToken; import com.ossez.wechat.common.model.WeChatAccessToken;
import com.ossez.wechat.common.model.WeChatApiDomainIp;
import com.ossez.wechat.common.util.http.HttpType; import com.ossez.wechat.common.util.http.HttpType;
import com.ossez.wechat.common.util.http.okhttp.OkHttpProxyInfo; import com.ossez.wechat.common.util.http.okhttp.OkHttpProxyInfo;
import com.ossez.wechat.oa.api.impl.BaseWeChatOfficialAccountServiceImpl; import com.ossez.wechat.oa.api.impl.BaseWeChatOfficialAccountServiceImpl;
import com.ossez.wechat.common.config.ConfigStorage; import com.ossez.wechat.oa.config.ConfigStorage;
import com.ossez.wechat.oa.api.impl.okhttp.interceptor.WeChatErrorInterceptor;
import okhttp3.ConnectionPool; import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -79,7 +77,6 @@ public class WeChatOfficialAccountServiceOkHttp extends BaseWeChatOfficialAccoun
// } catch (Exception e) { // } catch (Exception e) {
// throw new WxRuntimeException(e); // throw new WxRuntimeException(e);
// } // }
config.updateAccessToken(weChatAccessToken.getAccessToken(), weChatAccessToken.getExpiresIn());
return weChatAccessToken.getAccessToken(); return weChatAccessToken.getAccessToken();
} }
@ -96,7 +93,7 @@ public class WeChatOfficialAccountServiceOkHttp extends BaseWeChatOfficialAccoun
.addInterceptor(new WeChatErrorInterceptor()) .addInterceptor(new WeChatErrorInterceptor())
.connectionPool(new ConnectionPool(5, 1, TimeUnit.SECONDS)).readTimeout(1000, TimeUnit.SECONDS).build(); .connectionPool(new ConnectionPool(5, 1, TimeUnit.SECONDS)).readTimeout(1000, TimeUnit.SECONDS).build();
Retrofit retrofit = new Retrofit.Builder().baseUrl(WeChatConstant.ENDPOINT_WECHAT).client(client) Retrofit retrofit = new Retrofit.Builder().baseUrl(WeChatConstant.ENDPOINT_OFFICIAL_ACCOUNT).client(client)
.addConverterFactory(JacksonConverterFactory.create(mapper)) .addConverterFactory(JacksonConverterFactory.create(mapper))
.addCallAdapterFactory(RxJava2CallAdapterFactory.create()) .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build(); .build();

View File

@ -1,149 +0,0 @@
package com.ossez.wechat.oa.api.impl.okhttp;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.ossez.wechat.common.constant.WeChatConstant;
import com.ossez.wechat.common.exception.WxErrorException;
import com.ossez.wechat.common.model.WeChatApiDomainIp;
import com.ossez.wechat.common.model.req.NetworkCheck;
import com.ossez.wechat.common.model.req.QueryQuota;
import com.ossez.wechat.common.model.res.NetworkCheckResponse;
import com.ossez.wechat.common.model.res.QueryQuotaResponse;
import com.ossez.wechat.oa.api.WeChatOfficialAccountService;
import com.ossez.wechat.oa.api.impl.okhttp.interceptor.AuthenticationInterceptor;
import com.ossez.wechat.oa.api.impl.okhttp.interceptor.WeChatErrorInterceptor;
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import retrofit2.HttpException;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava2.RxJava2CallAdapterFactory;
import retrofit2.converter.jackson.JacksonConverterFactory;
import java.util.concurrent.TimeUnit;
/**
* WeChat Official Account Platform related Service
*
* @author YuCheng
*/
public class WeChatPlatformService {
private final Logger log = LoggerFactory.getLogger(WeChatPlatformService.class);
private final WeChatOfficialAccountService weChatOfficialAccountService;
WeChatOfficialAccountApi weChatOfficialAccountApi;
public WeChatPlatformService(WeChatOfficialAccountService weChatOfficialAccountService) {
this.weChatOfficialAccountService = weChatOfficialAccountService;
String accessToken = null;
try {
accessToken = weChatOfficialAccountService.getAccessToken();
} catch (WxErrorException e) {
throw new RuntimeException(e);
}
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(new AuthenticationInterceptor(accessToken))
.addInterceptor(new WeChatErrorInterceptor())
.connectionPool(new ConnectionPool(5, 1, TimeUnit.SECONDS)).readTimeout(1000, TimeUnit.SECONDS).build();
Retrofit retrofit = new Retrofit.Builder().baseUrl(WeChatConstant.ENDPOINT_WECHAT).client(client)
// .addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(JacksonConverterFactory.create())
.addCallAdapterFactory(RxJava2CallAdapterFactory.create())
.build();
this.weChatOfficialAccountApi = retrofit.create(WeChatOfficialAccountApi.class);
}
public String getDomainIPs() throws WxErrorException {
WeChatApiDomainIp apiDomainIp = new WeChatApiDomainIp();
try {
apiDomainIp = weChatOfficialAccountApi.getDomainIPs().blockingGet();
} catch (HttpException ex) {
log.warn("Access WeChat API return error.", ex);
if (ex.code() == 400) {
throw new WxErrorException(ex);
}
System.out.println(">>>>>>>>>>>>>>>>>>>> " + ex.getMessage());
}
return apiDomainIp.getIpList().toString();
}
public NetworkCheckResponse checkNetwork() throws WxErrorException {
NetworkCheck networkCheck = new NetworkCheck();
networkCheck.setAction("all");
NetworkCheckResponse networkCheckResponse = new NetworkCheckResponse();
try {
networkCheckResponse = weChatOfficialAccountApi.checkNetwork(networkCheck).blockingGet();
} catch (HttpException ex) {
log.warn("Access WeChat API return error.", ex);
if (ex.code() == 400) {
throw new WxErrorException(ex);
}
System.out.println(">>>>>>>>>>>>>>>>>>>> " + ex.getMessage());
}
return networkCheckResponse;
}
public NetworkCheckResponse clearQuota() throws WxErrorException {
NetworkCheck networkCheck = new NetworkCheck();
networkCheck.setAction("all");
NetworkCheckResponse networkCheckResponse = new NetworkCheckResponse();
try {
networkCheckResponse = weChatOfficialAccountApi.clearQuota(networkCheck).blockingGet();
} catch (HttpException ex) {
log.warn("Access WeChat API return error.", ex);
if (ex.code() == 400) {
throw new WxErrorException(ex);
}
System.out.println(">>>>>>>>>>>>>>>>>>>> " + ex.getMessage());
}
return networkCheckResponse;
}
/**
* queryQuota for WeChat API
*
* @return
* @throws WxErrorException
*/
public QueryQuotaResponse queryQuota() throws WxErrorException {
QueryQuota queryQuota = new QueryQuota();
queryQuota.setCgiPath("/cgi-bin/message/custom/send");
QueryQuotaResponse queryQuotaResponse = new QueryQuotaResponse();
try {
queryQuotaResponse = weChatOfficialAccountApi.queryQuota(queryQuota).blockingGet();
} catch (HttpException ex) {
log.warn("Access WeChat API return error.", ex);
if (ex.code() == 400) {
throw new WxErrorException(ex);
}
System.out.println(">>>>>>>>>>>>>>>>>>>> " + ex.getMessage());
}
return queryQuotaResponse;
}
}

Some files were not shown because too many files have changed in this diff Show More