本教程按我自己方式写的,不一定对,但是是可以实现的,为了方便逻辑都写在了Controller层,我数据是静态的,可以自行用数据库动态生成。

微信公众平台接口测试帐号申请:
http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login

内网穿透


微信官方文档:https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_standard_messages.html

当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL上。
请注意:
1,关于重试的消息排重,推荐使用msgid排重。
2,微信服务器在五秒内收不到响应会断掉连接,并且重新发起请求,总共重试三次。假如服务器无法保证在五秒内处理并回复,可以直接回复空串,微信服务器不会对此作任何处理,并且不会发起重试。详情请见“发送消息-被动回复消息”。
3,如果开发者需要对用户消息在5秒内立即做出回应,即使用“发送消息-被动回复消息”接口向用户被动回复消息时,可以在公众平台官网的开发者中心处设置消息加密。开启加密后,用户发来的消息和开发者回复的消息都会被加密(但开发者通过客服接口等API调用形式向用户发送消息,则不受影响)。关于消息加解密的详细说明,请见“发送消息-被动回复消息加解密说明”。 各消息类型的推送XML数据包结构如下:

文本消息
<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>1348831860</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[this is a test]]></Content><MsgId>1234567890123456</MsgId>
</xml>

Controller-------代码注释详细,不做多解释

@RestController
@RequestMapping("/a")
public class TemplateController {private static final Logger logger = Logger.getLogger(TemplateController.class);private static final org.slf4j.Logger logger2 = LoggerFactory.getLogger(TemplateController.class);//url校验@RequestMapping(value = "/c", method = RequestMethod.GET)public String weiXinGet(HttpServletRequest req, HttpServletResponse resp) throws Exception {logger.info("微信请求接入>>>>>>>>>>>>>>>>>>>>>>>>>>>");//获取微信加密签名String signature = req.getParameter("signature");logger2.info("微信签名是: {}", signature);//获取时间戳String timestamp = req.getParameter("timestamp");//获取随机数String nonce = req.getParameter("nonce");//获取随机字符串String echostr = req.getParameter("echostr");//判断加密后的字符串和签名是否一样.如果一样表示接入成功if (InspectionUtil.checkSignature(signature, timestamp, nonce)) {logger.info("已成功发送———————" + echostr);return echostr;}return null;}//消息处理@RequestMapping(value = "/c", method = RequestMethod.POST)public String weiXinPost(@RequestBody InWeiXinMessage weiXinMessage) throws Exception {OutWeiXinMessage outWeiXinMessage = new OutWeiXinMessage();//发送方outWeiXinMessage.setFromUserName(weiXinMessage.getToUserName());//接受方outWeiXinMessage.setToUserName(weiXinMessage.getFromUserName());//str = weiXinMessage.getFromUserName();//消息创建时间outWeiXinMessage.setCreateTime(new Date().getTime());//消息类型outWeiXinMessage.setMsgType("text");System.out.println(weiXinMessage.getContent());//消息内容String content = weiXinMessage.getContent();switch (content) {case "一级菜单<1>":outWeiXinMessage.setContent("<a href=\"weixin://bizmsgmenu?msgmenucontent=二级菜单<1>&msgmenuid=102\">二级菜单<1></a>\n" +"<a href=\"weixin://bizmsgmenu?msgmenucontent=二级菜单<2>&msgmenuid=103\">二级菜单<2></a>\n" +"<a href=\"weixin://bizmsgmenu?msgmenucontent=二级菜单<3>&msgmenuid=104\">二级菜单<3></a>");break;case "二级菜单<1>":outWeiXinMessage.setContent("二级菜单<1>");break;case "一级菜单<2>":outWeiXinMessage.setContent("我是一级菜单<2>");break;case "一级菜单<3>":outWeiXinMessage.setContent("我是一级菜单<3>");break;default:outWeiXinMessage.setContent("<a href=\"weixin://bizmsgmenu?msgmenucontent=一级菜单<1>&msgmenuid=102\">一级菜单<1></a>\n" +"<a href=\"weixin://bizmsgmenu?msgmenucontent=一级菜单<2>&msgmenuid=103\">一级菜单<2></a>\n" +"<a href=\"weixin://bizmsgmenu?msgmenucontent=一级菜单<3>&msgmenuid=104\">一级菜单<3></a>");}XStream xStream = new XStream();//设置别名xStream.alias("xml", OutWeiXinMessage.class);String xml = xStream.toXML(outWeiXinMessage);return xml;}
}

