| @@ -1 +0,0 @@ | |||||
| *.pmd | |||||
| @@ -1,7 +0,0 @@ | |||||
| #### 本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 | |||||
| @@ -1,91 +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>2.0.0-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.4</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> | |||||
| @@ -1,80 +0,0 @@ | |||||
| 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()); | |||||
| } | |||||
| } | |||||
| @@ -1,21 +0,0 @@ | |||||
| 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) ; | |||||
| } | |||||
| @@ -1,27 +0,0 @@ | |||||
| 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; | |||||
| } | |||||
| } | |||||
| @@ -1,25 +0,0 @@ | |||||
| 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; | |||||
| } | |||||
| } | |||||
| @@ -1,41 +0,0 @@ | |||||
| 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; | |||||
| } | |||||
| } | |||||
| @@ -1,23 +0,0 @@ | |||||
| 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 String getAesKey(); | |||||
| public abstract WxAccountEnum getWxAccountEnum(); | |||||
| public int getPubId() { | |||||
| return getWxAccountEnum().getPubid(); | |||||
| } | |||||
| } | |||||
| @@ -1,50 +0,0 @@ | |||||
| 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; | |||||
| @Value("#{gzh1WxProperties.wx_aeskey}") | |||||
| private String aesKey; | |||||
| @Override | |||||
| public String getToken() { | |||||
| return this.token; | |||||
| } | |||||
| @Override | |||||
| public String getAppid() { | |||||
| return this.appid; | |||||
| } | |||||
| @Override | |||||
| public String getAppsecret() { | |||||
| return this.appsecret; | |||||
| } | |||||
| @Override | |||||
| public String getAesKey() { | |||||
| return this.aesKey; | |||||
| } | |||||
| @Override | |||||
| public WxAccountEnum getWxAccountEnum() { | |||||
| return WxAccountEnum.GZH1; | |||||
| } | |||||
| } | |||||
| @@ -1,50 +0,0 @@ | |||||
| 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; | |||||
| @Value("#{gzh2WxProperties.wx_aeskey}") | |||||
| private String aesKey; | |||||
| @Override | |||||
| public String getToken() { | |||||
| return this.token; | |||||
| } | |||||
| @Override | |||||
| public String getAppid() { | |||||
| return this.appid; | |||||
| } | |||||
| @Override | |||||
| public String getAppsecret() { | |||||
| return this.appsecret; | |||||
| } | |||||
| @Override | |||||
| public String getAesKey() { | |||||
| return this.aesKey; | |||||
| } | |||||
| @Override | |||||
| public WxAccountEnum getWxAccountEnum() { | |||||
| return WxAccountEnum.GZH2; | |||||
| } | |||||
| } | |||||
| @@ -1,80 +0,0 @@ | |||||
| package com.github.binarywang.demo.spring.controller; | |||||
| import org.apache.commons.lang3.StringUtils; | |||||
| 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("\n接收到来自微信服务器的认证消息:[{},{},{},{}]", | |||||
| signature, timestamp, nonce, echostr); | |||||
| 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, | |||||
| @RequestParam("signature") String signature, | |||||
| @RequestParam("encrypt_type") String encType, | |||||
| @RequestParam("msg_signature") String msgSignature, | |||||
| @RequestParam("timestamp") String timestamp, | |||||
| @RequestParam("nonce") String nonce) { | |||||
| this.logger.info("\n接收微信请求:[{},{},{},{},{}]\n{} ", | |||||
| signature, encType, msgSignature, timestamp, nonce, requestBody); | |||||
| String out = null; | |||||
| if (encType == null) { | |||||
| // 明文传输的消息 | |||||
| WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(requestBody); | |||||
| WxMpXmlOutMessage outMessage = this.getWxService().route(inMessage); | |||||
| if (outMessage == null) { | |||||
| return ""; | |||||
| } | |||||
| out = outMessage.toXml(); | |||||
| }else if ("aes".equals(encType)) { | |||||
| // aes加密的消息 | |||||
| WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(requestBody, | |||||
| this.getWxService().getWxMpConfigStorage(), timestamp, nonce, msgSignature); | |||||
| this.logger.debug("\n消息解密后内容为:\n{} ", inMessage.toString()); | |||||
| WxMpXmlOutMessage outMessage = this.getWxService().route(inMessage); | |||||
| if (outMessage == null) { | |||||
| return ""; | |||||
| } | |||||
| out = outMessage.toEncryptedXml(this.getWxService().getWxMpConfigStorage()); | |||||
| } | |||||
| this.logger.debug("\n组装回复信息:{}", out); | |||||
| return out; | |||||
| } | |||||
| protected abstract BaseWxService getWxService(); | |||||
| } | |||||
| @@ -1,26 +0,0 @@ | |||||
| 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; | |||||
| } | |||||
| } | |||||
| @@ -1,26 +0,0 @@ | |||||
| 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; | |||||
| } | |||||
| } | |||||
| @@ -1,44 +0,0 @@ | |||||
| 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; | |||||
| } | |||||
| } | |||||
| @@ -1,23 +0,0 @@ | |||||
| 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(); | |||||
| } | |||||
| @@ -1,36 +0,0 @@ | |||||
| 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.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 | |||||
| * | |||||
| */ | |||||
| @Component | |||||
| public class KfSessionHandler extends AbstractHandler{ | |||||
| @Override | |||||
| public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, | |||||
| Map<String, Object> context, WxMpService wxMpService, | |||||
| WxSessionManager sessionManager) throws WxErrorException { | |||||
| //TODO 对会话做处理 | |||||
| return null; | |||||
| } | |||||
| @Override | |||||
| protected WxConfig getWxConfig() { | |||||
| return null; | |||||
| } | |||||
| } | |||||
| @@ -1,47 +0,0 @@ | |||||
| 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; | |||||
| } | |||||
| } | |||||
| @@ -1,34 +0,0 @@ | |||||
| 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 LogHandler extends AbstractHandler { | |||||
| @Override | |||||
| public WxMpXmlOutMessage handle(WxMpXmlMessage wxMessage, | |||||
| Map<String, Object> context, WxMpService wxMpService, | |||||
| WxSessionManager sessionManager) { | |||||
| this.logger.info("\n接收到请求消息,内容:【{}】", wxMessage.toString()); | |||||
| return null; | |||||
| } | |||||
| @Override | |||||
| protected WxConfig getWxConfig() { | |||||
| return null; | |||||
| } | |||||
| } | |||||
| @@ -1,71 +0,0 @@ | |||||
| 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; | |||||
| } | |||||
| } | |||||
| @@ -1,48 +0,0 @@ | |||||
| 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.hasKefuOnline()) { | |||||
| return WxMpXmlOutMessage | |||||
| .TRANSFER_CUSTOMER_SERVICE().fromUser(wxMessage.getToUserName()) | |||||
| .toUser(wxMessage.getFromUserName()).build(); | |||||
| } | |||||
| //TODO 组装回复消息 | |||||
| String content = "回复信息内容"; | |||||
| return new TextBuilder().build(content, wxMessage, weixinService); | |||||
| } | |||||
| } | |||||
| @@ -1,34 +0,0 @@ | |||||
| 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; | |||||
| } | |||||
| } | |||||
| @@ -1,10 +0,0 @@ | |||||
| package com.github.binarywang.demo.spring.handler; | |||||
| /** | |||||
| * | |||||
| * @author Binary Wang | |||||
| * | |||||
| */ | |||||
| public abstract class ScanHandler extends AbstractHandler { | |||||
| } | |||||
| @@ -1,61 +0,0 @@ | |||||
| package com.github.binarywang.demo.spring.handler; | |||||
| 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; | |||||
| import java.util.Map; | |||||
| /** | |||||
| * | |||||
| * @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.getUserService().userInfo(wxMessage.getFromUserName(), null); | |||||
| if (userWxInfo != null) { | |||||
| // TODO 可以添加关注用户到本地 | |||||
| } | |||||
| WxMpXmlOutMessage responseResult = null; | |||||
| try { | |||||
| responseResult = handleSpecial(wxMessage); | |||||
| } catch (Exception e) { | |||||
| this.logger.error(e.getMessage(), e); | |||||
| } | |||||
| if (responseResult != null) { | |||||
| return responseResult; | |||||
| } | |||||
| 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; | |||||
| } | |||||
| @@ -1,27 +0,0 @@ | |||||
| 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; | |||||
| } | |||||
| } | |||||
| @@ -1,23 +0,0 @@ | |||||
| package com.github.binarywang.demo.spring.handler.gzh1; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.beans.factory.config.ConfigurableBeanFactory; | |||||
| import org.springframework.context.annotation.Scope; | |||||
| import org.springframework.stereotype.Component; | |||||
| import com.github.binarywang.demo.spring.config.WxConfig; | |||||
| import com.github.binarywang.demo.spring.config.WxGzh1Config; | |||||
| import com.github.binarywang.demo.spring.handler.LocationHandler; | |||||
| @Component | |||||
| @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) | |||||
| public class Gzh1LocationHandler extends LocationHandler { | |||||
| @Autowired | |||||
| private WxGzh1Config wxConfig; | |||||
| @Override | |||||
| protected WxConfig getWxConfig() { | |||||
| return this.wxConfig; | |||||
| } | |||||
| } | |||||
| @@ -1,23 +0,0 @@ | |||||
| package com.github.binarywang.demo.spring.handler.gzh1; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.beans.factory.config.ConfigurableBeanFactory; | |||||
| import org.springframework.context.annotation.Scope; | |||||
| import org.springframework.stereotype.Component; | |||||
| import com.github.binarywang.demo.spring.config.WxConfig; | |||||
| import com.github.binarywang.demo.spring.config.WxGzh1Config; | |||||
| import com.github.binarywang.demo.spring.handler.MenuHandler; | |||||
| @Component | |||||
| @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) | |||||
| public class Gzh1MenuHandler extends MenuHandler { | |||||
| @Autowired | |||||
| private WxGzh1Config wxConfig; | |||||
| @Override | |||||
| protected WxConfig getWxConfig() { | |||||
| return this.wxConfig; | |||||
| } | |||||
| } | |||||
| @@ -1,23 +0,0 @@ | |||||
| package com.github.binarywang.demo.spring.handler.gzh1; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.beans.factory.config.ConfigurableBeanFactory; | |||||
| import org.springframework.context.annotation.Scope; | |||||
| import org.springframework.stereotype.Component; | |||||
| import com.github.binarywang.demo.spring.config.WxConfig; | |||||
| import com.github.binarywang.demo.spring.config.WxGzh1Config; | |||||
| import com.github.binarywang.demo.spring.handler.MsgHandler; | |||||
| @Component | |||||
| @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) | |||||
| public class Gzh1MsgHandler extends MsgHandler { | |||||
| @Autowired | |||||
| private WxGzh1Config wxConfig; | |||||
| @Override | |||||
| protected WxConfig getWxConfig() { | |||||
| return this.wxConfig; | |||||
| } | |||||
| } | |||||
| @@ -1,32 +0,0 @@ | |||||
| package com.github.binarywang.demo.spring.handler.gzh1; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.beans.factory.config.ConfigurableBeanFactory; | |||||
| import org.springframework.context.annotation.Scope; | |||||
| import org.springframework.stereotype.Component; | |||||
| import com.github.binarywang.demo.spring.config.WxConfig; | |||||
| import com.github.binarywang.demo.spring.config.WxGzh1Config; | |||||
| import com.github.binarywang.demo.spring.handler.SubscribeHandler; | |||||
| import me.chanjar.weixin.mp.bean.WxMpXmlMessage; | |||||
| import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; | |||||
| @Component | |||||
| @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) | |||||
| public class Gzh1SubscribeHandler extends SubscribeHandler { | |||||
| @Autowired | |||||
| private WxGzh1Config wxConfig; | |||||
| @Override | |||||
| protected WxConfig getWxConfig() { | |||||
| return this.wxConfig; | |||||
| } | |||||
| @Override | |||||
| protected WxMpXmlOutMessage handleSpecial(WxMpXmlMessage wxMessage) | |||||
| throws Exception { | |||||
| return null; | |||||
| } | |||||
| } | |||||
| @@ -1,23 +0,0 @@ | |||||
| package com.github.binarywang.demo.spring.handler.gzh1; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import org.springframework.beans.factory.config.ConfigurableBeanFactory; | |||||
| import org.springframework.context.annotation.Scope; | |||||
| import org.springframework.stereotype.Component; | |||||
| import com.github.binarywang.demo.spring.config.WxConfig; | |||||
| import com.github.binarywang.demo.spring.config.WxGzh1Config; | |||||
| import com.github.binarywang.demo.spring.handler.UnsubscribeHandler; | |||||
| @Component | |||||
| @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) | |||||
| public class Gzh1UnSubscribeHandler extends UnsubscribeHandler { | |||||
| @Autowired | |||||
| private WxGzh1Config wxConfig; | |||||
| @Override | |||||
| protected WxConfig getWxConfig() { | |||||
| return this.wxConfig; | |||||
| } | |||||
| } | |||||
| @@ -1,138 +0,0 @@ | |||||
| package com.github.binarywang.demo.spring.service; | |||||
| import com.github.binarywang.demo.spring.config.WxConfig; | |||||
| import com.github.binarywang.demo.spring.handler.*; | |||||
| 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.impl.WxMpServiceImpl; | |||||
| import me.chanjar.weixin.mp.bean.WxMpXmlMessage; | |||||
| import me.chanjar.weixin.mp.bean.WxMpXmlOutMessage; | |||||
| import me.chanjar.weixin.mp.bean.kefu.result.WxMpKfOnlineList; | |||||
| import org.slf4j.Logger; | |||||
| import org.slf4j.LoggerFactory; | |||||
| import org.springframework.beans.factory.annotation.Autowired; | |||||
| import javax.annotation.PostConstruct; | |||||
| /** | |||||
| * | |||||
| * @author Binary Wang | |||||
| * | |||||
| */ | |||||
| public abstract class BaseWxService extends WxMpServiceImpl { | |||||
| private final Logger logger = LoggerFactory.getLogger(this.getClass()); | |||||
| @Autowired | |||||
| protected LogHandler logHandler; | |||||
| @Autowired | |||||
| protected NullHandler nullHandler; | |||||
| @Autowired | |||||
| protected KfSessionHandler kfSessionHandler; | |||||
| 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 | |||||
| config.setAesKey(this.getServerConfig().getAesKey());// 设置消息加解密密钥 | |||||
| super.setWxMpConfigStorage(config); | |||||
| this.refreshRouter(); | |||||
| } | |||||
| private void refreshRouter() { | |||||
| final WxMpMessageRouter newRouter = new WxMpMessageRouter(this); | |||||
| // 记录所有事件的日志 | |||||
| newRouter.rule().handler(this.logHandler).next(); | |||||
| // 接收客服会话管理事件 | |||||
| newRouter.rule().async(false).msgType(WxConsts.XML_MSG_EVENT) | |||||
| .event(WxConsts.EVT_KF_CREATE_SESSION).handler(this.kfSessionHandler).end(); | |||||
| newRouter.rule().async(false).msgType(WxConsts.XML_MSG_EVENT) | |||||
| .event(WxConsts.EVT_KF_CLOSE_SESSION).handler(this.kfSessionHandler).end(); | |||||
| newRouter.rule().async(false).msgType(WxConsts.XML_MSG_EVENT) | |||||
| .event(WxConsts.EVT_KF_SWITCH_SESSION).handler(this.kfSessionHandler).end(); | |||||
| // 自定义菜单事件 | |||||
| newRouter.rule().async(false).msgType(WxConsts.XML_MSG_EVENT) | |||||
| .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 { | |||||
| return this.router.route(message); | |||||
| } catch (Exception e) { | |||||
| this.logger.error(e.getMessage(), e); | |||||
| } | |||||
| return null; | |||||
| } | |||||
| public boolean hasKefuOnline() { | |||||
| try { | |||||
| WxMpKfOnlineList kfOnlineList = this.getKefuService().kfOnlineList(); | |||||
| return kfOnlineList != null && kfOnlineList.getKfOnlineList().size() > 0; | |||||
| } catch (Exception e) { | |||||
| this.logger.error("获取客服在线状态异常: " + e.getMessage(), e); | |||||
| } | |||||
| return false; | |||||
| } | |||||
| } | |||||
| @@ -1,79 +0,0 @@ | |||||
| 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; | |||||
| import com.github.binarywang.demo.spring.handler.gzh1.Gzh1LocationHandler; | |||||
| import com.github.binarywang.demo.spring.handler.gzh1.Gzh1MenuHandler; | |||||
| import com.github.binarywang.demo.spring.handler.gzh1.Gzh1MsgHandler; | |||||
| import com.github.binarywang.demo.spring.handler.gzh1.Gzh1SubscribeHandler; | |||||
| import com.github.binarywang.demo.spring.handler.gzh1.Gzh1UnSubscribeHandler; | |||||
| /** | |||||
| * | |||||
| * @author Binary Wang | |||||
| * | |||||
| */ | |||||
| @Service | |||||
| public class Gzh1WxService extends BaseWxService { | |||||
| @Autowired | |||||
| private WxGzh1Config wxConfig; | |||||
| @Autowired | |||||
| private Gzh1LocationHandler locationHandler; | |||||
| @Autowired | |||||
| private Gzh1MenuHandler menuHandler; | |||||
| @Autowired | |||||
| private Gzh1MsgHandler msgHandler; | |||||
| @Autowired | |||||
| private Gzh1UnSubscribeHandler unSubscribeHandler; | |||||
| @Autowired | |||||
| private Gzh1SubscribeHandler subscribeHandler; | |||||
| @Override | |||||
| protected WxConfig getServerConfig() { | |||||
| return this.wxConfig; | |||||
| } | |||||
| @Override | |||||
| protected MenuHandler getMenuHandler() { | |||||
| return this.menuHandler; | |||||
| } | |||||
| @Override | |||||
| protected SubscribeHandler getSubscribeHandler() { | |||||
| return this.subscribeHandler; | |||||
| } | |||||
| @Override | |||||
| protected UnsubscribeHandler getUnsubscribeHandler() { | |||||
| return this.unSubscribeHandler; | |||||
| } | |||||
| @Override | |||||
| protected AbstractHandler getLocationHandler() { | |||||
| return this.locationHandler; | |||||
| } | |||||
| @Override | |||||
| protected MsgHandler getMsgHandler() { | |||||
| return this.msgHandler; | |||||
| } | |||||
| @Override | |||||
| protected AbstractHandler getScanHandler() { | |||||
| return null; | |||||
| } | |||||
| } | |||||
| @@ -1,66 +0,0 @@ | |||||
| 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; | |||||
| } | |||||
| } | |||||
| @@ -1,2 +0,0 @@ | |||||
| /wx-gzh1.properties | |||||
| /wx-gzh2.properties | |||||
| @@ -1,17 +0,0 @@ | |||||
| <?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> | |||||
| @@ -1,8 +0,0 @@ | |||||
| 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 | |||||
| @@ -1,29 +0,0 @@ | |||||
| <?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> | |||||
| @@ -1,43 +0,0 @@ | |||||
| <?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> | |||||
| @@ -1,4 +0,0 @@ | |||||
| wx_appid= | |||||
| wx_appsecret= | |||||
| wx_token= | |||||
| wx_aeskey= | |||||
| @@ -1,4 +0,0 @@ | |||||
| wx_appid= | |||||
| wx_appsecret= | |||||
| wx_token= | |||||
| wx_aeskey= | |||||
| @@ -1,47 +0,0 @@ | |||||
| <?xml version="1.0" encoding="UTF-8"?> | |||||
| <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | |||||
| xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" | |||||
| xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" | |||||
| version="3.0"> | |||||
| <display-name>api</display-name> | |||||
| <context-param> | |||||
| <param-name>contextConfigLocation</param-name> | |||||
| <param-value>classpath:applicationContext.xml</param-value> | |||||
| </context-param> | |||||
| <filter> | |||||
| <filter-name>encodingFilter</filter-name> | |||||
| <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> | |||||
| <init-param> | |||||
| <param-name>encoding</param-name> | |||||
| <param-value>UTF-8</param-value> | |||||
| </init-param> | |||||
| </filter> | |||||
| <filter-mapping> | |||||
| <filter-name>encodingFilter</filter-name> | |||||
| <url-pattern>/*</url-pattern> | |||||
| </filter-mapping> | |||||
| <listener> | |||||
| <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> | |||||
| </listener> | |||||
| <listener> | |||||
| <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> | |||||
| </listener> | |||||
| <servlet> | |||||
| <description>spring mvc servlet</description> | |||||
| <servlet-name>springMvc</servlet-name> | |||||
| <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> | |||||
| <init-param> | |||||
| <param-name>contextConfigLocation</param-name> | |||||
| <param-value>classpath:spring-servlet-common.xml</param-value> | |||||
| </init-param> | |||||
| <load-on-startup>1</load-on-startup> | |||||
| </servlet> | |||||
| <servlet-mapping> | |||||
| <servlet-name>springMvc</servlet-name> | |||||
| <url-pattern>/</url-pattern> | |||||
| </servlet-mapping> | |||||
| <session-config> | |||||
| <session-timeout>30</session-timeout> | |||||
| </session-config> | |||||
| </web-app> | |||||