mirror of
https://gitee.com/binary/weixin-java-tools.git
synced 2025-04-24 08:57:16 +08:00
初步实现一个使用Spring框架的Demo Web模块
This commit is contained in:
parent
29cfa7762e
commit
d29cc984bc
@ -1,25 +0,0 @@
|
|||||||
<?xml version="1.0"?>
|
|
||||||
<project
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
|
||||||
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<parent>
|
|
||||||
<groupId>com.github.binarywang</groupId>
|
|
||||||
<artifactId>weixin-java-parent</artifactId>
|
|
||||||
<version>1.3.6-SNAPSHOT</version>
|
|
||||||
</parent>
|
|
||||||
<artifactId>spring-demo</artifactId>
|
|
||||||
<packaging>war</packaging>
|
|
||||||
<name>WeiXin Java Tools - demo with spring</name>
|
|
||||||
<description>spring demo</description>
|
|
||||||
<url>https://github.com/binarywang/weixin-java-tools</url>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.github.binarywang</groupId>
|
|
||||||
<artifactId>weixin-java-common</artifactId>
|
|
||||||
<version>${project.version}</version>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</project>
|
|
1
weixin-java-demo-with-spring/.gitignore
vendored
Normal file
1
weixin-java-demo-with-spring/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
*.pmd
|
7
weixin-java-demo-with-spring/README.md
Normal file
7
weixin-java-demo-with-spring/README.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#### 本Demo使用Spring MVC 框架实现微信公众号后台管理功能,支持多公众号,欢迎帮忙维护添加新功能,或提供更好的实现。
|
||||||
|
### 1. 配置
|
||||||
|
复制/src/main/resources/wx-gzh1.properties.template 生成wx-gzh1.properties 文件,填写相关配置;
|
||||||
|
复制/src/main/resources/wx-gzh2.properties.template 生成wx-gzh2.properties 文件,填写相关配置.
|
||||||
|
|
||||||
|
### 2. 使用maven运行demo程序
|
||||||
|
mvn jetty:run
|
91
weixin-java-demo-with-spring/pom.xml
Normal file
91
weixin-java-demo-with-spring/pom.xml
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<project
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||||
|
xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>com.github.binarywang</groupId>
|
||||||
|
<artifactId>weixin-java-parent</artifactId>
|
||||||
|
<version>1.3.6-SNAPSHOT</version>
|
||||||
|
</parent>
|
||||||
|
<artifactId>weixin-java-demo-with-spring</artifactId>
|
||||||
|
<packaging>war</packaging>
|
||||||
|
<name>WeiXin Java Tools - DemoWithSpring</name>
|
||||||
|
<description>spring demo</description>
|
||||||
|
<url>https://github.com/binarywang/weixin-java-tools</url>
|
||||||
|
<properties>
|
||||||
|
<spring.version>4.3.0.RELEASE</spring.version>
|
||||||
|
<spring-security.version>4.1.0.RELEASE</spring-security.version>
|
||||||
|
<guava.version>19.0</guava.version>
|
||||||
|
<slf4j.version>1.7.2</slf4j.version>
|
||||||
|
<aspectj.version>1.8.9</aspectj.version>
|
||||||
|
<fastjson.version>1.2.6</fastjson.version>
|
||||||
|
<commons-lang3.version>3.1</commons-lang3.version>
|
||||||
|
<jetty-maven-plugin.version>9.3.10.v20160621</jetty-maven-plugin.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.binarywang</groupId>
|
||||||
|
<artifactId>weixin-java-mp</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>fastjson</artifactId>
|
||||||
|
<version>${fastjson.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>${commons-lang3.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
<version>${guava.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.slf4j</groupId>
|
||||||
|
<artifactId>slf4j-log4j12</artifactId>
|
||||||
|
<version>${slf4j.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-webmvc</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework</groupId>
|
||||||
|
<artifactId>spring-web</artifactId>
|
||||||
|
<version>${spring.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.security</groupId>
|
||||||
|
<artifactId>spring-security-core</artifactId>
|
||||||
|
<version>${spring-security.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.aspectj</groupId>
|
||||||
|
<artifactId>aspectjrt</artifactId>
|
||||||
|
<version>${aspectj.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.aspectj</groupId>
|
||||||
|
<artifactId>aspectjweaver</artifactId>
|
||||||
|
<version>${aspectj.version}</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
|
<artifactId>jetty-maven-plugin</artifactId>
|
||||||
|
<version>${jetty-maven-plugin.version}</version>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
@ -0,0 +1,80 @@
|
|||||||
|
package com.github.binarywang.demo.spring.aop;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
import org.aspectj.lang.JoinPoint;
|
||||||
|
import org.aspectj.lang.annotation.After;
|
||||||
|
import org.aspectj.lang.annotation.Aspect;
|
||||||
|
import org.aspectj.lang.annotation.Before;
|
||||||
|
import org.aspectj.lang.annotation.Pointcut;
|
||||||
|
import org.aspectj.lang.reflect.CodeSignature;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Binary Wang
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Aspect
|
||||||
|
@Component
|
||||||
|
public class ControllerLogAspect {
|
||||||
|
private Logger logger = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
|
@Pointcut("within(com.github.binarywang.demo.spring..*.controller..*)")
|
||||||
|
public void inController() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Pointcut("execution(public * com.github.binarywang.demo.spring..*.controller..*.*(..))")
|
||||||
|
public void controller() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before("inController()")
|
||||||
|
public void writeBeforeLog(JoinPoint jp) {
|
||||||
|
this.debugInController(jp, "Start");
|
||||||
|
}
|
||||||
|
|
||||||
|
@After("inController()")
|
||||||
|
public void writeAfterLog(JoinPoint jp) {
|
||||||
|
this.debugInController(jp, "End");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void debugInController(JoinPoint jp, String msg) {
|
||||||
|
String userName = getLoginUserName();
|
||||||
|
|
||||||
|
this.logger.debug("\n【{}】{}.{}() {} ", userName,
|
||||||
|
jp.getTarget()
|
||||||
|
.getClass().getSimpleName(), jp.getSignature().getName(), msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getLoginUserName() {
|
||||||
|
Authentication authentication = SecurityContextHolder.getContext()
|
||||||
|
.getAuthentication();
|
||||||
|
if (authentication != null) {
|
||||||
|
return authentication.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Anonymous";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Before("controller()")
|
||||||
|
public void writeParams(JoinPoint jp) {
|
||||||
|
String[] names = ((CodeSignature) jp.getSignature())
|
||||||
|
.getParameterNames();
|
||||||
|
Object[] args = jp.getArgs();
|
||||||
|
|
||||||
|
if (ArrayUtils.isEmpty(names)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder("Arguments: ");
|
||||||
|
for (int i = 0; i < names.length; i++) {
|
||||||
|
sb.append(names[i] + " = " + args[i] + ",");
|
||||||
|
}
|
||||||
|
|
||||||
|
debugInController(jp, sb.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package com.github.binarywang.demo.spring.builder;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.github.binarywang.demo.spring.service.BaseWxService;
|
||||||
|
|
||||||
|
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
|
||||||
|
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Binary Wang
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class AbstractBuilder {
|
||||||
|
protected final Logger logger = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
|
public abstract WxMpXmlOutMessage build(String content,
|
||||||
|
WxMpXmlMessage wxMessage, BaseWxService service) ;
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package com.github.binarywang.demo.spring.builder;
|
||||||
|
|
||||||
|
import com.github.binarywang.demo.spring.service.BaseWxService;
|
||||||
|
|
||||||
|
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
|
||||||
|
import me.chanjar.weixin.mp.bean.WxMpXmlOutImageMessage;
|
||||||
|
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Binary Wang
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class ImageBuilder extends AbstractBuilder {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WxMpXmlOutMessage build(String content, WxMpXmlMessage wxMessage,
|
||||||
|
BaseWxService service) {
|
||||||
|
|
||||||
|
WxMpXmlOutImageMessage m = WxMpXmlOutMessage.IMAGE().mediaId(content)
|
||||||
|
.fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package com.github.binarywang.demo.spring.builder;
|
||||||
|
|
||||||
|
import com.github.binarywang.demo.spring.service.BaseWxService;
|
||||||
|
|
||||||
|
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
|
||||||
|
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
|
||||||
|
import me.chanjar.weixin.mp.bean.WxMpXmlOutTextMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Binary Wang
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class TextBuilder extends AbstractBuilder {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WxMpXmlOutMessage build(String content, WxMpXmlMessage wxMessage,
|
||||||
|
BaseWxService service) {
|
||||||
|
WxMpXmlOutTextMessage m = WxMpXmlOutMessage.TEXT().content(content)
|
||||||
|
.fromUser(wxMessage.getToUserName()).toUser(wxMessage.getFromUserName())
|
||||||
|
.build();
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
package com.github.binarywang.demo.spring.config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 公众号标识的枚举类
|
||||||
|
* @author Binary Wang
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public enum WxAccountEnum {
|
||||||
|
GZH1(1, "公众号1"),
|
||||||
|
GZH2(2, "公众号2");
|
||||||
|
|
||||||
|
private int pubid;
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
private WxAccountEnum(int pubid, String name) {
|
||||||
|
this.name = name;
|
||||||
|
this.pubid = pubid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPubid() {
|
||||||
|
return this.pubid;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return this.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int queryPubid(String wxCode) {
|
||||||
|
return WxAccountEnum.valueOf(wxCode.toUpperCase()).getPubid();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String queryWxCode(int pubid) {
|
||||||
|
for (WxAccountEnum e : values()) {
|
||||||
|
if (e.getPubid() == pubid) {
|
||||||
|
return e.name().toLowerCase();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,21 @@
|
|||||||
|
package com.github.binarywang.demo.spring.config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 微信配置的抽象实现类
|
||||||
|
* @author Binary Wang
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class WxConfig {
|
||||||
|
public abstract String getToken();
|
||||||
|
|
||||||
|
public abstract String getAppid();
|
||||||
|
|
||||||
|
public abstract String getAppsecret();
|
||||||
|
|
||||||
|
public abstract WxAccountEnum getWxAccountEnum();
|
||||||
|
|
||||||
|
public int getPubId() {
|
||||||
|
return getWxAccountEnum().getPubid();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package com.github.binarywang.demo.spring.config;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Binary Wang
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class WxGzh1Config extends WxConfig {
|
||||||
|
@Value("#{gzh1WxProperties.wx_token}")
|
||||||
|
private String token;
|
||||||
|
|
||||||
|
@Value("#{gzh1WxProperties.wx_appid}")
|
||||||
|
private String appid;
|
||||||
|
|
||||||
|
@Value("#{gzh1WxProperties.wx_appsecret}")
|
||||||
|
private String appsecret;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getToken() {
|
||||||
|
return this.token;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAppid() {
|
||||||
|
return this.appid;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAppsecret() {
|
||||||
|
return this.appsecret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WxAccountEnum getWxAccountEnum() {
|
||||||
|
return WxAccountEnum.GZH1;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,42 @@
|
|||||||
|
package com.github.binarywang.demo.spring.config;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Binary Wang
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class WxGzh2Config extends WxConfig {
|
||||||
|
@Value("#{gzh2WxProperties.wx_token}")
|
||||||
|
private String token;
|
||||||
|
|
||||||
|
@Value("#{gzh2WxProperties.wx_appid}")
|
||||||
|
private String appid;
|
||||||
|
|
||||||
|
@Value("#{gzh2WxProperties.wx_appsecret}")
|
||||||
|
private String appsecret;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getToken() {
|
||||||
|
return this.token;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAppid() {
|
||||||
|
return this.appid;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getAppsecret() {
|
||||||
|
return this.appsecret;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WxAccountEnum getWxAccountEnum() {
|
||||||
|
return WxAccountEnum.GZH2;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
package com.github.binarywang.demo.spring.controller;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMethod;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
|
import com.github.binarywang.demo.spring.service.BaseWxService;
|
||||||
|
|
||||||
|
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
|
||||||
|
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Binary Wang
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class AbstractWxPortalController {
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
|
@RequestMapping(method = RequestMethod.GET, produces = "text/plain;charset=utf-8")
|
||||||
|
public @ResponseBody String authGet(
|
||||||
|
@RequestParam("signature") String signature,
|
||||||
|
@RequestParam("timestamp") String timestamp,
|
||||||
|
@RequestParam("nonce") String nonce,
|
||||||
|
@RequestParam("echostr") String echostr) {
|
||||||
|
this.logger.info("接收到来自微信服务器的认证消息");
|
||||||
|
|
||||||
|
if (this.getWxService().checkSignature(timestamp, nonce, signature)) {
|
||||||
|
return echostr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "非法请求";
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequestMapping(method = RequestMethod.POST, produces = "application/xml; charset=UTF-8")
|
||||||
|
public @ResponseBody String post(@RequestBody String requestBody) {
|
||||||
|
|
||||||
|
this.logger.debug("\n接收微信请求:{} ", requestBody);
|
||||||
|
|
||||||
|
BaseWxService wxService = this.getWxService();
|
||||||
|
|
||||||
|
WxMpXmlOutMessage out = wxService
|
||||||
|
.route(WxMpXmlMessage.fromXml(requestBody));
|
||||||
|
|
||||||
|
if (out == null) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
String outXml = out.toXml();
|
||||||
|
|
||||||
|
this.logger.debug("\n组装回复信息:{}", outXml);
|
||||||
|
|
||||||
|
return outXml;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract BaseWxService getWxService();
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package com.github.binarywang.demo.spring.controller;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import com.github.binarywang.demo.spring.service.BaseWxService;
|
||||||
|
import com.github.binarywang.demo.spring.service.Gzh1WxService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 第一个公众号的微信交互接口
|
||||||
|
* @author Binary Wang
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/gzh1/portal")
|
||||||
|
public class Gzh1WxPortalController extends AbstractWxPortalController{
|
||||||
|
@Autowired
|
||||||
|
private Gzh1WxService wxService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected BaseWxService getWxService() {
|
||||||
|
return this.wxService;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package com.github.binarywang.demo.spring.controller;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
import com.github.binarywang.demo.spring.service.BaseWxService;
|
||||||
|
import com.github.binarywang.demo.spring.service.Gzh2WxService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 第二个公众号的微信交互接口
|
||||||
|
* @author Binary Wang
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/gzh2/portal")
|
||||||
|
public class Gzh2WxPortalController extends AbstractWxPortalController{
|
||||||
|
@Autowired
|
||||||
|
private Gzh2WxService wxService;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected BaseWxService getWxService() {
|
||||||
|
return this.wxService;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
package com.github.binarywang.demo.spring.dto;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.builder.ToStringBuilder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 菜单的dto对象
|
||||||
|
* @author Binary Wang
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public class WxMenuKey {
|
||||||
|
private String type;
|
||||||
|
private String content;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return ToStringBuilder.reflectionToString(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WxMenuKey() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public WxMenuKey(String type, String content) {
|
||||||
|
this.type = type;
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return this.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setType(String type) {
|
||||||
|
this.type = type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getContent() {
|
||||||
|
return this.content;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setContent(String content) {
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
package com.github.binarywang.demo.spring.handler;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import com.github.binarywang.demo.spring.config.WxConfig;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
import me.chanjar.weixin.mp.api.WxMpMessageHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Binary Wang
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class AbstractHandler implements WxMpMessageHandler {
|
||||||
|
|
||||||
|
protected Logger logger = LoggerFactory.getLogger(getClass());
|
||||||
|
protected final Gson gson = new Gson();
|
||||||
|
|
||||||
|
protected abstract WxConfig getWxConfig();
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package com.github.binarywang.demo.spring.handler;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.github.binarywang.demo.spring.builder.TextBuilder;
|
||||||
|
|
||||||
|
import me.chanjar.weixin.common.api.WxConsts;
|
||||||
|
import me.chanjar.weixin.common.exception.WxErrorException;
|
||||||
|
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||||
|
import me.chanjar.weixin.mp.api.WxMpService;
|
||||||
|
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
|
||||||
|
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Binary Wang
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class LocationHandler extends AbstractHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
|
||||||
|
Map<String, Object> context, WxMpService wxMpService,
|
||||||
|
WxSessionManager sessionManager) throws WxErrorException {
|
||||||
|
if (wxMessage.getMsgType().equals(WxConsts.XML_MSG_LOCATION)) {
|
||||||
|
//TODO 接收处理用户发送的地理位置消息
|
||||||
|
try {
|
||||||
|
String content = "感谢反馈,您的的地理位置已收到!";
|
||||||
|
return new TextBuilder().build(content, wxMessage, null);
|
||||||
|
} catch (Exception e) {
|
||||||
|
this.logger.error("位置消息接收处理失败", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//上报地理位置事件
|
||||||
|
this.logger.info("\n上报地理位置 。。。 ");
|
||||||
|
this.logger.info("\n纬度 : " + wxMessage.getLatitude());
|
||||||
|
this.logger.info("\n经度 : " + wxMessage.getLongitude());
|
||||||
|
this.logger.info("\n精度 : " + String.valueOf(wxMessage.getPrecision()));
|
||||||
|
|
||||||
|
//TODO 可以将用户地理位置信息保存到本地数据库,以便以后使用
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,71 @@
|
|||||||
|
package com.github.binarywang.demo.spring.handler;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.JSON;
|
||||||
|
import com.github.binarywang.demo.spring.builder.AbstractBuilder;
|
||||||
|
import com.github.binarywang.demo.spring.builder.ImageBuilder;
|
||||||
|
import com.github.binarywang.demo.spring.builder.TextBuilder;
|
||||||
|
import com.github.binarywang.demo.spring.dto.WxMenuKey;
|
||||||
|
import com.github.binarywang.demo.spring.service.BaseWxService;
|
||||||
|
|
||||||
|
import me.chanjar.weixin.common.api.WxConsts;
|
||||||
|
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||||
|
import me.chanjar.weixin.mp.api.WxMpService;
|
||||||
|
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
|
||||||
|
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Binary Wang
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class MenuHandler extends AbstractHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
|
||||||
|
Map<String, Object> context, WxMpService wxMpService,
|
||||||
|
WxSessionManager sessionManager) {
|
||||||
|
BaseWxService weixinService = (BaseWxService) wxMpService;
|
||||||
|
|
||||||
|
String key = wxMessage.getEventKey();
|
||||||
|
WxMenuKey menuKey = null;
|
||||||
|
try {
|
||||||
|
menuKey = JSON.parseObject(key, WxMenuKey.class);
|
||||||
|
} catch (Exception e) {
|
||||||
|
return WxMpXmlOutMessage.TEXT().content(key)
|
||||||
|
.fromUser(wxMessage.getToUserName())
|
||||||
|
.toUser(wxMessage.getFromUserName()).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
AbstractBuilder builder = null;
|
||||||
|
switch (menuKey.getType()) {
|
||||||
|
case WxConsts.XML_MSG_TEXT:
|
||||||
|
builder = new TextBuilder();
|
||||||
|
break;
|
||||||
|
case WxConsts.XML_MSG_IMAGE:
|
||||||
|
builder = new ImageBuilder();
|
||||||
|
break;
|
||||||
|
case WxConsts.XML_MSG_VOICE:
|
||||||
|
break;
|
||||||
|
case WxConsts.XML_MSG_VIDEO:
|
||||||
|
break;
|
||||||
|
case WxConsts.XML_MSG_NEWS:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (builder != null) {
|
||||||
|
try {
|
||||||
|
return builder.build(menuKey.getContent(), wxMessage, weixinService);
|
||||||
|
} catch (Exception e) {
|
||||||
|
this.logger.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,48 @@
|
|||||||
|
package com.github.binarywang.demo.spring.handler;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import com.github.binarywang.demo.spring.builder.TextBuilder;
|
||||||
|
import com.github.binarywang.demo.spring.service.BaseWxService;
|
||||||
|
|
||||||
|
import me.chanjar.weixin.common.api.WxConsts;
|
||||||
|
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||||
|
import me.chanjar.weixin.mp.api.WxMpService;
|
||||||
|
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
|
||||||
|
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Binary Wang
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class MsgHandler extends AbstractHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
|
||||||
|
Map<String, Object> context, WxMpService wxMpService,
|
||||||
|
WxSessionManager sessionManager) {
|
||||||
|
|
||||||
|
BaseWxService weixinService = (BaseWxService) wxMpService;
|
||||||
|
|
||||||
|
if (!wxMessage.getMsgType().equals(WxConsts.XML_MSG_EVENT)) {
|
||||||
|
//TODO 可以选择将消息保存到本地
|
||||||
|
}
|
||||||
|
|
||||||
|
//当用户输入关键词如“你好”,“在吗”等并且有客服在线时,把消息转发给在线客服
|
||||||
|
if (StringUtils.startsWithAny(wxMessage.getContent(), "你好", "在吗")
|
||||||
|
&& weixinService.isCustomerServiceOnline()) {
|
||||||
|
return WxMpXmlOutMessage
|
||||||
|
.TRANSFER_CUSTOMER_SERVICE().fromUser(wxMessage.getToUserName())
|
||||||
|
.toUser(wxMessage.getFromUserName()).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO 组装回复消息
|
||||||
|
String content = "回复信息内容";
|
||||||
|
return new TextBuilder().build(content, wxMessage, weixinService);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,34 @@
|
|||||||
|
package com.github.binarywang.demo.spring.handler;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import com.github.binarywang.demo.spring.config.WxConfig;
|
||||||
|
|
||||||
|
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||||
|
import me.chanjar.weixin.mp.api.WxMpService;
|
||||||
|
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
|
||||||
|
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Binary Wang
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Component
|
||||||
|
public class NullHandler extends AbstractHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
|
||||||
|
Map<String, Object> context, WxMpService wxMpService,
|
||||||
|
WxSessionManager sessionManager) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected WxConfig getWxConfig() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,10 @@
|
|||||||
|
package com.github.binarywang.demo.spring.handler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Binary Wang
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class ScanHandler extends AbstractHandler {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
package com.github.binarywang.demo.spring.handler;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.github.binarywang.demo.spring.builder.TextBuilder;
|
||||||
|
import com.github.binarywang.demo.spring.service.BaseWxService;
|
||||||
|
|
||||||
|
import me.chanjar.weixin.common.exception.WxErrorException;
|
||||||
|
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||||
|
import me.chanjar.weixin.mp.api.WxMpService;
|
||||||
|
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
|
||||||
|
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
|
||||||
|
import me.chanjar.weixin.mp.bean.result.WxMpUser;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Binary Wang
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class SubscribeHandler extends AbstractHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, Map<String, Object> context, WxMpService wxMpService,
|
||||||
|
WxSessionManager sessionManager) throws WxErrorException {
|
||||||
|
|
||||||
|
this.logger.info("新关注用户 OPENID: " + wxMessage.getFromUserName());
|
||||||
|
|
||||||
|
BaseWxService weixinService = (BaseWxService) wxMpService;
|
||||||
|
|
||||||
|
// 获取微信用户基本信息
|
||||||
|
WxMpUser userWxInfo = weixinService.userInfo(wxMessage.getFromUserName(), null);
|
||||||
|
|
||||||
|
if (userWxInfo != null) {
|
||||||
|
// TODO 可以添加关注用户到本地
|
||||||
|
}
|
||||||
|
|
||||||
|
WxMpXmlOutMessage responsResult = null;
|
||||||
|
try {
|
||||||
|
responsResult = handleSpecial(wxMessage);
|
||||||
|
} catch (Exception e) {
|
||||||
|
this.logger.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (responsResult != null) {
|
||||||
|
return responsResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
return new TextBuilder().build("感谢关注", wxMessage, weixinService);
|
||||||
|
} catch (Exception e) {
|
||||||
|
this.logger.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 处理特殊请求,比如如果是扫码进来的,可以做相应处理
|
||||||
|
*/
|
||||||
|
protected abstract WxMpXmlOutMessage handleSpecial(WxMpXmlMessage wxMessage) throws Exception;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
package com.github.binarywang.demo.spring.handler;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import me.chanjar.weixin.common.session.WxSessionManager;
|
||||||
|
import me.chanjar.weixin.mp.api.WxMpService;
|
||||||
|
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
|
||||||
|
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Binary Wang
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class UnsubscribeHandler extends AbstractHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage,
|
||||||
|
Map<String, Object> context, WxMpService wxMpService,
|
||||||
|
WxSessionManager sessionManager) {
|
||||||
|
String openId = wxMessage.getFromUserName();
|
||||||
|
this.logger.info("取消关注用户 OPENID: " + openId);
|
||||||
|
// TODO 可以更新本地数据库为取消关注状态
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,129 @@
|
|||||||
|
package com.github.binarywang.demo.spring.service;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
import com.github.binarywang.demo.spring.config.WxConfig;
|
||||||
|
import com.github.binarywang.demo.spring.handler.AbstractHandler;
|
||||||
|
import com.github.binarywang.demo.spring.handler.MenuHandler;
|
||||||
|
import com.github.binarywang.demo.spring.handler.MsgHandler;
|
||||||
|
import com.github.binarywang.demo.spring.handler.NullHandler;
|
||||||
|
import com.github.binarywang.demo.spring.handler.SubscribeHandler;
|
||||||
|
import com.github.binarywang.demo.spring.handler.UnsubscribeHandler;
|
||||||
|
import com.google.gson.JsonArray;
|
||||||
|
import com.google.gson.JsonParser;
|
||||||
|
|
||||||
|
import me.chanjar.weixin.common.api.WxConsts;
|
||||||
|
import me.chanjar.weixin.mp.api.WxMpInMemoryConfigStorage;
|
||||||
|
import me.chanjar.weixin.mp.api.WxMpMessageRouter;
|
||||||
|
import me.chanjar.weixin.mp.api.WxMpServiceImpl;
|
||||||
|
import me.chanjar.weixin.mp.bean.WxMpXmlMessage;
|
||||||
|
import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Binary Wang
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public abstract class BaseWxService extends WxMpServiceImpl {
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
protected NullHandler nullHandler;
|
||||||
|
|
||||||
|
private WxMpMessageRouter router;
|
||||||
|
|
||||||
|
protected abstract WxConfig getServerConfig();
|
||||||
|
|
||||||
|
protected abstract MenuHandler getMenuHandler();
|
||||||
|
|
||||||
|
protected abstract SubscribeHandler getSubscribeHandler();
|
||||||
|
|
||||||
|
protected abstract UnsubscribeHandler getUnsubscribeHandler();
|
||||||
|
|
||||||
|
protected abstract AbstractHandler getLocationHandler();
|
||||||
|
|
||||||
|
protected abstract MsgHandler getMsgHandler();
|
||||||
|
|
||||||
|
protected abstract AbstractHandler getScanHandler();
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
final WxMpInMemoryConfigStorage config = new WxMpInMemoryConfigStorage();
|
||||||
|
config.setAppId(this.getServerConfig().getAppid());// 设置微信公众号的appid
|
||||||
|
config.setSecret(this.getServerConfig().getAppsecret());// 设置微信公众号的app corpSecret
|
||||||
|
config.setToken(this.getServerConfig().getToken());// 设置微信公众号的token
|
||||||
|
super.setWxMpConfigStorage(config);
|
||||||
|
|
||||||
|
this.refreshRouter();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshRouter() {
|
||||||
|
|
||||||
|
final WxMpMessageRouter newRouter = new WxMpMessageRouter(this);
|
||||||
|
|
||||||
|
// 自定义菜单事件
|
||||||
|
newRouter.rule().async(false).event(WxConsts.BUTTON_CLICK)
|
||||||
|
.handler(this.getMenuHandler()).end();
|
||||||
|
|
||||||
|
// 点击菜单连接事件
|
||||||
|
newRouter.rule().async(false).msgType(WxConsts.XML_MSG_EVENT)
|
||||||
|
.event(WxConsts.BUTTON_VIEW).handler(this.nullHandler).end();
|
||||||
|
|
||||||
|
// 关注事件
|
||||||
|
newRouter.rule().async(false).msgType(WxConsts.XML_MSG_EVENT)
|
||||||
|
.event(WxConsts.EVT_SUBSCRIBE).handler(this.getSubscribeHandler())
|
||||||
|
.end();
|
||||||
|
|
||||||
|
// 取消关注事件
|
||||||
|
newRouter.rule().async(false).msgType(WxConsts.XML_MSG_EVENT)
|
||||||
|
.event(WxConsts.EVT_UNSUBSCRIBE).handler(this.getUnsubscribeHandler())
|
||||||
|
.end();
|
||||||
|
|
||||||
|
// 上报地理位置事件
|
||||||
|
newRouter.rule().async(false).msgType(WxConsts.XML_MSG_EVENT)
|
||||||
|
.event(WxConsts.EVT_LOCATION).handler(this.getLocationHandler()).end();
|
||||||
|
|
||||||
|
// 接收地理位置消息
|
||||||
|
newRouter.rule().async(false).msgType(WxConsts.XML_MSG_LOCATION)
|
||||||
|
.handler(this.getLocationHandler()).end();
|
||||||
|
|
||||||
|
// 扫码事件
|
||||||
|
newRouter.rule().async(false).msgType(WxConsts.XML_MSG_EVENT)
|
||||||
|
.event(WxConsts.EVT_SCAN).handler(this.getScanHandler()).end();
|
||||||
|
|
||||||
|
// 默认
|
||||||
|
newRouter.rule().async(false).handler(this.getMsgHandler()).end();
|
||||||
|
|
||||||
|
this.router = newRouter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public WxMpXmlOutMessage route(WxMpXmlMessage message) {
|
||||||
|
try {
|
||||||
|
final WxMpXmlOutMessage responseMessage = this.router.route(message);
|
||||||
|
return responseMessage;
|
||||||
|
} catch (Exception e) {
|
||||||
|
this.logger.error(e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isCustomerServiceOnline() {
|
||||||
|
try {
|
||||||
|
String url = "https://api.weixin.qq.com/cgi-bin/customservice/getonlinekflist";
|
||||||
|
String executeResult = this.get(url, null);
|
||||||
|
JsonArray jsonArray = new JsonParser().parse(executeResult)
|
||||||
|
.getAsJsonObject().get("kf_online_list").getAsJsonArray();
|
||||||
|
return jsonArray.size() > 0;
|
||||||
|
} catch (Exception e) {
|
||||||
|
this.logger.error("获取客服在线状态异常: " + e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,65 @@
|
|||||||
|
package com.github.binarywang.demo.spring.service;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import com.github.binarywang.demo.spring.config.WxGzh1Config;
|
||||||
|
import com.github.binarywang.demo.spring.config.WxConfig;
|
||||||
|
import com.github.binarywang.demo.spring.handler.AbstractHandler;
|
||||||
|
import com.github.binarywang.demo.spring.handler.MenuHandler;
|
||||||
|
import com.github.binarywang.demo.spring.handler.MsgHandler;
|
||||||
|
import com.github.binarywang.demo.spring.handler.SubscribeHandler;
|
||||||
|
import com.github.binarywang.demo.spring.handler.UnsubscribeHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Binary Wang
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class Gzh1WxService extends BaseWxService {
|
||||||
|
@Autowired
|
||||||
|
private WxGzh1Config wxConfig;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected WxConfig getServerConfig() {
|
||||||
|
return this.wxConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected MenuHandler getMenuHandler() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SubscribeHandler getSubscribeHandler() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected UnsubscribeHandler getUnsubscribeHandler() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected AbstractHandler getLocationHandler() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected MsgHandler getMsgHandler() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected AbstractHandler getScanHandler() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
package com.github.binarywang.demo.spring.service;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import com.github.binarywang.demo.spring.config.WxGzh2Config;
|
||||||
|
import com.github.binarywang.demo.spring.config.WxConfig;
|
||||||
|
import com.github.binarywang.demo.spring.handler.AbstractHandler;
|
||||||
|
import com.github.binarywang.demo.spring.handler.MenuHandler;
|
||||||
|
import com.github.binarywang.demo.spring.handler.MsgHandler;
|
||||||
|
import com.github.binarywang.demo.spring.handler.SubscribeHandler;
|
||||||
|
import com.github.binarywang.demo.spring.handler.UnsubscribeHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Binary Wang
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class Gzh2WxService extends BaseWxService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WxGzh2Config wxConfig;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected WxConfig getServerConfig() {
|
||||||
|
return this.wxConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected MenuHandler getMenuHandler() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected SubscribeHandler getSubscribeHandler() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected UnsubscribeHandler getUnsubscribeHandler() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected AbstractHandler getLocationHandler() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected MsgHandler getMsgHandler() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected AbstractHandler getScanHandler() {
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
2
weixin-java-demo-with-spring/src/main/resources/.gitignore
vendored
Normal file
2
weixin-java-demo-with-spring/src/main/resources/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
/wx-gzh1.properties
|
||||||
|
/wx-gzh2.properties
|
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
|
||||||
|
xmlns:context="http://www.springframework.org/schema/context"
|
||||||
|
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:util="http://www.springframework.org/schema/util"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
|
||||||
|
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
|
||||||
|
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||||
|
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
|
||||||
|
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
|
||||||
|
|
||||||
|
<import resource="classpath*:spring-service-bean.xml" />
|
||||||
|
|
||||||
|
<util:properties id="gzh1WxProperties" location="classpath:/wx-gzh1.properties" />
|
||||||
|
<util:properties id="gzh2WxProperties" location="classpath:/wx-gzh2.properties" />
|
||||||
|
|
||||||
|
</beans>
|
@ -0,0 +1,8 @@
|
|||||||
|
log4j.rootLogger=DEBUG, stdout
|
||||||
|
|
||||||
|
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
|
||||||
|
log4j.appender.stdout.Target=System.out
|
||||||
|
log4j.appender.stdout.layout=org.apache.log4j.EnhancedPatternLayout
|
||||||
|
log4j.appender.stdout.layout.ConversionPattern=[%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} [%t]:%c:%L#%M() %m%n
|
||||||
|
|
||||||
|
log4j.logger.org.apache.http.impl.conn.PoolingHttpClientConnectionManager=INFO
|
@ -0,0 +1,29 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
|
||||||
|
xmlns:amq="http://activemq.apache.org/schema/core" xmlns:util="http://www.springframework.org/schema/util"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||||
|
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
|
||||||
|
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
|
||||||
|
|
||||||
|
<context:component-scan base-package="com.github.binarywang.demo.spring">
|
||||||
|
<context:exclude-filter type="annotation"
|
||||||
|
expression="org.springframework.stereotype.Controller" />
|
||||||
|
</context:component-scan>
|
||||||
|
|
||||||
|
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
|
||||||
|
<property name="messageConverters">
|
||||||
|
<list>
|
||||||
|
<bean
|
||||||
|
class="org.springframework.http.converter.StringHttpMessageConverter">
|
||||||
|
<constructor-arg>
|
||||||
|
<value>UTF-8</value>
|
||||||
|
</constructor-arg>
|
||||||
|
</bean>
|
||||||
|
<bean
|
||||||
|
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
</beans>
|
@ -0,0 +1,43 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
|
||||||
|
xmlns:context="http://www.springframework.org/schema/context"
|
||||||
|
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:task="http://www.springframework.org/schema/task"
|
||||||
|
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
|
||||||
|
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
|
||||||
|
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
|
||||||
|
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
|
||||||
|
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">
|
||||||
|
<!-- only scan the Controller class for web context -->
|
||||||
|
<context:component-scan base-package="com.github.binarywang.demo.spring">
|
||||||
|
<context:include-filter type="annotation"
|
||||||
|
expression="org.springframework.stereotype.Controller" />
|
||||||
|
</context:component-scan>
|
||||||
|
|
||||||
|
<mvc:annotation-driven>
|
||||||
|
<mvc:message-converters>
|
||||||
|
<ref bean="jsonConverter" />
|
||||||
|
<ref bean="stringHttpMessageConverter" />
|
||||||
|
</mvc:message-converters>
|
||||||
|
</mvc:annotation-driven>
|
||||||
|
|
||||||
|
<mvc:default-servlet-handler />
|
||||||
|
|
||||||
|
<bean id="stringHttpMessageConverter"
|
||||||
|
class="org.springframework.http.converter.StringHttpMessageConverter">
|
||||||
|
<property name="supportedMediaTypes">
|
||||||
|
<list>
|
||||||
|
<value>text/html;charset=UTF-8</value>
|
||||||
|
<value>text/plain;charset=UTF-8</value>
|
||||||
|
</list>
|
||||||
|
</property>
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<bean id="jsonConverter"
|
||||||
|
class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
|
||||||
|
<property name="supportedMediaTypes" value="application/json" />
|
||||||
|
</bean>
|
||||||
|
|
||||||
|
<aop:aspectj-autoproxy proxy-target-class="true" />
|
||||||
|
|
||||||
|
</beans>
|
@ -0,0 +1,3 @@
|
|||||||
|
wx_appid=
|
||||||
|
wx_appsecret=
|
||||||
|
wx_token=
|
@ -0,0 +1,3 @@
|
|||||||
|
wx_appid=
|
||||||
|
wx_appsecret=
|
||||||
|
wx_token=
|
@ -20,14 +20,6 @@
|
|||||||
<filter-name>encodingFilter</filter-name>
|
<filter-name>encodingFilter</filter-name>
|
||||||
<url-pattern>/*</url-pattern>
|
<url-pattern>/*</url-pattern>
|
||||||
</filter-mapping>
|
</filter-mapping>
|
||||||
<filter>
|
|
||||||
<filter-name>springSecurityFilterChain</filter-name>
|
|
||||||
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
|
|
||||||
</filter>
|
|
||||||
<filter-mapping>
|
|
||||||
<filter-name>springSecurityFilterChain</filter-name>
|
|
||||||
<url-pattern>/v1/admin/*</url-pattern>
|
|
||||||
</filter-mapping>
|
|
||||||
|
|
||||||
<listener>
|
<listener>
|
||||||
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
|
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
|
Loading…
Reference in New Issue
Block a user