XStream的pom.xml,其他常用的不做多阐述

        <dependency><groupId>com.thoughtworks.xstream</groupId><artifactId>xstream</artifactId><version>1.4.9</version></dependency>

InspectionUtil

public class InspectionUtil {public static boolean checkSignature(String signature, String timestamp, String nonce) {String[] strArrays = {Constast.Token, timestamp, nonce};Arrays.sort(strArrays);//拼接字符串String str = new StringBuffer().append(strArrays[0]).append((strArrays[1])).append((strArrays[2])).toString();//加密的字符串跟微信加密签名是否一样return InspectionUtil.sha1(str).equals(signature);}//将字符串进行sha1加密public static String sha1(String str) {try {MessageDigest digest = MessageDigest.getInstance("SHA-1");digest.update(str.getBytes());byte messageDigest[] = digest.digest();// Create Hex StringStringBuffer hexString = new StringBuffer();// 字节数组转换为十六进制数for (int i = 0; i < messageDigest.length; i++) {String shaHex = Integer.toHexString(messageDigest[i] & 0xFF);if (shaHex.length() < 2) {hexString.append(0);}hexString.append(shaHex);}return hexString.toString();} catch (NoSuchAlgorithmException e) {e.printStackTrace();}return "";}
}

InWeiXinMessage-----这里接收xml格式并转换,用的注解实现的

@Data
@XmlRootElement(name = "xml")
@XmlAccessorType(XmlAccessType.FIELD)
public class InWeiXinMessage {@XmlElement(name = "ToUserName")private String toUserName;        //开发者微信号private String FromUserName;    //发送方帐号(一个OpenID)private Long CreateTime;     //消息创建时间 (整型)private String  MsgType;     //消息类型,text/image/voiceprivate Long MsgId;               //消息id,64位整型private String Content;          //文本消息内容private String PicUrl;          //图片链接(由系统生成)private String MediaId;          //语音消息媒体id,可以调用获取临时素材接口拉取数据。
}

OutWeiXinMessage-----这里本来想用注解实现,无法实现改用XStream

@Data
public class OutWeiXinMessage {private String ToUserName;       //用户微信号private String FromUserName;    //用户帐号(一个OpenID)private Long CreateTime;       //消息创建时间 (整型)private String  MsgType;     //消息类型,text/image/voiceprivate String Content;           //文本消息内容
}

启动项目,扫码关注,查看结果


微信公众号自定义回复文字菜单-----详细教程相关推荐

  1. 微信公众号自定义回复(关键词回复:文本消息、图文消息)

