赞
踩
准备工作 申请一个微信测试号 下载一个内网穿透软件用于获取域名 我用的多 wenat软件
微信授权接口配置位置
测试号管理的接口配置中 此处使用内网穿透转换的域名
/** * @desc: 门户入口 * @author: cao_wencao * @date: 2019-09-02 17:06 */ @Slf4j @AllArgsConstructor @RestController @RequestMapping("/**/****/{appid}") public class WxPortalController { private final WxMpService wxService; private final WxMpMessageRouter messageRouter; @Autowired private WxLoginService wxLoginService; @GetMapping(produces = "text/plain;charset=utf-8") public String authGet(@PathVariable String appid, @RequestParam(name = "signature", required = false) String signature, @RequestParam(name = "timestamp", required = false) String timestamp, @RequestParam(name = "nonce", required = false) String nonce, @RequestParam(name = "echostr", required = false) String echostr) { log.info("\n接收到来自微信服务器的认证消息:[{}, {}, {}, {}]", signature, timestamp, nonce, echostr); if (StringUtils.isAnyBlank(signature, timestamp, nonce, echostr)) { throw new IllegalArgumentException("请求参数非法,请核实!"); } if (!this.wxService.switchover(appid)) { throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", appid)); } if (wxService.checkSignature(timestamp, nonce, signature)) { return echostr; } return "非法请求"; } @PostMapping(produces = "application/xml; charset=UTF-8") public String post(@PathVariable String appid, @RequestBody String requestBody, @RequestParam("signature") String signature, @RequestParam("timestamp") String timestamp, @RequestParam("nonce") String nonce, @RequestParam("openid") String openid, @RequestParam(name = "encrypt_type", required = false) String encType, @RequestParam(name = "msg_signature", required = false) String msgSignature) { log.info("\n接收微信请求:[openid=[{}], [signature=[{}], encType=[{}], msgSignature=[{}]," + " timestamp=[{}], nonce=[{}], requestBody=[\n{}\n] ", openid, signature, encType, msgSignature, timestamp, nonce, requestBody); if (!this.wxService.switchover(appid)) { throw new IllegalArgumentException(String.format("未找到对应appid=[%s]的配置,请核实!", appid)); } if (!wxService.checkSignature(timestamp, nonce, signature)) { throw new IllegalArgumentException("非法请求,可能属于伪造的请求!"); } String out = null; if (encType == null) { // 明文传输的消息 WxMpXmlMessage inMessage = WxMpXmlMessage.fromXml(requestBody); //路由去跳转微信事件 WxMpXmlOutMessage outMessage = this.route(inMessage); //没有微信事件 if (outMessage == null) { return ""; } out = outMessage.toXml(); } else if ("aes".equalsIgnoreCase(encType)) { // aes加密的消息 WxMpXmlMessage inMessage = WxMpXmlMessage.fromEncryptedXml(requestBody, wxService.getWxMpConfigStorage(), timestamp, nonce, msgSignature); log.debug("\n消息解密后内容为:\n{} ", inMessage.toString()); WxMpXmlOutMessage outMessage = this.route(inMessage); if (outMessage == null) { return ""; } out = outMessage.toEncryptedXml(wxService.getWxMpConfigStorage()); } log.debug("\n组装回复信息:{}", out); return out; } private WxMpXmlOutMessage route(WxMpXmlMessage message) { try { return this.messageRouter.route(message); } catch (Exception e) { log.error("路由消息时出现异常!", e); } return null; } } //路由类 /** * @desc: 路由配置 * @author: cao_wencao * @date: 2019-09-02 17:06 */ @AllArgsConstructor @Configuration @EnableConfigurationProperties(WxMpProperties.class) public class WxMpConfiguration { private final LogHandler logHandler; private final NullHandler nullHandler; private final KfSessionHandler kfSessionHandler; private final StoreCheckNotifyHandler storeCheckNotifyHandler; private final LocationHandler locationHandler; private final MenuHandler menuHandler; private final MsgHandler msgHandler; private final UnsubscribeHandler unsubscribeHandler; private final SubscribeHandler subscribeHandler; private final ScanHandler scanHandler; private final WxMpProperties properties; @Bean public WxMpService wxMpService() { final List<WxMpProperties.MpConfig> configs = this.properties.getConfigs(); if (configs == null) { throw new RuntimeException("大哥,拜托先看下项目首页的说明(readme文件),添加下相关配置,注意别配错了!"); } WxMpService service = new WxMpServiceImpl(); service.setMultiConfigStorages(configs .stream().map(a -> { WxMpDefaultConfigImpl configStorage = new WxMpDefaultConfigImpl(); configStorage.setAppId(a.getAppId()); configStorage.setSecret(a.getSecret()); configStorage.setToken(a.getToken()); configStorage.setAesKey(a.getAesKey()); return configStorage; }).collect(Collectors.toMap(WxMpDefaultConfigImpl::getAppId, a -> a, (o, n) -> o))); System.out.println(configs.get(0).getAppId()+"==============================="); return service; } @Bean public WxMpMessageRouter messageRouter(WxMpService wxMpService) { final WxMpMessageRouter newRouter = new WxMpMessageRouter(wxMpService); // 记录所有事件的日志 (异步执行) newRouter.rule().handler(this.logHandler).next(); // 接收客服会话管理事件 newRouter.rule().async(false).msgType(EVENT).event(KF_CREATE_SESSION) .handler(this.kfSessionHandler).end(); newRouter.rule().async(false).msgType(EVENT).event(KF_CLOSE_SESSION) .handler(this.kfSessionHandler).end(); newRouter.rule().async(false).msgType(EVENT).event(KF_SWITCH_SESSION) .handler(this.kfSessionHandler).end(); // 门店审核事件 newRouter.rule().async(false).msgType(EVENT).event(POI_CHECK_NOTIFY).handler(this.storeCheckNotifyHandler).end(); // 自定义菜单事件 newRouter.rule().async(false).msgType(EVENT).event(CLICK).handler(this.menuHandler).end(); // 点击菜单连接事件 newRouter.rule().async(false).msgType(EVENT).event(VIEW).handler(this.nullHandler).end(); // 关注事件 newRouter.rule().async(false).msgType(EVENT).event(SUBSCRIBE).handler(this.subscribeHandler).end(); // 取消关注事件 newRouter.rule().async(false).msgType(EVENT).event(UNSUBSCRIBE).handler(this.unsubscribeHandler).end(); // 上报地理位置事件 newRouter.rule().async(false).msgType(EVENT).event(EventType.LOCATION).handler(this.locationHandler).end(); // 接收地理位置消息 newRouter.rule().async(false).msgType(XmlMsgType.LOCATION).handler(this.locationHandler).end(); // 扫码事件 newRouter.rule().async(false).msgType(EVENT).event(EventType.SCAN).handler(this.scanHandler).end(); // 默认 newRouter.rule().async(false).handler(this.msgHandler).end(); return newRouter; } } /** * @desc: yml配置映射成实体类 会将yml文件对应参数映射入当前类 * @author: cao_wencao * @date: 2019-09-02 17:08 */ @Data @ConfigurationProperties(prefix = "wx.mp") public class WxMpProperties { private List<MpConfig> configs; @Data public static class MpConfig { /** * 设置微信公众号的appid */ private String appId; /** * 设置微信公众号的app secret */ private String secret; /** * 设置微信公众号的token */ private String token; /** * 设置微信公众号的EncodingAESKey */ private String aesKey; } @Override public String toString() { return JsonUtils.toJson(this); } //下面yml文件 logging: level: org.springframework.web: INFO com.github.binarywang.demo.wx.mp: DEBUG me.chanjar.weixin: DEBUG wx: mp: configs: - appId: #(一个公众号的appid) secret: #(公众号的appsecret) token: # (接口配置里的Token值) aesKey: 111 # (接口配置里的EncodingAESKey值) - appId: 2222 # (另一个公众号的appid,以下同上) secret: 1111 token: 111 aesKey: 111
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。