个人只能申请订阅号
1、首先需要申请一个微信公众号。具体如何申请,请登录微信公众号平台申请即可
2、外网映射工具——ngrok
项目使用spring boot 开发 结合自己项目 引入如下依赖及两个java文件
<!-- 微信开发工具包 --> <!-- https://github.com/binarywang/weixin-java-mp-demo-springboot --> <dependency> <groupId>com.github.binarywang</groupId> <artifactId>weixin-java-mp</artifactId> <version>4.2.0</version> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.0.7</version> </dependency>
WeChatProperties.java
import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; @Data @Component @ConfigurationProperties(prefix = "wechat.config") public class WeChatProperties { /** * 是否使用redis存储access token */ private boolean useRedis; /** * 设置微信公众号的appid */ private String appId; /** * 设置微信公众号的app secret */ private String appSecret; /** * 设置微信公众号的token */ private String token; /** * 设置微信公众号的EncodingAESKey */ private String aesKey; private String mpVerify; private String jobTemplateId1; }
WxController.java
package com.frkj.modules.wechat; import cn.hutool.json.JSONObject; import com.frkj.common.api.vo.Result; import com.frkj.common.exception.WechatException; import com.frkj.common.util.MessageUtils; import com.frkj.config.WeChatProperties; import me.chanjar.weixin.common.api.WxConsts; import me.chanjar.weixin.common.bean.WxJsapiSignature; import me.chanjar.weixin.common.bean.WxOAuth2UserInfo; import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken; import me.chanjar.weixin.common.error.WxErrorException; import me.chanjar.weixin.mp.api.WxMpService; import me.chanjar.weixin.mp.bean.menu.WxMpMenu; import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage; import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage; import me.chanjar.weixin.mp.bean.message.WxMpXmlOutNewsMessage; import me.chanjar.weixin.mp.bean.message.WxMpXmlOutTextMessage; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.util.ArrayList; import java.util.List; @RestController @RequestMapping("/wx") public class WxController { private static final Logger log = LoggerFactory.getLogger(WxController.class); @Autowired WxMpService wxService; @Autowired WxMpXmlMessage wxMpXmlMessage; @Autowired WeChatProperties weChatProperties; @RequestMapping(value = "authWx", method = RequestMethod.GET) public String authGet(HttpServletRequest request, HttpServletResponse response) { String signature = request.getParameter("signature"); String timestamp = request.getParameter("timestamp"); String nonce = request.getParameter("nonce"); String echostr = request.getParameter("echostr"); log.info("\n接收到来自微信服务器的认证消息:[signature:{}, timestamp:{}, nonce:{}, echostr:{}]", signature, timestamp, nonce, echostr); if (StringUtils.isAnyBlank(signature, timestamp, nonce, echostr)) { throw new IllegalArgumentException("请求参数非法,请核实!"); } if (wxService.checkSignature(timestamp, nonce, signature)) { log.info("返回随机字符串表示验证成功,随机字符串:{}", echostr); return echostr; } return "非法请求,验证微信服务器失败"; } @RequestMapping(value = "authWx", method = RequestMethod.POST) public String getMessageFromUser(HttpServletRequest request, HttpServletResponse response) throws IOException { //获取用户发送的消息fromXml方法底层已转化为对象 WxMpXmlMessage message = wxMpXmlMessage.fromXml(request.getInputStream()); if (com.frkj.common.util.StringUtils.isNull(message)) { throw new RuntimeException("解析用户发送的消息失败"); } if (!message.getMsgType().equals(WxConsts.XmlMsgType.EVENT)) {//不是事件 //TODO 可以选择将消息保存到本地 } log.info("用户发送的消息:{}", message); //回复用户消息 return replyMessage(message); } public String replyMessage(WxMpXmlMessage message) { String out = null; switch (message.getMsgType()) { case WxConsts.XmlMsgType.TEXT: out = dealTextMessage(message); break; case WxConsts.XmlMsgType.IMAGE: break; case WxConsts.XmlMsgType.VIDEO: break; case WxConsts.XmlMsgType.VOICE: break; case WxConsts.XmlMsgType.NEWS: break; case WxConsts.XmlMsgType.MUSIC: break; case WxConsts.XmlMsgType.LOCATION: break; case WxConsts.XmlMsgType.LINK: break; case WxConsts.XmlMsgType.EVENT: break; } if (StringUtils.isNotEmpty(out)) { return out; } return "欢迎关注"; } private String dealTextMessage(WxMpXmlMessage message) { //TODO 组装回复消息 String out = null; MessageUtils messageUtils = new MessageUtils(); long time = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8")); //当用户输入关键词如“1”,“2”等,可以组装特定的响应消息返回给用户 try { if (StringUtils.startsWithAny(message.getContent(), "你好", "1")) { WxMpXmlOutTextMessage xmlOutTextMessage = messageUtils.replyTextMessage(message.getFromUser(), message.getToUser(), "欢迎关注"); //组装回复用户消息 out = xmlOutTextMessage.toXml();//返回也是xml return out; }else if (StringUtils.startsWithAny(message.getContent(), "图文")) { List<WxMpXmlOutNewsMessage.Item> articles = new ArrayList<>(); WxMpXmlOutNewsMessage.Item item = new WxMpXmlOutNewsMessage.Item(); item.setDescription("微信公众号发送图文消息"); item.setPicUrl("http://mmbiz.qpic.cn/mmbiz_jpg/DhpEVfrp0gtYNA8lA3py0YBhHxByIJIRUE1J2Hhe8vd6V1lh82PvP4hBFzY6R25AlyO96HJpSRYyF4LYZeqWew/0"); item.setTitle("正在开发,敬请期待"); item.setUrl("http://www.baidu.com"); articles.add(item); WxMpXmlOutMessage newsMessage = messageUtils.replyNewsMessage(message.getFromUser(), message.getToUser(), item, articles); //组装回复用户消息 out = newsMessage.toXml();//返回也是xml return out; } //不是关键字 WxMpXmlOutTextMessage xmlOutTextMessage = messageUtils.replyTextMessage(message.getFromUser(), message.getToUser(), "http://www.baidu.com"); //组装回复用户消息 out = xmlOutTextMessage.toXml();//返回也是xml } catch (Exception e) { e.printStackTrace(); } return out; } public String dealNewMessage(WxMpXmlMessage message) { String out = null; MessageUtils messageUtils = new MessageUtils(); try { } catch (Exception e) { e.printStackTrace(); } return out; } /** * 创建自定义按钮 * * @param json * @return * @throws WxErrorException */ @PostMapping("/createByJson") public String menuCreate(@RequestBody String json) throws WxErrorException { try { String s = wxService.switchoverTo(weChatProperties.getAppId()).getMenuService().menuCreate(json); if (StringUtils.isNotEmpty(s)) { JSONObject jsonObject = new JSONObject(s); if (jsonObject.get("errcode").equals(String.valueOf(0))) { return "创建菜单成功"; } return "创建菜单失败"; } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e.getMessage()); } return null; } /** * 自定义菜单删除接口 */ @GetMapping("/delete") public void menuDelete() throws WxErrorException { try { this.wxService.switchoverTo(weChatProperties.getAppId()).getMenuService().menuDelete(); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e.getMessage()); } } /** * 删除个性化菜单接口 * * @param menuId 个性化菜单的menuid */ @GetMapping("/delete/{menuId}") public void menuDelete(@PathVariable String menuId) throws WxErrorException { this.wxService.switchoverTo(weChatProperties.getAppId()).getMenuService().menuDelete(menuId); } /** * 自定义菜单查询接口 */ @GetMapping("/get") public WxMpMenu menuGet() throws WxErrorException { try { WxMpMenu wxMpMenu = this.wxService.switchoverTo(weChatProperties.getAppId()).getMenuService().menuGet(); if (com.frkj.common.util.StringUtils.isNotNull(wxMpMenu)) { log.info("获取菜单列表成功{}", wxMpMenu); return wxMpMenu; } throw new RuntimeException("没有获取到菜单列表"); } catch (Exception e) { e.printStackTrace(); } return null; } }
测试平台申请地址:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login 获取appId、appSecret
在配置文件 application-dev.yml 中填写获取appId、appSecret token自定义
wechat: config: useRedis: true #自己测试用的appId及appSecret appId: xxxxxxxx appSecret: xxxxxxxxxxx aesKey: IfDd5twyHOmEzmElMgyNE5mmnh8BRuQ23jXRdajDa7B token: 123456 mpVerify: 6qn27EliDfT1mSYa jobTemplateId1: yvv6RNXhtvYRow-w14NhXwc5ZmDDBj23nBETi8zmGNw
打开cmd 窗口运行ngrok.exe http 9999 因为自己项目的端口号是9999
启动成功如下所示
启动自己项目 在测试平台接口配配置上 把ngrok获取的http://20de-182-242-18-59.ngrok.io + wechat(项目根路径)+WxController.java中的authWx认证路径(get请求) 填入url
完成url: http://20de-182-242-18-59.ngrok.io/wechat/wx/authWx
填入自定义token:123456
点击提交按钮 若提示配置成功 则成功介入微信公众测试平台