    要回复客户发到微信公共号的消息,首先要获取用户发来的消息, 接收地址就是微信公众号基本配置里写的服务器地址所在的文件地址: $postStr = $GLOBALS["HTTP_RAW_POS ...

  2. 微信公众号文章怎么添加附件|详细教程讲解,太实用了!

    公众号运营,涉及文字编写.图片制作美化,标题撰写等等,其中比较重要的一环是,在公众号文章中插入附件(附件:word文件.excel表格.pdf文件.zip压缩文件.txt文件等).公众号在每一次的发布 ...

  3. 微信公众号自定义3*5菜单

    微信自定义菜单文档地址: https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141013 通读文档,发现需要按照其规定的字段 ...

  4. 微信公众号自定义菜单如何设置?

    随着微信公众号注册条件的放宽,微信公众号的使用范围更加广泛,普及程度也有所提高.现在大大小小的商家几乎都有自己的微信公众号. 无论什么产品,都离不开一个固有的规律,那就是是用的人多了,问题也就显现出来 ...

  5. springboot微信公众号自定义菜单创建及响应

    微信公众号自定义菜单创建及响应 前言 本篇博客是为了速度开发微信公众号而进行讲解,对于深入的原理性讲解推荐去观看微信公众平台的官方文档. 微信公众号分为订阅号,服务号,小程序,本篇主要是介绍的订阅号开 ...

  6. 微信公众号关注回复多条信息(文字、图片、视频、跳转小程序)

    微信公众号关注回复多条信息(文字.图片.视频.跳转小程序) 对于没做过关注回复多条信息的开发来说,没有实现的思路,花费了一天的时间研究写代码.测试,现做个记录 思路 公众号后台配置关注自动回复只能配置 ...

  7. 自定义菜单url不能带_微服务架构【SpringBoot+SpringCloud+VUE】五 || 实战项目微信公众号自定义开发...

    本章主要讲解微信公众号自定义菜单.微信网页开发.模板消息推送等功能的实现: 发福利了,下方关注公众号,就能免费获取项目源码 1.自定义菜单 开发前需要了解以下几点: 1.微信公众号的自定义菜单最多包括 ...

  8. 微信公众号自定义菜单添加emoji表情图标

    微信公众号自定义菜单添加emoji表情图标 第一步:打开微信公众平台接口调试工具,点击前往接口调试工具: 第二步:把这段代码   {"button":[{"sub_but ...

  9. 微信公众号自定义菜单设置教程

    微信公众号菜单等功能如何开通 自定义菜单最大的优点是减少了用户的认知门槛,可以将公众账号里的重点信息入口直观的暴露给用户.当用户进入到公众账号时,可以一目了然的了解相关的服务,只需要点击,不需要再通过 ...

最新文章

  1. 剑指offer:面试题07. 重建二叉树
  2. window下从硬盘安装ubuntu双系统
  3. matlab中fliter函数,用C语言实现MATLAB中Filter()函数
  4. ML之NB:利用朴素贝叶斯NB算法(TfidfVectorizer+不去除停用词)对20类新闻文本数据集进行分类预测、评估
  5. python flask 基础入门
  6. 从数学到计算机 从莱布尼兹到冯诺依曼 从数理逻辑到算法分析
  7. leetcode题库6-- Z 字形变换
  8. Golang的4种传递引用类型
  9. 查找单词个数案列实现(字符串流)
  10. 清华数据结构c语言版严蔚敏pdf,清华数据结构习题集答案(C语言版严蔚敏).pdf
  11. 【FlexSim2019】自学笔记:2019版本中传送带属性设置 | Use transport | 如何建立S连接 | 操作员 叉车 传送带
  12. 常微分方程在计算机的应用,简述计算机数学软件在常微分方程中的应用
  13. 曹鹏CSS视频教程 编程之邦
  14. 【SpringBoot】63、SpringBoot中教你手把手封装自己的starter(xxl-job-spring-boot-starter)
  15. 电脑安装android2.0,应用多开 这才是最适用电脑的安卓—凤凰系统2.0
  16. 第一篇Blog,随便写一点吧:)
  17. 试用期三个月,快转正的时候,领导说,“你的表现没有达到预期”
  18. 家用空气净化器除甲醛什么品牌好 能除甲醛吗
  19. 分享六款原型设计软件,交流协作更便捷
  20. 史上最接地气的国外穷游攻略

热门文章

  1. ~7 ccf 2021-04-1 灰度直方图
  2. 最好用的房屋租赁软件(租赁行业)
  3. 解决typora beta版本过期提示
  4. 3Dmax+Substance Painter(SP)+.glb+threejs 次时代效果
  5. 2016计算机考研大纲视频,2016计算机考研大纲介绍:
  6. linux 查找删除目录,Linux运维知识之Linux系统下find命令递归删除查找目录的方法...
  7. 2022(核酸年)结束了
  8. 【操作系统基础】进程管理(三)进程同步与互斥
  9. 精彩回顾 |风丘科技亮相广州国际汽车测试技术展
  10. Android中的ShareSDK学习