├── .gitignore
├── .travis.yml
├── README.MD
├── commit.sh
├── pom.xml
└── src
└── main
├── java
└── com
│ └── github
│ └── binarywang
│ └── demo
│ └── wx
│ └── open
│ ├── WxOpenApplication.java
│ ├── config
│ ├── RedisProperies.java
│ └── WechatOpenProperties.java
│ ├── controller
│ ├── WechatApiController.java
│ └── WechatNotifyController.java
│ └── service
│ └── WxOpenServiceDemo.java
└── resources
└── application.yml
/.gitignore:
--------------------------------------------------------------------------------
1 | #mac
2 | .DS_Store
3 | # https://github.com/github/gitignore/blob/master/Java.gitignore
4 |
5 | *.class
6 |
7 | # Mobile Tools for Java (J2ME)
8 | .mtj.tmp/
9 |
10 | # Package Files #
11 | *.jar
12 | *.war
13 | *.ear
14 |
15 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
16 | hs_err_pid*
17 |
18 | /.project
19 |
20 |
21 | # https://github.com/github/gitignore/blob/master/Maven.gitignore
22 | target/
23 | pom.xml.tag
24 | pom.xml.releaseBackup
25 | pom.xml.versionsBackup
26 | pom.xml.next
27 | release.properties
28 | dependency-reduced-pom.xml
29 | buildNumber.properties
30 | .mvn/timing.properties
31 |
32 |
33 | # https://github.com/github/gitignore/blob/master/Global/Eclipse.gitignore
34 |
35 | .metadata
36 | bin/
37 | tmp/
38 | *.tmp
39 | *.bak
40 | *.swp
41 | *~.nib
42 | local.properties
43 | .settings/
44 | .loadpath
45 | .recommenders
46 |
47 | # Eclipse Core
48 | .project
49 |
50 | # External tool builders
51 | .externalToolBuilders/
52 |
53 | # Locally stored "Eclipse launch configurations"
54 | *.launch
55 |
56 | # PyDev specific (Python IDE for Eclipse)
57 | *.pydevproject
58 |
59 | # CDT-specific (C/C++ Development Tooling)
60 | .cproject
61 |
62 | # JDT-specific (Eclipse Java Development Tools)
63 | .classpath
64 |
65 | # Java annotation processor (APT)
66 | .factorypath
67 |
68 | # PDT-specific (PHP Development Tools)
69 | .buildpath
70 |
71 | # sbteclipse plugin
72 | .target
73 |
74 | # Tern plugin
75 | .tern-project
76 |
77 | # TeXlipse plugin
78 | .texlipse
79 |
80 | # STS (Spring Tool Suite)
81 | .springBeans
82 |
83 | # Code Recommenders
84 | .recommenders/
85 |
86 |
87 | # https://github.com/github/gitignore/blob/master/Global/JetBrains.gitignore
88 |
89 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and Webstorm
90 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
91 |
92 | # User-specific stuff:
93 | .idea/workspace.xml
94 | .idea/tasks.xml
95 | .idea/dictionaries
96 | .idea/vcs.xml
97 | .idea/jsLibraryMappings.xml
98 |
99 | # Sensitive or high-churn files:
100 | .idea/dataSources.ids
101 | .idea/dataSources.xml
102 | .idea/dataSources.local.xml
103 | .idea/sqlDataSources.xml
104 | .idea/dynamic.xml
105 | .idea/uiDesigner.xml
106 |
107 | # Gradle:
108 | .idea/gradle.xml
109 | .idea/libraries
110 |
111 | # Mongo Explorer plugin:
112 | .idea/mongoSettings.xml
113 |
114 | ## File-based project format:
115 | *.iws
116 |
117 | ## Plugin-specific files:
118 |
119 | # IntelliJ
120 | /out/
121 |
122 | # mpeltonen/sbt-idea plugin
123 | .idea_modules/
124 |
125 | # JIRA plugin
126 | atlassian-ide-plugin.xml
127 |
128 | # Crashlytics plugin (for Android Studio and IntelliJ)
129 | com_crashlytics_export_strings.xml
130 | crashlytics.properties
131 | crashlytics-build.properties
132 | fabric.properties
133 |
134 |
135 | # zeroturnaround
136 | rebel.xml
137 |
138 |
139 | # log
140 | log/
141 | logs/
142 |
143 |
144 | # IntelliJ IDEA
145 | *.iml
146 | .idea/
147 |
148 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 | jdk:
3 | - openjdk8
4 |
5 | script: "mvn clean package -Dmaven.test.skip=true"
6 |
7 | branches:
8 | only:
9 | - master
10 |
11 | notifications:
12 | email:
13 | - binarywang@vip.qq.com
14 |
--------------------------------------------------------------------------------
/README.MD:
--------------------------------------------------------------------------------
1 | ### 本Demo基于Spring Boot构建,实现微信第三方平台开发功能。
2 |
3 | #### 本项目为WxJava的Demo演示程序,更多信息请查阅:https://github.com/Wechat-Group/WxJava
4 |
5 | [](https://gitee.com/binary/weixin-java-open-demo)
6 | [](https://github.com/Wechat-Group/weixin-java-open-demo)
7 | [](https://travis-ci.org/Wechat-Group/weixin-java-open-demo)
8 | -----------------------
9 |
10 | ## 使用步骤:
11 | 1. 新手遇到问题,请务必先阅读[【开发文档首页】](https://github.com/Wechat-Group/WxJava/wiki)的常见问题部分,可以少走很多弯路,节省不少时间。如还有其他问题请[【在此提问】](https://github.com/Wechat-Group/weixin-java-open-demo/issues),谢谢配合。
12 | 1. 配置:修改`/src/main/resources/application.yml` ,根据自己需要填写相关配置(需要注意的是:yml文件内的属性冒号后面的文字之前需要加空格,可参考已有配置,否则属性会设置不成功);
13 | 1. 运行Java程序:`com.github.binarywang.demo.wechat.WxOpenDemoApplication`;
14 | 1. 配置微信第三方平台中的授权事件接收URL:http://my-domain/notify/receive_ticket
15 | 1. 配置微信第三方平台中的公众号消息与事件接收URL http://my-domain/notify/$APPID$/callback
16 | 1. 首次启动后需要 等待收到 微信推送的 component_verify_ticket 后才可以使用接口 (在第三方平台创建审核通过后,微信服务器每隔10分钟会向第三方的消息接收地址推送一次component_verify_ticket,用于获取第三方平台接口调用凭据)
17 | 1. 浏览器访问:http://my-domain/api/auth/goto_auth_url_show 点击 go 跳转到微信授权页面 扫码授权
18 |
--------------------------------------------------------------------------------
/commit.sh:
--------------------------------------------------------------------------------
1 | git commit -a -m ":arrow_up: 升级sdk版本为4.7.0"
2 | git pull --rebase
3 |
4 | git push origin master
5 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | org.springframework.boot
8 | spring-boot-starter-parent
9 | 2.3.3.RELEASE
10 |
11 | com.github.binarywang
12 | weixin-java-open-demo
13 | 1.0-SNAPSHOT
14 | jar
15 |
16 | spring-boot-demo-for-wechat-open
17 | Spring Boot Demo with wechat Open
18 |
19 |
20 | 4.7.0
21 |
22 | 1.8
23 | 1.8
24 | UTF-8
25 | UTF-8
26 | zh_CN
27 |
28 |
29 |
30 | org.springframework.boot
31 | spring-boot-starter-web
32 |
33 |
34 | com.fasterxml.jackson.core
35 | jackson-databind
36 |
37 |
38 |
39 |
40 |
41 | com.github.binarywang
42 | weixin-java-open
43 | ${weixin-java-open.version}
44 |
45 |
46 |
47 |
48 | org.springframework.boot
49 | spring-boot-starter-test
50 | test
51 |
52 |
53 |
54 | redis.clients
55 | jedis
56 | 3.3.0
57 |
58 |
59 | com.github.jedis-lock
60 | jedis-lock
61 | 1.0.0
62 |
63 |
64 |
65 |
66 |
67 |
68 | org.springframework.boot
69 | spring-boot-maven-plugin
70 |
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/src/main/java/com/github/binarywang/demo/wx/open/WxOpenApplication.java:
--------------------------------------------------------------------------------
1 | package com.github.binarywang.demo.wx.open;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 | /**
6 | * @author 007
7 | */
8 | @SpringBootApplication
9 | public class WxOpenApplication {
10 | public static void main(String[] args) {
11 | SpringApplication.run(WxOpenApplication.class, args);
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/github/binarywang/demo/wx/open/config/RedisProperies.java:
--------------------------------------------------------------------------------
1 | package com.github.binarywang.demo.wx.open.config;
2 |
3 | import org.springframework.boot.context.properties.ConfigurationProperties;
4 | import redis.clients.jedis.JedisPoolConfig;
5 | import redis.clients.jedis.Protocol;
6 |
7 | import javax.net.ssl.HostnameVerifier;
8 | import javax.net.ssl.SSLParameters;
9 | import javax.net.ssl.SSLSocketFactory;
10 | /**
11 | * @author 007
12 | */
13 | @ConfigurationProperties(prefix = "wechat.redis")
14 | public class RedisProperies extends JedisPoolConfig {
15 | private String host = Protocol.DEFAULT_HOST;
16 | private int port = Protocol.DEFAULT_PORT;
17 | private String password;
18 | private int database = 1;
19 | private int connectionTimeout = Protocol.DEFAULT_TIMEOUT;
20 | private int soTimeout = Protocol.DEFAULT_TIMEOUT;
21 | private String clientName;
22 | private boolean ssl;
23 | private SSLSocketFactory sslSocketFactory;
24 | private SSLParameters sslParameters;
25 | private HostnameVerifier hostnameVerifier;
26 |
27 | public boolean isSsl() {
28 | return ssl;
29 | }
30 |
31 | public void setSsl(boolean ssl) {
32 | this.ssl = ssl;
33 | }
34 |
35 | public SSLSocketFactory getSslSocketFactory() {
36 | return sslSocketFactory;
37 | }
38 |
39 | public void setSslSocketFactory(SSLSocketFactory sslSocketFactory) {
40 | this.sslSocketFactory = sslSocketFactory;
41 | }
42 |
43 | public SSLParameters getSslParameters() {
44 | return sslParameters;
45 | }
46 |
47 | public void setSslParameters(SSLParameters sslParameters) {
48 | this.sslParameters = sslParameters;
49 | }
50 |
51 | public HostnameVerifier getHostnameVerifier() {
52 | return hostnameVerifier;
53 | }
54 |
55 | public void setHostnameVerifier(HostnameVerifier hostnameVerifier) {
56 | this.hostnameVerifier = hostnameVerifier;
57 | }
58 |
59 | public String getHost() {
60 | return host;
61 | }
62 |
63 | public void setHost(String host) {
64 | if (host == null || "".equals(host)) {
65 | host = Protocol.DEFAULT_HOST;
66 | }
67 | this.host = host;
68 | }
69 |
70 | public int getPort() {
71 | return port;
72 | }
73 |
74 | public void setPort(int port) {
75 | this.port = port;
76 | }
77 |
78 | public String getPassword() {
79 | return password;
80 | }
81 |
82 | public void setPassword(String password) {
83 | if ("".equals(password)) {
84 | password = null;
85 | }
86 | this.password = password;
87 | }
88 |
89 | public int getDatabase() {
90 | return database;
91 | }
92 |
93 | public void setDatabase(int database) {
94 | this.database = database;
95 | }
96 |
97 | public String getClientName() {
98 | return clientName;
99 | }
100 |
101 | public void setClientName(String clientName) {
102 | if ("".equals(clientName)) {
103 | clientName = null;
104 | }
105 | this.clientName = clientName;
106 | }
107 |
108 | public int getConnectionTimeout() {
109 | return connectionTimeout;
110 | }
111 |
112 | public void setConnectionTimeout(int connectionTimeout) {
113 | this.connectionTimeout = connectionTimeout;
114 | }
115 |
116 | public int getSoTimeout() {
117 | return soTimeout;
118 | }
119 |
120 | public void setSoTimeout(int soTimeout) {
121 | this.soTimeout = soTimeout;
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/src/main/java/com/github/binarywang/demo/wx/open/config/WechatOpenProperties.java:
--------------------------------------------------------------------------------
1 | package com.github.binarywang.demo.wx.open.config;
2 |
3 | import org.apache.commons.lang3.builder.ToStringBuilder;
4 | import org.apache.commons.lang3.builder.ToStringStyle;
5 | import org.springframework.boot.context.properties.ConfigurationProperties;
6 | /**
7 | * @author 007
8 | */
9 | @ConfigurationProperties(prefix = "wechat.open")
10 | public class WechatOpenProperties {
11 | /**
12 | * 设置微信三方平台的appid
13 | */
14 | private String componentAppId;
15 |
16 | /**
17 | * 设置微信三方平台的app secret
18 | */
19 | private String componentSecret;
20 |
21 | /**
22 | * 设置微信三方平台的token
23 | */
24 | private String componentToken;
25 |
26 | /**
27 | * 设置微信三方平台的EncodingAESKey
28 | */
29 | private String componentAesKey;
30 |
31 | public String getComponentAppId() {
32 | return componentAppId;
33 | }
34 |
35 | public void setComponentAppId(String componentAppId) {
36 | this.componentAppId = componentAppId;
37 | }
38 |
39 | public String getComponentSecret() {
40 | return componentSecret;
41 | }
42 |
43 | public void setComponentSecret(String componentSecret) {
44 | this.componentSecret = componentSecret;
45 | }
46 |
47 | public String getComponentToken() {
48 | return componentToken;
49 | }
50 |
51 | public void setComponentToken(String componentToken) {
52 | this.componentToken = componentToken;
53 | }
54 |
55 | public String getComponentAesKey() {
56 | return componentAesKey;
57 | }
58 |
59 | public void setComponentAesKey(String componentAesKey) {
60 | this.componentAesKey = componentAesKey;
61 | }
62 |
63 | @Override
64 | public String toString() {
65 | return ToStringBuilder.reflectionToString(this,
66 | ToStringStyle.MULTI_LINE_STYLE);
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/com/github/binarywang/demo/wx/open/controller/WechatApiController.java:
--------------------------------------------------------------------------------
1 | package com.github.binarywang.demo.wx.open.controller;
2 |
3 | import com.github.binarywang.demo.wx.open.service.WxOpenServiceDemo;
4 | import me.chanjar.weixin.common.error.WxErrorException;
5 | import me.chanjar.weixin.open.bean.result.WxOpenAuthorizerInfoResult;
6 | import me.chanjar.weixin.open.bean.result.WxOpenQueryAuthResult;
7 | import org.slf4j.Logger;
8 | import org.slf4j.LoggerFactory;
9 | import org.springframework.beans.factory.annotation.Autowired;
10 | import org.springframework.stereotype.Controller;
11 | import org.springframework.web.bind.annotation.GetMapping;
12 | import org.springframework.web.bind.annotation.RequestMapping;
13 | import org.springframework.web.bind.annotation.RequestParam;
14 | import org.springframework.web.bind.annotation.ResponseBody;
15 |
16 | import javax.servlet.http.HttpServletRequest;
17 | import javax.servlet.http.HttpServletResponse;
18 | import java.io.IOException;
19 | /**
20 | * @author 007
21 | */
22 | @Controller
23 | @RequestMapping("/api")
24 | public class WechatApiController {
25 | private final Logger logger = LoggerFactory.getLogger(getClass());
26 | @Autowired
27 | private WxOpenServiceDemo wxOpenServiceDemo;
28 | @GetMapping("/auth/goto_auth_url_show")
29 | @ResponseBody
30 | public String gotoPreAuthUrlShow(){
31 | return "go";
32 | }
33 | @GetMapping("/auth/goto_auth_url")
34 | public void gotoPreAuthUrl(HttpServletRequest request, HttpServletResponse response){
35 | String host = request.getHeader("host");
36 | String url = "http://"+host+"/api/auth/jump";
37 | try {
38 | url = wxOpenServiceDemo.getWxOpenComponentService().getPreAuthUrl(url);
39 | // 添加来源,解决302跳转来源丢失的问题
40 | response.addHeader("Referer", "http://"+host);
41 | response.sendRedirect(url);
42 | } catch (WxErrorException | IOException e) {
43 | logger.error("gotoPreAuthUrl", e);
44 | throw new RuntimeException(e);
45 | }
46 | }
47 | @GetMapping("/auth/jump")
48 | @ResponseBody
49 | public WxOpenQueryAuthResult jump(@RequestParam("auth_code") String authorizationCode){
50 | try {
51 | WxOpenQueryAuthResult queryAuthResult = wxOpenServiceDemo.getWxOpenComponentService().getQueryAuth(authorizationCode);
52 | logger.info("getQueryAuth", queryAuthResult);
53 | return queryAuthResult;
54 | } catch (WxErrorException e) {
55 | logger.error("gotoPreAuthUrl", e);
56 | throw new RuntimeException(e);
57 | }
58 | }
59 | @GetMapping("/get_authorizer_info")
60 | @ResponseBody
61 | public WxOpenAuthorizerInfoResult getAuthorizerInfo(@RequestParam String appId){
62 | try {
63 | return wxOpenServiceDemo.getWxOpenComponentService().getAuthorizerInfo(appId);
64 | } catch (WxErrorException e) {
65 | logger.error("getAuthorizerInfo", e);
66 | throw new RuntimeException(e);
67 | }
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/src/main/java/com/github/binarywang/demo/wx/open/controller/WechatNotifyController.java:
--------------------------------------------------------------------------------
1 | package com.github.binarywang.demo.wx.open.controller;
2 |
3 | import com.github.binarywang.demo.wx.open.service.WxOpenServiceDemo;
4 | import me.chanjar.weixin.common.error.WxErrorException;
5 | import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
6 | import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
7 | import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
8 | import me.chanjar.weixin.open.bean.message.WxOpenXmlMessage;
9 | import org.apache.commons.lang3.StringUtils;
10 | import org.slf4j.Logger;
11 | import org.slf4j.LoggerFactory;
12 | import org.springframework.beans.factory.annotation.Autowired;
13 | import org.springframework.web.bind.annotation.*;
14 |
15 | /**
16 | * @author 007
17 | */
18 | @RestController
19 | @RequestMapping("/notify")
20 | public class WechatNotifyController {
21 | private final Logger logger = LoggerFactory.getLogger(this.getClass());
22 | @Autowired
23 | protected WxOpenServiceDemo wxOpenService;
24 |
25 | @RequestMapping("/receive_ticket")
26 | public Object receiveTicket(@RequestBody(required = false) String requestBody, @RequestParam("timestamp") String timestamp,
27 | @RequestParam("nonce") String nonce, @RequestParam("signature") String signature,
28 | @RequestParam(name = "encrypt_type", required = false) String encType,
29 | @RequestParam(name = "msg_signature", required = false) String msgSignature) {
30 | log.info(
31 | "\n接收微信请求:[signature=[{}], encType=[{}], msgSignature=[{}],"
32 | + " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ",
33 | signature, encType, msgSignature, timestamp, nonce, requestBody);
34 |
35 | if (!StringUtils.equalsIgnoreCase("aes", encType)
36 | || !wxOpenService.getWxOpenComponentService().checkSignature(timestamp, nonce, signature)) {
37 | throw new IllegalArgumentException("非法请求,可能属于伪造的请求!");
38 | }
39 |
40 | // aes加密的消息
41 | WxOpenXmlMessage inMessage = WxOpenXmlMessage.fromEncryptedXml(requestBody,
42 | wxOpenService.getWxOpenConfigStorage(), timestamp, nonce, msgSignature);
43 | log.debug("\n消息解密后内容为:\n{} ", inMessage.toString());
44 | try {
45 | String out = wxOpenService.getWxOpenComponentService().route(inMessage);
46 | log.debug("\n组装回复信息:{}", out);
47 | } catch (WxErrorException e) {
48 | log.error("receive_ticket", e);
49 | }
50 |
51 |
52 | return "success";
53 | }
54 |
55 | @RequestMapping("{appId}/callback")
56 | public Object callback(@RequestBody(required = false) String requestBody,
57 | @PathVariable("appId") String appId,
58 | @RequestParam("signature") String signature,
59 | @RequestParam("timestamp") String timestamp,
60 | @RequestParam("nonce") String nonce,
61 | @RequestParam("openid") String openid,
62 | @RequestParam("encrypt_type") String encType,
63 | @RequestParam("msg_signature") String msgSignature) {
64 | log.info(
65 | "\n接收微信请求:[appId=[{}], openid=[{}], signature=[{}], encType=[{}], msgSignature=[{}],"
66 | + " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ",
67 | appId, openid, signature, encType, msgSignature, timestamp, nonce, requestBody);
68 | if (!StringUtils.equalsIgnoreCase("aes", encType)
69 | || !wxOpenService.getWxOpenComponentService().checkSignature(timestamp, nonce, signature)) {
70 | throw new IllegalArgumentException("非法请求,可能属于伪造的请求!");
71 | }
72 |
73 | String out = "";
74 | // aes加密的消息
75 | WxMpXmlMessage inMessage = WxOpenXmlMessage.fromEncryptedMpXml(requestBody,
76 | wxOpenService.getWxOpenConfigStorage(), timestamp, nonce, msgSignature);
77 | log.debug("\n消息解密后内容为:\n{} ", inMessage.toString());
78 | // 全网发布测试用例
79 | if (StringUtils.equalsAnyIgnoreCase(appId, "wxd101a85aa106f53e", "wx570bc396a51b8ff8")) {
80 | try {
81 | if (StringUtils.equals(inMessage.getMsgType(), "text")) {
82 | if (StringUtils.equals(inMessage.getContent(), "TESTCOMPONENT_MSG_TYPE_TEXT")) {
83 | out = WxOpenXmlMessage.wxMpOutXmlMessageToEncryptedXml(
84 | WxMpXmlOutMessage.TEXT().content("TESTCOMPONENT_MSG_TYPE_TEXT_callback")
85 | .fromUser(inMessage.getToUser())
86 | .toUser(inMessage.getFromUser())
87 | .build(),
88 | wxOpenService.getWxOpenConfigStorage()
89 | );
90 | } else if (StringUtils.startsWith(inMessage.getContent(), "QUERY_AUTH_CODE:")) {
91 | String msg = inMessage.getContent().replace("QUERY_AUTH_CODE:", "") + "_from_api";
92 | WxMpKefuMessage kefuMessage = WxMpKefuMessage.TEXT().content(msg).toUser(inMessage.getFromUser()).build();
93 | wxOpenService.getWxOpenComponentService().getWxMpServiceByAppid(appId).getKefuService().sendKefuMessage(kefuMessage);
94 | }
95 | } else if (StringUtils.equals(inMessage.getMsgType(), "event")) {
96 | WxMpKefuMessage kefuMessage = WxMpKefuMessage.TEXT().content(inMessage.getEvent() + "from_callback").toUser(inMessage.getFromUser()).build();
97 | wxOpenService.getWxOpenComponentService().getWxMpServiceByAppid(appId).getKefuService().sendKefuMessage(kefuMessage);
98 | }
99 | } catch (WxErrorException e) {
100 | logger.error("callback", e);
101 | }
102 | }else{
103 | WxMpXmlOutMessage outMessage = wxOpenService.getWxOpenMessageRouter().route(inMessage, appId);
104 | if(outMessage != null){
105 | out = WxOpenXmlMessage.wxMpOutXmlMessageToEncryptedXml(outMessage, wxOpenService.getWxOpenConfigStorage());
106 | }
107 | }
108 | return out;
109 | }
110 | }
111 |
--------------------------------------------------------------------------------
/src/main/java/com/github/binarywang/demo/wx/open/service/WxOpenServiceDemo.java:
--------------------------------------------------------------------------------
1 | package com.github.binarywang.demo.wx.open.service;
2 |
3 | import com.github.binarywang.demo.wx.open.config.RedisProperies;
4 | import com.github.binarywang.demo.wx.open.config.WechatOpenProperties;
5 | import me.chanjar.weixin.open.api.impl.WxOpenInRedisConfigStorage;
6 | import me.chanjar.weixin.open.api.impl.WxOpenMessageRouter;
7 | import me.chanjar.weixin.open.api.impl.WxOpenServiceImpl;
8 | import org.slf4j.Logger;
9 | import org.slf4j.LoggerFactory;
10 | import org.springframework.beans.factory.annotation.Autowired;
11 | import org.springframework.boot.context.properties.EnableConfigurationProperties;
12 | import org.springframework.stereotype.Service;
13 | import redis.clients.jedis.JedisPool;
14 |
15 | import javax.annotation.PostConstruct;
16 |
17 | /**
18 | * @author 007
19 | */
20 | @Service
21 | @EnableConfigurationProperties({WechatOpenProperties.class, RedisProperies.class})
22 | public class WxOpenServiceDemo extends WxOpenServiceImpl {
23 | private Logger logger = LoggerFactory.getLogger(getClass());
24 | @Autowired
25 | private WechatOpenProperties wechatOpenProperties;
26 | @Autowired
27 | private RedisProperies redisProperies;
28 | private volatile static JedisPool pool;
29 | private WxOpenMessageRouter wxOpenMessageRouter;
30 |
31 | @PostConstruct
32 | public void init() {
33 | WxOpenInRedisConfigStorage inRedisConfigStorage = new WxOpenInRedisConfigStorage(getJedisPool());
34 | inRedisConfigStorage.setComponentAppId(wechatOpenProperties.getComponentAppId());
35 | inRedisConfigStorage.setComponentAppSecret(wechatOpenProperties.getComponentSecret());
36 | inRedisConfigStorage.setComponentToken(wechatOpenProperties.getComponentToken());
37 | inRedisConfigStorage.setComponentAesKey(wechatOpenProperties.getComponentAesKey());
38 | setWxOpenConfigStorage(inRedisConfigStorage);
39 | wxOpenMessageRouter = new WxOpenMessageRouter(this);
40 | wxOpenMessageRouter.rule().handler((wxMpXmlMessage, map, wxMpService, wxSessionManager) -> {
41 | logger.info("\n接收到 {} 公众号请求消息,内容:{}", wxMpService.getWxMpConfigStorage().getAppId(), wxMpXmlMessage);
42 | return null;
43 | }).next();
44 | }
45 | public WxOpenMessageRouter getWxOpenMessageRouter(){
46 | return wxOpenMessageRouter;
47 | }
48 |
49 | private JedisPool getJedisPool() {
50 | if (pool == null) {
51 | synchronized (WxOpenServiceDemo.class) {
52 | if (pool == null) {
53 | pool = new JedisPool(redisProperies, redisProperies.getHost(),
54 | redisProperies.getPort(), redisProperies.getConnectionTimeout(),
55 | redisProperies.getSoTimeout(), redisProperies.getPassword(),
56 | redisProperies.getDatabase(), redisProperies.getClientName(),
57 | redisProperies.isSsl(), redisProperies.getSslSocketFactory(),
58 | redisProperies.getSslParameters(), redisProperies.getHostnameVerifier());
59 | }
60 | }
61 | }
62 | return pool;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | logging:
2 | level:
3 | org.springframework.web: DEBUG
4 | com.github.binarywang.demo.wx.open: DEBUG
5 |
6 | wechat:
7 | open:
8 | componentAppId: ""
9 | componentSecret: ""
10 | componentToken: ""
11 | componentAesKey: ""
12 | redis:
13 | host: "127.0.0.1"
14 | server:
15 | port: 80
16 |
17 |
18 |
--------------------------------------------------------------------------------