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
。
此是spring-boot-route系列的第二十三篇文章,这个系列的文章都比较简单,主要目的就是为了帮助初次接触Spring Boot 的同学有一个系统的认识。本文已收录至我的github,欢迎各位小伙伴star
!
github:https://github.com/binzh303/spring-boot-route
点关注、不迷路
如果觉得文章不错,欢迎关注、点赞、收藏,你们的支持是我创作的动力,感谢大家。
如果文章写的有问题,请不要吝惜文笔,欢迎留言指出,我会及时核查修改。
spring-boot-route(二十三)开发微信公众号的更多相关文章
- Spring Boot 开发微信公众号后台
Hello 各位小伙伴,松哥今天要和大家聊一个有意思的话题,就是使用 Spring Boot 开发微信公众号后台. 很多小伙伴可能注意到松哥的个人网站(http://www.javaboy.org)前 ...
- PHP开发微信公众号(一)二维码的获取
要开发微信公众号,首先进行需要注册一个,然后认证.这就不用多说了. 当然如果没有,也可以去申请一个测试号来使用,地址:https://mp.weixin.qq.com/debug/cgi-bin/sa ...
- Java开发微信公众号(二)---开启开发者模式,接入微信公众平台开发
接入微信公众平台开发,开发者需要按照如下步骤完成: 1.填写服务器配置 2.验证服务器地址的有效性 3.依据接口文档实现业务逻辑 资料准备: 1.一个可以访问的外网,即80的访问端口,因为微信公众号接 ...
- Java开发微信公众号(一)---初识微信公众号以及环境搭建
ps:1.开发语言使用Java springMvc+Mybaits+spring maven实现 2.使用微信接口测试账号进行本地测试 https://mp.weixin.qq.com/debug/c ...
- 使用vue开发微信公众号下SPA站点的填坑之旅
原文发表于本人博客,点击进入使用vue开发微信公众号下SPA站点的填坑之旅 本文为我创业过程中,开发项目的填坑之旅.作为一个技术宅男,我的项目是做一个微信公众号,前后端全部自己搞定,不浪费国家一分钱^ ...
- Java开发微信公众号(五)---微信开发中如何获取access_token以及缓存access_token
获取access_token是微信api最重要的一个部分,因为调用其他api很多都需要用到access_token.比如自定义菜单接口.客服接口.获取用户信息接口.用户分组接口.群发接口等在请求的时候 ...
- Java开发微信公众号(四)---微信服务器post消息体的接收及消息的处理
在前几节文章中我们讲述了微信公众号环境的搭建.如何接入微信公众平台.以及微信服务器请求消息,响应消息,事件消息以及工具处理类的封装:接下来我们重点说一下-微信服务器post消息体的接收及消息的处理,这 ...
- Java开发微信公众号(三)---微信服务器请求消息,响应消息,事件消息以及工具处理类的封装
在前面几篇文章我们讲了微信公众号环境的配置 和微信公众号服务的接入,接下来我们来说一下微信服务器请求消息,响应消息以及事件消息的相关内容,首先我们来分析一下消息类型和返回xml格式及实体类的封装. ( ...
- 小机器人自动回复(python,可扩展开发微信公众号的小机器人)
api来之图灵机器人.我们都知道微信公众号可以有自动回复,我们先用python脚本编写一个简单的自动回复的脚本,利用图灵机器人的api. http://www.tuling123.com/help/h ...
随机推荐
- Kubernetes中的Helm和修改证书有效时间(八)
一.Helm的介绍 1,概念 Helm 把 k8s 资源(比如 deployments.services 或 ingress 等)打包到一个 chart 中,而 chart 被保存到 chart 仓库 ...
- spring framework源码之AnnotationConfigApplicationContext
AnnotationConfigApplicationContext 内部使用了AnnotatedBeanDefinitionReader:ClassPathBeanDefinitionScanner ...
- Spring Boot 如何使用拦截器、过滤器、监听器?
过滤器 过滤器的英文名称为 Filter, 是 Servlet 技术中最实用的技术. 如同它的名字一样,过滤器是处于客户端和服务器资源文件之间的一道过滤网,帮助我们过滤掉一些不符合要求的请求,通常用作 ...
- Windows10数字权利永久激活教程
很多人用Windows10系统,但是没有办法激活,这个教程一定会让你永久激活windows10系统(并非ksm) 打开设置,查看是否激活 如果激活的话,先退掉秘钥,在Windows power ...
- 刷题[网鼎杯 2020 朱雀组]phpweb
解题思路 打开是一个蛮有意思的背景,众生皆懒狗,是自己没错了.源代码看一看,啥都没有.抓个包 诶,一看到func和p两个参数,想到了call_user_func(). 尝试着把date改成system ...
- 2019.8.13 sdfzoier
lxy: lixf acwing上的118,126 zhangtingyu zhaosirui wujialin
- IPV6介绍已经IPV6改造基本步骤
IPV6介绍 地址资源无限多 通常见到的124.33.24.116这种形式的是ipv4版本的地址,这种地址由32位二进制数表示. ipv6是一种新的ip地址的表示方式形如fc80::2367:7cff ...
- sipp3.6对freeswitch进行压力测试
一.安装sipp 1.下载地址: https://github-production-release-asset-2e65be.s3.amazonaws.com/13161657/99df6100-9 ...
- [Vue warn]: Error in render: "TypeError: Cannot read property 'matched' of undefined" found in <App> at src/App.vue
当用Vue模块化开发时,输入 http://localhost:8080 页面没有显示,首先按F12,检查是否有如下错误 话不多说,直接看下面: 解决方法1 如果是上面出的问题,以后就要注意了哦, ...
- 【学习笔记/题解】分层图/[JLOI2011]飞行路线
题目戳我 \(\text{Solution:}\) 关于分层图: 一般用于处理:给你\(k\)次机会对边权进行修改的最短路问题. 算法流程: 建立出\(k\)层图,对应进行\(k\)次操作后的局面. ...