spring-boot-route(二十三)开发微信公众号
在讲微信公众号开发之前,先来大概了解一下微信公众号。微信公众号大体上可以分为服务号和订阅号,订阅号和服务号的区别如下:
- 服务号可以申请微信支付功能。
- 服务号只能由企业申请,订阅号可以有企业或个人申请。
- 订阅号和服务号每月推送消息次数不同,订阅号每天可以推送一次,服务号每月可以推送四次。
- 服务号推送的消息会出现在用户的聊天列表中,而订阅号推送的消息显示在订阅号文件夹中。
- 还有一些其他接口功能的区别和限制,总的来说服务号支持更高级的功能开发。
订阅号更加偏向于向用户传递咨询,一般各种技术类公众号都属于订阅号,订阅号的消息推送并不会有太显眼的提醒,如果你想让某个公众号的推送内容更加显眼,可以选择置为星标。置为星标后公众号会显示在所有订阅号的最顶部,同时收到消息后会有黄色五角星星标提醒。
一 公众号配置服务器
微信官方提供了非常完善的接入文档,如果想了解文档的具体内容,直接浏览器搜索微信开发文档就可以了。但是为了方便开发,一般不会直接去根据微信开发文档进行开发,gitee上有许多开源项目对微信开发文档进行了封装,这里我使用mica-weixin
开发包进行演示,mica-weixin
是jfinal-weixin
的boot版本。
配置服务器信息很简单,具体流程就是微信服务发送请求一个请求给业务服务器,业务服务器验证请求后给微信服务一个响应。
1.1 搭建业务服务
本地搭建一个spring-boot-weixin
的项目,使用内网穿透工具进行穿透,使其可以与外网进行通信。
1.1.1 引入mica-weixin
依赖
<dependency> <groupId>net.dreamlu</groupId> <artifactId>mica-weixin</artifactId> <version>2.0.1</version> </dependency>
1.1.2 配置公众号信息
mica-weixin
通过配置文件进行公众号信息的配置,如果你想通过数据库配置公众号信息,可以参考我以前写过的一篇文章jfinal-weixin自定义配置支持多公众号。
dream: weixin: wx-configs: - appId: xxxxxx appSecret: xxxxxx token: javatrip encodingAesKey: xxxxxx
appId
和appSecret
可在公众号后台进行查看,具体位置在菜单开发—>基本配置中,其中appSecret
要妥善保管,现在公众号已经不支持查看appSecret
了,如果你忘了appSecret
,只能进行重置。
1.1.3 开发消息校验接口
mica-weixin
已经为我们提供好了消息校验接口,只需要继承DreamMsgControllerAdapter
就可以了。
@WxMsgController("/weixin/wx") public class WeiXinMsgController extends DreamMsgControllerAdapter { @Override protected void processInFollowEvent(InFollowEvent inFollowEvent) { } @Override protected void processInTextMsg(InTextMsg inTextMsg) { } @Override protected void processInMenuEvent(InMenuEvent inMenuEvent) { } }
同时,需要开启缓存,由于mica-weixin
的将access_token
等信息放在了缓存中。在启动类上加@EnableCaching
就开启了。
@SpringBootApplication @EnableCaching public class WeixinApplication { public static void main(String[] args) { SpringApplication.run(WeixinApplication.class, args); } }
1.1.4 公众号后台配置服务器信息
使用内网穿透工具穿透内网地址,然后在公众号后台菜单开发—>基本配置中填写服务器配置信息。
填写完成后点击启用,这样就完成了微信服务器和业务服务器的关系配置。开启开发者配置后,自动回复、自定义菜单等功能都不能正常使用了。这时候就需要去调用对应的接口实现这些功能。
二 实现各种消息接口
2.1 关注消息
在一步中,自定义类WeiXinMsgController
中需要重写三个父类中的方法,其中processInFollowEvent()
就是关注和取消关注的方法,取消关注后用户虽然不能收到消息,但是后台可以接收到用户取消关注的事件。
@Override protected void processInFollowEvent(InFollowEvent inFollowEvent) { OutTextMsg defaultMsg = new OutTextMsg(inFollowEvent); // 关注 if(InFollowEvent.EVENT_INFOLLOW_SUBSCRIBE.equals(inFollowEvent.getEvent())){ // 可将关注用户录入db,此处可以获取到用户openid String openId = inFollowEvent.getFromUserName(); // 查询db,根据响应消息类型封装消息体 if("文本消息"){ OutTextMsg otm = new OutTextMsg(inFollowEvent); otm.setContent("消息内容"); render(otm); return; }else if("图片消息"){ OutImageMsg oim = new OutImageMsg(inFollowEvent); // 这里需要调用微信提供的素材接口,将图片上传至素材库。 oim.setMediaId("图片素材id"); render(oim); return; }else if("图文消息"){ OutNewsMsg onm = new OutNewsMsg(inFollowEvent); onm.addNews("标题","简介","图片地址","图文链接"); render(onm); return; }else if("视频消息"){ OutVideoMsg ovm = new OutVideoMsg(inFollowEvent); ovm.setTitle("标题"); ovm.setDescription("简介"); ovm.setMediaId("视频素材id"); render(ovm); return; }else{ defaultMsg.setContent("感谢关注"); } } // 取消关注 if(InFollowEvent.EVENT_INFOLLOW_UNSUBSCRIBE.equals(inFollowEvent.getEvent())){ log.info("用户取消关注了"); // 此处可以将取消关注的用户更新db } }
2.2 关键词消息
响应内容跟关注消息一样,查询db去匹配关键词,然会根据消息内容封装对应的消息体进行返回,如果没匹配到关键词则回复统一的消息内容。processInTextMsg()
方法就是用来回复关键词消息的。
@Override protected void processInTextMsg(InTextMsg inTextMsg) { String content = inTextMsg.getContent(); // 根据用户发送的content去查询db中的响应内容 if("文本消息"){ OutTextMsg otm = new OutTextMsg(inTextMsg); otm.setContent("消息内容"); render(otm); return; }else if("图片消息"){ OutImageMsg oim = new OutImageMsg(inTextMsg); // 这里需要调用微信提供的素材接口,将图片上传至素材库。 oim.setMediaId("图片素材id"); render(oim); return; }else if("图文消息"){ OutNewsMsg onm = new OutNewsMsg(inTextMsg); onm.addNews("标题","简介","图片地址","图文链接"); render(onm); return; }else if("视频消息"){ OutVideoMsg ovm = new OutVideoMsg(inTextMsg); ovm.setTitle("标题"); ovm.setDescription("简介"); ovm.setMediaId("视频素材id"); render(ovm); return; }else{ OutTextMsg otm = new OutTextMsg(inTextMsg); otm.setContent("暂未查到关键词..."); } }
2.3 菜单消息
点击菜单后也是一样,通过processInMenuEvent()
方法进行响应内容的回复。
@Override protected void processInMenuEvent(InMenuEvent inMenuEvent) { String eventKey = inMenuEvent.getEventKey(); // 根据用户发送的content去查询db中的响应内容 if("文本消息"){ OutTextMsg otm = new OutTextMsg(inMenuEvent); otm.setContent("消息内容"); render(otm); return; }else if("图片消息"){ OutImageMsg oim = new OutImageMsg(inMenuEvent); // 这里需要调用微信提供的素材接口,将图片上传至素材库。 oim.setMediaId("图片素材id"); render(oim); return; }else if("图文消息"){ OutNewsMsg onm = new OutNewsMsg(inMenuEvent); onm.addNews("标题","简介","图片地址","图文链接"); render(onm); return; }else if("视频消息"){ OutVideoMsg ovm = new OutVideoMsg(inMenuEvent); ovm.setTitle("标题"); ovm.setDescription("简介"); ovm.setMediaId("视频素材id"); render(ovm); return; }else{ OutTextMsg otm = new OutTextMsg(inMenuEvent); otm.setContent("无效链接,请重试..."); } }
三 接口API调用
目前,微信提供的接口对订阅号的限制比较大,未认证的订阅号基本上只有接收消息的几个功能接口。
调用接口的时候需要传递token
,获取token需要在微信后台中配置业务服务器的白名单。如下:
如果需要配置多个白名单ip,使用回车键将多个ip分隔开。
mica-weixin
提供了所有的接口封装,具体可参考它的官方文档,如果要获取微信菜单,可以这样写:
@WxApi("weixin/api") public class WeiXinApiController { @GetMapping("menu") @ResponseBody public String getMenu(){ ApiResult menu = MenuApi.getMenu(); return menu.getJson(); } }
@WxApi
这个是它的自定义注解,其实就是包含了@RequestMapping
和@Controller
。
四 其他事项
4.1 多公众号配置
mica-weixin
提供了多公众号配置的功能,使用ThreadLocal
和appid
进行绑定。只需要简单配置即可实现多公众号配置。
dream: weixin: wx-configs: - appId: xxxxxx appSecret: xxxxxx token: javatrip encodingAesKey: xxxxxx - appId: xxxxxx appSecret: xxxxxx token: javatrip encodingAesKey: xxxxxx
4.2 redis配置
access_token
的有效期是2小时,并且该接口有调用次数限制,mica-weixin
将access_token
存储在redis中,避免每次调用接口都去获取access-token
,因此项目需要配置redis。
spring: redis: host: localhost port: 6379
4.3 手动选择ThreadLocal
如果想要开发微信公众号的后台管理功能,多公众号的时候就需要手动去指定当前线程使用哪个公众号信息。如下:
ApiConfigKit.setThreadLocalAppId(appid);
至此,SpringBoot开发微信公众号就算完成了,由于订阅号开放的接口太少了,好多功能不能正常演示。还有mica-weixin
也许不是最好的选择,如果想试着开发微信公众号,可以在gitee上找一下开发包。至于我为什么会使用mica-weixin
,是因为我曾用过一段时间的jfinal
框架,与之配套的微信开发包就是jfinal-weixin
,也就是jfinal版的mica-weixin
。
本文示例代码已上传至github,点个star
支持一下!
Spring Boot系列教程目录
spring-boot-route(一)Controller接收参数的几种方式
spring-boot-route(二)读取配置文件的几种方式
spring-boot-route(五)整合Swagger生成接口文档
spring-boot-route(六)整合JApiDocs生成接口文档
spring-boot-route(七)整合jdbcTemplate操作数据库
spring-boot-route(八)整合mybatis操作数据库
spring-boot-route(九)整合JPA操作数据库
spring-boot-route(十一)数据库配置信息加密
spring-boot-route(十二)整合redis做为缓存
spring-boot-route(十三)整合RabbitMQ
spring-boot-route(十五)整合RocketMQ
spring-boot-route(十六)使用logback生产日志文件
spring-boot-route(十七)使用aop记录操作日志
spring-boot-route(十八)spring-boot-adtuator监控应用
spring-boot-route(十九)spring-boot-admin监控服务
spring-boot-route(二十)Spring Task实现简单定时任务
spring-boot-route(二十一)quartz实现动态定时任务
spring-boot-route(二十二)实现邮件发送功能
这个系列的文章都是工作中频繁用到的知识,学完这个系列,应付日常开发绰绰有余。如果还想了解其他内容,扫面下方二维码告诉我,我会进一步完善这个系列的文章!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
小熊派开发实践丨漫谈LiteOS之传感器移植
摘要:本文基于小熊派开发板简单介绍了如何在LiteOS中移植传感器,从而实现对于传感器的相关控制。 1 hello world 相信大家无论在学习编程语言开始的第一个函数应该是HelloWorld,本文将从hello_world_demo为大家介绍如何实现传感器的移植工作。 首先我们创建HelloWorld工程,选择STM32_BearPi → hello_world_demo,工程名称可以自定义。 创建之后我们点击编译,然后烧录到开发板,打开VSCode-IoTLink的串口,并按照图中进行设置串口连接参数,之后按键Reset,可以看到串口打印如下图所示。 首先来介绍一下代码运行的简单流程,之前在漫谈LiteOS系列中介绍过LiteOS 的启动流程,我们知道在程序下载到开发板之后,首先会按一下Reset按键进行开发板的启动,因此在开发板上电之后执行的第一个函数就是ReSet_Handler函数。 首先找到对应的启动文件los_startup.S 文件(根据使用的操作系统以及板子MCU系列查找文件目录),可以看到其由汇编语言编写,具体启动流程在漫谈LiteOS系列中已经介绍过,这里只看...
- 下一篇
理解 http 反向代理
要理解什么是 反向代理(reverse proxy) , 自然你得先知道什么是 正向代理(forward proxy). 另外需要说的是, 一般提到反向代理, 通常是指 http 反向代理, 但反向代理的范围可以更大, 比如 tcp 反向代理, 在这里, 不打算讨论 tcp 之类的反向代理, 当文中说到反向代理时, 指的就是 http 反向代理. 正向代理通常直接称为 代理(proxy), 无需强调它是正向的, 在 http 协议中, 代理即指正向代理. 直接访问 而要谈论什么是正向代理, 则需要先讨论"直接访问"的形式. 也就是没有任何代理的模式. 事实上, 直接访问对于很多的小网站来说是最常见的方式. 直接访问用我们日常购物来比喻的话就是类似于"厂家直销", 你直接向生产厂家下单, 没有经过任何的中间商. 从系统的角度看, "直接访问"就是浏览器的请求直接到了最终生成网页的服务器, 中间没有经过任何的 http 代理服务器. 那么代理或者说更啰嗦点的"正向代理"又是什么情况呢? 正向代理(forward proxy) 还是用购物来比喻的话, 你从商店里而不是直接从厂家购买一个商品就...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS6,7,8上安装Nginx,支持https2.0的开启
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS7,8上快速安装Gitea,搭建Git服务器
- CentOS8编译安装MySQL8.0.19
- CentOS关闭SELinux安全模块
- CentOS7设置SWAP分区,小内存服务器的救世主
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题