系列文章传送门

公众号开发精品教程(1)——绪论及环境搭建

公众号开发精品教程(2)——将项目接入微信及简单交互

公众号开发精品教程(3)——创建菜单

公众号开发精品教程(4)——生成带参数的二维码及合成海报

公众号开发精品教程(5)——获取用户基本信息与网页授权

整个项目的源码已经上传到百度网盘(博主的Git在维护,就不拿出来丢人了),永久有效,免费,在ChatConf类中填写自己的APPID和开发者密钥,在相关地方替换一下外网域名,即可使用,如有任何问题,欢迎在下方评论:

链接:百度网盘传送门
提取码:03eb

目录

前言

开始接入

简单的交互

一、被关注时自动回复

二、用户发送消息时,自动回复

小结


前言

在上一篇博文中,我们申请了公众号的测试号,创建了服务器项目,并且通过内网穿透映射到了外网上。

那么我们如何让微信把公众号产生的消息,发送给我们的服务器呢?这就要在公众平台去配置服务器信息,因为我们这里是自己学习体验,所以在公众号测试系统去操作即可,公众号测试系统入口:

https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/index

用你注册公众号的微信,扫码登录即可。

开始接入

登录到测试号系统中后,你会看到如下信息:

我们就是要在这里,配置自己的服务器信息。我们暂且不配置,因为后台服务器还没有进行相关代码的编写,先看一下文档怎么说。

主要是三个信息

1、提交配置之后,用户在你的公众号所有的操作,微信都会转发到你填写的URL

2、成为开发者时的认证,是以GET方式提交到你填写的URL,并且携带4个参数

3、认证逻辑你自己编写,只要你最后返回给我echostr字符串即可,哪怕不进行验证直接返回

既然这样,那我们就开始动手吧!

仍然继续在上一篇文章中创建的项目,我们新建一个WechatController,用于处理微信发来的请求:

