【一篇就够了】springboot微信公众号开发,你的坑我来踩

前些日子在抖音上看到一个写给女朋友的微信公众号突然心血来潮自己也想写一个,随后就开始在下面的踩坑填坑的阶段了,因为也是第一次写微信公众号再次也是记录一下自己的开发过程。

如果你也是刚刚接触的公众号的我认为我们可以慢慢聊聊,再者我是一个喜欢化繁为简的人,不喜欢将问题搞的很复杂,所以我会尽可能的将问题描述的简单、清楚。

一.注册微信公众号

微信公众号注册网址

注册好之后


在开发者工具里面你能看到这些工具,我一般用的就是开发者文档、在线接口调试工具和公众平台测试账号。

这是就是测试号,往下滑就有关注的二维码,一般测试都是在这里测试开发,这里权限几乎全开,所以很方便。

二、准备开发

我其实一开始用的服务器,但是后来觉得这样调试特别麻烦,不过有兴趣的可以去试试微信云托管,这里就不说了(因为我也不会用),之后我就用花生壳内网穿透,映射出了一个外网ip。

需要注意的就是需要选择https这个,会出现什么不支持web访问。

最后就是将这个外网ip填写在下图,就是测试公众号的那个页面

到这里你可能有疑问:
1、接口配置信息是干嘛的?

简单画了一个示意图,因为你需要将自己的服务器接入公众号,那必然需要配置你的服务器地址,这个接口配置信息就是用来验证你的服务器是否有用和这个验证消息来自微信服务器

2、URL是指什么地址?
这个就是花生壳映射出来的外网IP,也就是用来验证你的服务器是否有用的

3、Token是什么?
这个就是用来验证消息来自微信服务器
这个值是可以任意填写的。在微信开发文档中也有介绍到如何验证服务器。

好复杂不想看?

那就直接看代码

这里可以简单的看一下目录结构,就是Controller层和Service

     @GetMapping()@ResponseBodypublic String doGet(@RequestParam("signature") String signature,@RequestParam("timestamp") String timestamp,@RequestParam("nonce") String nonce,@RequestParam("echostr") String echostr) {return weChatService.checkSignature(signature, timestamp, nonce,echostr);}