package com.blog.wechat.controller;import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;/***  微信控制器,负责接收微信推送的消息及开发者验证* @author 秋枫艳梦* @date 2019-06-02* */
@Controller
public class WechatController {/***  进行开发者验证,接入微信。注意这个方法是GET请求* @param signature 微信加密签名* @param timestamp 时间戳* @param nonce 随机数* @param echostr 随机字符串* @return 验证通过,原样返回echostr字符串* */@RequestMapping(value = "/wechat",method = RequestMethod.GET)public void checkAuth(@RequestParam(value = "signature") String signature,@RequestParam(value = "timestamp") String timestamp,@RequestParam(value = "nonce") String nonce,@RequestParam(value = "echostr") String echostr,HttpServletResponse response) {//认证逻辑这里就不实现了,我们直接返回echostr,写入到响应体中PrintWriter writer = null;try {writer = response.getWriter();//返回结果writer.print(echostr);} catch (IOException e) {e.printStackTrace();}finally {if (writer!=null){writer.close();}}}
}

然后在测试号系统中填写我们的服务器配置(不要忘了先将你的项目映射到外网上),域名+请求路径:

然后点击提交,如果你的项目及配置没问题的话,会显示配置成功,这时就已经对接上了,用户跟公众号产生的所有交互都会访问这个URL。

简单的交互

测试号系统中有一个二维码,我们扫一下,关注一下我们的测试公众号:

我们向公众号发起了交互,却说服务异常? 这是因为我们的服务器没有作出响应。前面提到,一旦成为了开发者模式,所有的交互行为都会访问我们填写的URL,这里也就是http://umu5uk.natappfree.cc/wechat,但是我们并没有处理这些交互,微信得不到响应,就会通知用户发生了异常。

那么问题来了,我只有一个/wechat请求处理路径,而且我已经用这个路径做了开发者认证,怎么能继续用它处理交互行为呢?

这就需要看文档了,文档指出,成为开发者模式的时候,是GET方式访问这个URL,而所有的事件交互,以POST方式访问。而且交互分为几种:普通消息、事件推送等,刚才我们向公众号发信息,属于普通消息,而被关注属于事件推送。

接下来,我们做两件事:

1、被关注的时候,给用户发送消息;

2、用户发送消息过来时,回复用户;

一、被关注时自动回复

这里需要向用户发送信息,所以先看一下文档怎么说:

因为我们要在用户关注的时候,发送给用户一段文本信息,所以就要先接收微信的事件推送,继续看文档:

文档指出,当公众号被关注时,微信会向我们配置的服务器发送一个POST请求,并且携带一个XML格式的请求体,结合下面的参数说明,我们可以知道被关注时的event为subscribe,那么思路就理顺了:

先在控制器中解析微信推过来的xml数据,拿到event的值,如果是subscribe,则返回一个回复文本消息的xml响应体。

然后开始写代码,因为微信推过来的数据是XML格式的,操作起来不方便,所以我们先将它转为Map,写一个工具类:

注意:这里是采用dom4j解析的,需要引入依赖。

package com.blog.wechat.utils;import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/***  XML解析工具类* @author 秋枫艳梦* @date 2019-06-02* */
public class XMLUtil {/***  将XML转换成Map* @param inputStream 请求体中的输入流* @return Map* */public static Map<String,String> getMap(InputStream inputStream){//返回的MapMap<String,String> map = new HashMap<>();//初始化解析器SAXReader reader = new SAXReader();//读取XML文档Document document = null;try {document = reader.read(inputStream);} catch (DocumentException e) {e.printStackTrace();}//获取XML文档的根节点Element element = document.getRootElement();//遍历所有节点,把键和值存入MapList<Element> elementList = element.elements();for (Element e : elementList) {map.put(e.getName(),e.getText());}return map;}
}

然后还需要一个工具类,负责生成回复给用户的消息:

package com.blog.wechat.utils;/***  返回消息的工具类* @author 秋枫艳梦* @date 2019-06-02* */
public class MessageUtil {/*** 要回复的消息* @param fromUser 发送方* @param toUser 接收方* @param content 回复给用户的内容* @return 整理好的XML文本* */public static String setMessage(String fromUser,String toUser,String content){return "<xml>\n" +"  <ToUserName><![CDATA["+toUser+"]]></ToUserName>\n" +"  <FromUserName><![CDATA["+fromUser+"]]></FromUserName>\n" +"  <CreateTime>12345678</CreateTime>\n" +"  <MsgType><![CDATA[text]]></MsgType>\n" +"  <Content><![CDATA["+content+"]]></Content>\n" +"</xml>";}
}

然后在WechatController中增加一个POST请求的处理方法,请求路径依然是/wechat,返回数据格式是application/xml:

/***  处理交互行为* @param request 请求体* @param response 响应体* */@RequestMapping(value = "/wechat",method = RequestMethod.POST,produces = {"application/xml;charset=utf-8"})public void doRequest(HttpServletRequest request,HttpServletResponse response) throws IOException {//将XML转为MapMap<String,String> map = XMLUtil.getMap(request.getInputStream());PrintWriter writer = response.getWriter();//这里不要弄混了,微信推过来的信息是用户发过来的,所以ToUserName是我们的公众号,FromUserName是用户的微信openid//所以我们既然要回复过去,就要颠倒过来String fromUser = map.get("ToUserName");String toUser = map.get("FromUserName");String content = "";//先判断是事件消息,还是普通消息if (map.get("MsgType").equals("event")){//如果是被关注事件,向用户回复内容,只需要将整理好的XML文本参数返回给微信即可if (map.get("Event").equals("subscribe")){content = "欢迎关注秋枫艳梦的测试公众号!";//把数据包返回给微信服务器,微信服务器再推给用户writer.print(MessageUtil.setMessage(fromUser,toUser,content));}}writer.close();}

然后重新运行项目,重新关注测试公众号:

到这里,我们的第一个任务就完成了,接下来我们再完成下一个。

二、用户发送消息时,自动回复

这个场景很常见,用户发送一个信息,公众号返回一段内容,接下来我们就实现这个功能。

首先要明确,这个场景不再是事件消息了,而是普通消息,而且是普通消息中的文本消息,看一下文档说明:

所以我们要做如下处理:

/***  处理交互行为* @param request 请求体* @param response 响应体* */@RequestMapping(value = "/wechat",method = RequestMethod.POST,produces = {"application/xml;charset=utf-8"})public void doRequest(HttpServletRequest request,HttpServletResponse response) throws IOException {//将XML转为MapMap<String,String> map = XMLUtil.getMap(request.getInputStream());PrintWriter writer = response.getWriter();//这里不要弄混了,微信推过来的信息是用户发过来的,所以ToUserName是我们的公众号,FromUserName是用户的微信openid//所以我们既然要回复过去,就要颠倒过来String fromUser = map.get("ToUserName");String toUser = map.get("FromUserName");//要返回给用户的信息String content = "";//先判断是事件消息,还是普通消息if (map.get("MsgType").equals("event")){//如果是被关注事件,向用户回复内容,只需要将整理好的XML文本参数返回给微信即可if (map.get("Event").equals("subscribe")){content = "欢迎关注秋枫艳梦的测试公众号!";}}else if (map.get("MsgType").equals("text")){//如果是普通文本消息,先拿到用户发送过来的内容,模拟自动答疑的场景String text = map.get("Content");if (text.equals("1")){content = "您可以在“我的账户——服务——退款”中查看您的退款明细";}else if (text.equals("2")){content = "如果您购买了本店的产品,订单页面会展示在您的主菜单中";}else if (text.equals("3")){content = "如有更多问题,请拨打我们的客服热线:xxxxx";}else {//否则,不管用户输入什么,都返回给ta这个列表,这也是最常见的场景content = "请输入您遇到的问题编号:\n"+"1、如何查看退款进度?\n"+"2、我的订单在哪里查看?\n"+"3、其他问题";}}//把数据包返回给微信服务器,微信服务器再推给用户writer.print(MessageUtil.setMessage(fromUser,toUser,content));writer.close();}

我们重新运行项目,测试一下:

小结

今天的博文就更新到这里,下一篇文章,将带领大家创建公众号的菜单!

公众号开发精品教程(2)——将项目接入微信及简单交互相关推荐

  1. 公众号开发精品教程(1)——绪论及环境搭建

    系列文章传送门 公众号开发精品教程(1)--绪论及环境搭建 公众号开发精品教程(2)--将项目接入微信及简单交互 公众号开发精品教程(3)--创建菜单 公众号开发精品教程(4)--生成带参数的二维码及 ...

  2. C#微信公众号开发系列教程二(新手接入指南)

    此系列前面已经更新了两篇博文了,都是微信开发的前期准备工作,现在切入正题,本篇讲解新手接入的步骤与方法,大神可直接跳过,也欢迎大神吐槽. 微信公众号开发系列教程一(调试环境部署) 微信公众号开发系列教 ...

  3. 微信公众号开发系列教程一(调试环境部署)

    http://www.cnblogs.com/zskbll/p/4074855.html 目录 C#微信公众号开发系列教程一(调试环境部署) C#微信公众号开发系列教程一(调试环境部署续:vs远程调试 ...

  4. 微信公众号开发系列教程一(调试环境部署续:vs远程调试)

    微信公众号开发系列教程一(调试环境部署) 微信公众号开发系列教程一(调试环境部署续:vs远程调试) C#微信公众号开发系列教程二(新手接入指南) C#微信公众号开发系列教程三(消息体签名及加解密) C ...

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

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

  6. C#微信公众号开发系列教程三(消息体签名及加解密)

    http://www.cnblogs.com/zskbll/p/4139039.html C#微信公众号开发系列教程一(调试环境部署) C#微信公众号开发系列教程一(调试环境部署续:vs远程调试) C ...

  7. C#微信公众号开发系列教程五(接收事件推送与消息排重)

    C#微信公众号开发系列教程五(接收事件推送与消息排重) 原文:C#微信公众号开发系列教程五(接收事件推送与消息排重) 微信公众号开发系列教程一(调试环境部署) 微信公众号开发系列教程一(调试环境部署续 ...

  8. 微信公众号开发详细教程

    微信公众号开发之配置开发服务器 微信公众号开发之获取access_token 微信公众号开发之关键词回复 微信公众号开发之模板消息 微信公众号开发之授权回调

  9. 微信公众号开发完整教程(一) PHP7.0版本,TP5.0框架

    因为工作的需要,这一两年对微信公众号和小程序,项目制作的比较多.所以我才打算写一篇全面的制作教程,当然了,最好的教程是微信工作平台的文档.我这里只是讲述一下我的工作中的制作流程.所有相关文章的源码,我 ...

最新文章

  1. python3 graphviz入门教程
  2. mysql如何插入新的字段_Mysql 如何 得到新插入的字段ID
  3. 基于享元记忆的 Boost.Flyweight 示例
  4. C# 汉字转拼音(全拼)
  5. java 毫秒转分钟和秒_PDF如何转换CAD文件?教你一分钟批量转上百文件方法,看完秒懂!...
  6. Win11系统使用Excel表格的时候很卡怎么办
  7. cr全称是什么意思_轻生未遂?她到底经历了些什么......
  8. 刚毕业就年薪百万,谁说知识不是财富
  9. hadoop2.x配合ZooKeeper集群环境搭建
  10. mysql 5.5 驱动jar包_MySQL驱动jar包下载
  11. 【MSRA文档智能综述论文】Document AI: Benchmarks, Models and Applications
  12. 【软件测试】应用白盒测试实例
  13. 基于QT的HLW8032电能芯片测试上位机开发
  14. 如何利用ikuai将闲置电脑配作软路由器?
  15. javascript写的日历控件(收藏)
  16. 详解Qt字体设置 (QFont)
  17. Android自定义折线图,可设置基准线,不同点颜色
  18. Aprioriall算法
  19. 二维码登录原理+Web端即时通讯技术
  20. CSS 关键字 initial、inherit 和 unset

热门文章

  1. @用Python的turtle库画一个奥运五环!
  2. avatar-view
  3. 学网页平面UI设计,我选择广州传智播客
  4. 快讯|ONES 通过 CMMI 3 级评估认证
  5. 【Linux】进程信号
  6. xy坐标正负方向_道路施工图纸上x坐标和y坐标分别代表什么方向?哪个代表南北方向?哪个代表东西方向?...
  7. 数据可视化呈现方式有哪些
  8. python N叉树
  9. 虽说是递推式,但我还是觉得是逆推法
  10. java 中的 while和 do...while语句的区别