下面代码所做的就是:
1)将token、timestamp、nonce三个参数进行字典序排序
2)将三个参数字符串拼接成一个字符串进行sha1加密
3)开发者获得加密后的字符串可与 signature 对比,标识该请求来源于微信
token就是你自己填写的值。

 @Overridepublic String checkSignature(String signature, String timestamp, String nonce, String echostr) {log.info("接收来自微信服务器的认证消息:[{},{},{},{}]",signature,timestamp,nonce,echostr);//1)将token、timestamp、nonce三个参数进行字典序排序String[] str = new String[]{token, timestamp, nonce};Arrays.sort(str);//2)将三个参数字符串拼接成一个字符串进行sha1加密String str2 = str[0] + str[1] + str[2];String sha1Str = SecureUtil.sha1(str2);//3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信System.out.println("结果:" + sha1Str.equals(signature));log.info("结果:{}", sha1Str.equals(signature));if (sha1Str.equals(signature)){return echostr;}else {return "请求非法";}}

代码编写好这些之后,你就可以在接口配置信息里填写好你的url和你自己的token,点击提交,会提示提交成功。如果显示提交失败,需要注意一下代码是否报错和你的花生壳内网穿透是否成功,比如你yml文件里的端口号是否和花生壳内网端口相同。

三、自动回复(文本)

这里需要提醒一下微信公众号使用的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><MsgDataId>xxxx</MsgDataId><Idx>xxxx</Idx>
</xml>


而且这里需要特别注意一个点
我们之前开发都是在通过请求路径去区分调用方法,例如

@RestController
@RequestMapping("/wechat")
@Slf4j
public class WeChatController {@Autowiredprivate WeChatService weChatService;@GetMapping("/getToken")public ApiResponse doGet() {String token = weChatService.getToken();return ApiResponse.ok(token);}
}

请求就是ip:端口/wechat/getToken来达到请求的目的
但是微信这个是自动回复的微信服务器只是单纯的给我们服务器发送一个POST请求然后带上XML数据,所以我们只需要接收一个POST请求,读取XML格式返回;

Controller

@PostMapping(produces = "application/xml; charset=UTF-8")public String doPost(HttpServletRequest request) {return weChatService.dealMessage(request);}

Service

 @Overridepublic String dealMessage(HttpServletRequest request) {Map<String, String> map = MessageUtil.xmlToMap(request);String ToUserName = map.get("ToUserName");String FromUserName = map.get("FromUserName");String MsgType = map.get("MsgType");String CreateTime = map.get("CreateTime");String MsgId = map.get("MsgId");log.info("ToUserName:{},FromUserName:{},MsgType:{},CreateTime:{},MsgId:{}",ToUserName,FromUserName,MsgType,CreateTime,MsgId);if(MessageUtil.REQ_MESSAGE_TYPE_TEXT.equals(MsgType)){//文字String Content = map.get("Content");log.info("Content:{}",Content);TextMessage textMessage = new TextMessage();textMessage.setToUserName(FromUserName).setFromUserName(ToUserName).setMsgType(MsgType).setCreateTime(System.currentTimeMillis());textMessage.setContent(textReplyTemplateMapper.getReply(Content));return MessageUtil.messageToXml(textMessage);}return null;}

Util

public class MessageUtil {/*** 返回消息类型:文本*/public static final String RESP_MESSAGE_TYPE_TEXT = "text";/*** 返回消息类型:音乐*/public static final String RESP_MESSAGE_TYPE_MUSIC = "music";/*** 返回消息类型:图文*/public static final String RESP_MESSAGE_TYPE_NEWS = "news";/*** 请求消息类型:文本*/public static final String REQ_MESSAGE_TYPE_TEXT = "text";/*** 请求消息类型:图片*/public static final String REQ_MESSAGE_TYPE_IMAGE = "image";/*** 请求消息类型:链接*/public static final String REQ_MESSAGE_TYPE_LINK = "link";/*** 请求消息类型:地理位置*/public static final String REQ_MESSAGE_TYPE_LOCATION = "location";/*** 请求消息类型:音频*/public static final String REQ_MESSAGE_TYPE_VOICE = "voice";/*** 请求消息类型:推送*/public static final String REQ_MESSAGE_TYPE_EVENT = "event";/*** 事件类型:subscribe(订阅)*/public static final String EVENT_TYPE_SUBSCRIBE = "subscribe";/*** 事件类型:unsubscribe(取消订阅)*/public static final String EVENT_TYPE_UNSUBSCRIBE = "unsubscribe";/*** 事件类型:CLICK(自定义菜单点击事件)*/public static final String EVENT_TYPE_CLICK = "CLICK";public static Map<String, String> xmlToMap(HttpServletRequest request) {Map<String, String> map = new HashMap<>();SAXReader reader = new SAXReader();InputStream in = null;try {in = request.getInputStream();Document doc = reader.read(in);Element root = doc.getRootElement();List<Element> list = root.elements();for (Element element : list) {map.put(element.getName(), element.getText());}} catch (IOException | DocumentException e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {try {in.close();} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}return map;}/*** 消息转XML* @param message* @param <T>* @return*/public static <T> String messageToXml(T message) {XStream xstream  = new XStream();xstream.alias("xml", message.getClass());return xstream.toXML(message);}
}

以上就是消息回复的全部代码,回复的文本我保存在自己的数据库里,到时也可以自己配置回复对应的文本信息。

目前刚学到这也是即使的分享出来学习过程。。。也是诚恳的希望和大佬们多多交流交流。。。未完待续

=============================
女朋友分了,不搞了

【一篇就够了】springboot微信公众号开发,你的坑我来踩相关推荐

  1. 视频教程-SpringBoot微信公众号开发-微信开发

    SpringBoot微信公众号开发 就职于国内知名在线互联网旅游公司,10+互联网开发经验,精通前后端开发 刘志强 ¥149.00 立即订阅 扫码下载「CSDN程序员学院APP」,1000+技术好课免 ...

  2. 微信公众号开发 发现的 “坑”

    为什么80%的码农都做不了架构师?>>>    0.微信接入token验证问题 如果你是使用tp框架的,那么务必关闭调试模式,不然肯定不会通过,哈哈哈哈! 1.客服接口问题 客服接口 ...

  3. 从永远到永远-SpringBoot微信公众号开发实战(一)-自用

    项目架构: 角色:买家(手机).卖家(PC) 重点:前后台系统发起的请求均先经过nginx服务器,如果访问的后端接口,再由其对请求进行转发. 跟着视频自学Spring cloud项目,现做下关键遇坑记 ...

  4. Java微信公众号开发微信网页授权之前端传递code方式获取用户信息

    本片博客讲解的网页授权分为两步,前端先传递backUrl(回调地址)到后台网页授权接口,该接口拿到回调地址后组装授权连接,重定向到前端页面,前端页面截取Code,传入后端获取用户信息方法,获取用户信息 ...

  5. 公众号如何跳转到页面php,图文详解微信公众号开发自定义菜单跳转页面并获取用户信息实例...

    这篇文章主要介绍了微信公众号开发 自定义菜单跳转页面并获取用户信息实例详解的相关资料,需要的朋友可以参考下 微信公众号开发 自定义菜单 请先读完本文再进行配置开发 请先前往微信平台开发者文档阅读&qu ...

  6. 【除夕夜特辑】手把手教你微信公众号开发

    文章目录 文章主题 开发环境的搭建 接入微信公众平台 填写服务器配置 验证消息的确来自微信服务器 接收消息 回复消息 聊天机器人 回复图文消息 自定义菜单 菜单响应 模板消息 设置所属行业 发送模板消 ...

  7. 微信公众号开发-vue1

    转载于湖工电气兄弟原文:https://blog.csdn.net/zhuming3834/article/details/80845698 觉得这篇写得很好 微信公众号开发-vue 之前做这类项目都 ...

  8. 微信公众号开发教程(一) 验证接入

    作者:陈惠,叩丁狼教育高级讲师.原创文章,转载请注明出处. 微信公众号开发教程(一)验证接入 本篇文章主要介绍了微信公众号开发接入详细流程,希望对刚接触公众号开发的同学有所帮助,有兴趣的同学可多多关注 ...

  9. 微信公众号开发入门教程第一篇

    微信公众号开发入门教程第一篇 关键字:微信公众平台开发 作者:方倍工作室 在这篇微信公众平台开发教程中,我们假定你已经有了PHP语言程序.MySQL数据库.计算机网络通讯.及HTTP/XML/CSS/ ...

最新文章

  1. hdu 1520 树形dp
  2. java程序发送邮件_用java程序发送邮件
  3. 获取ClassLoader的途径
  4. java多线程中的死锁、活锁、饥饿、无锁都是什么鬼?
  5. 7-5 公路村村通 (30 分)(C语言实现)
  6. java 数据溢出和编译错误的差别
  7. node.js 端口号被占用解决方法
  8. 【白皮书分享】2020年5G应用创新发展白皮书.pdf(附下载链接)
  9. dubbo中源码之缓存设计
  10. 0-1之间的随机数 C/C++
  11. 多线程设计模式总结(一)
  12. java动态代理_Java核心 -- 动态代理
  13. 基于python的一个论文降重脚本
  14. [破解] nasca drm file -ver1.00
  15. python自动注册邮箱_python自动化办公——邮箱
  16. 保姆教程 | YOLOv5在建筑工地中安全帽佩戴检测的应用
  17. fps透视基础-3分钟快速定位矩阵基址-附3D坐标转屏幕坐标算法
  18. 《从0开始做运营》(有感)
  19. 微信支付(一)SpringBoot 实现微信扫码支付/Native支付
  20. 【Eigen】【Eigen实践】【Eigen的使用学习记录】

热门文章

  1. joomla+连接不上mysql_配置joomla数据库mysql
  2. 关于sublime代码格式化和关闭更新提示
  3. 过来人的经验:高中学历学Java能找到工作吗?
  4. 安装教程 | Eric7安装与配置
  5. java程序实现可移植性依靠的是_什么是JAVA的可移植性
  6. excel表格右上角添加小红三角标记
  7. 自制深度学习推理框架-第七课-构建自己的计算图
  8. 安全狗加入UAPP 共建国产操作系统安全生态
  9. 工程师、程序员、码农有什么区别?
  10. 【故事编程:Lambda表达式】之久久未回的消息(三)