工具:idea2018,jdk1.8,框架:springboot+thymeleaf前端
说明,本项目着力于快速开发,前端页面只作最基本的页面跳转和参数校验。如果须要先后端分离,可参考一些开源的项目,如givebest/node.js-wechat-js-sdkjava
1、测试/正式帐号公众平台测试帐号,根据上一篇注册便可node
2、web开发者工具,拖至文末,选择适配版本下载便可。(由于微信部分URL须要权限的校验,只能在微信浏览器内打开,而相似postman的第三方工具没法使用)mysql
3、公网可访问地址,如阿里云,或内网穿透工具,可参考上一篇中【接口配置信息修改】。(个人是http://chety.mynatapp.cc -> 127.0.0.1:8080,已打开状态)git
4、订阅测试号,扫描二维码便可github
向公众号发送消息,公众号原样返回咱们的内容,如发送【你好】,公众号回复【你好】web
1、参考微信公众平台技术文档,选择【消息管理】模块中的【接收普通消息】。spring
2、根据接收普通消息的介绍,可知:sql
3、参数介绍数据库
如文本消息,有消息的发送的接收方,消息类型和内容等。可以使用bean对象来封装该消息格式
ToUserName
:开发者微信号,即目前我正在使用的测试公众号FromUserName
:发送方帐号,描述为一个openid
,即一个手机微信用户在一公众号下的惟一标识,不管何种客户端设备访问,该id都是统一且惟一的。注意:消息的收发方是相对的,客户端与服务端相反
1、新建springboot项目,须要的核心依赖以下:
<dependencies>
<!-- web项目 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.1</version>
</dependency>
<!-- 引入thymeleaf -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- alibaba druid链接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
<!-- lombok JavaBean工具 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.8</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpcore</artifactId>
<version>4.4.11</version>
</dependency>
<!-- http客户端工具 -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.9</version>
</dependency>
<!-- json转换工具 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.58</version>
</dependency>
<!-- 数据库可选,如项目须要本地存储支付交易流水 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.26</version>
<scope>runtime</scope>
</dependency>
</dependencies>
复制代码
2、我这里都使用默认配置,所以暂时不配置application.yml,各位根据本身的须要配置
3、根据输入消息的字段,封装为bean对象
注意,xml中参数的键都是大写,所以定义java参数时,须要使用注解或直接大写命名
@Data // lombok,包含setter,getter,tostring
@XmlRootElement(name = "xml") // 根节点
@XmlAccessorType(XmlAccessType.FIELD) // 映射类中的全部字段到XML
public class MsgSendEntity {
/** * 公有部分 */
// 开发者微信号
@XmlElement(name = "ToUserName") // 指定名称映射
private String toUserName;
// 发送方账号(一个OpenID)
@XmlElement(name = "FromUserName")
private String fromUserName;
// 消息建立时间 (整型)
@XmlElement(name = "CreateTime")
private Long createTime;
// 消息类型
@XmlElement(name = "MsgType")
private String msgType;
// 消息id,64位整型
@XmlElement(name = "MsgId")
private Long msgId;
// 文本消息内容
@XmlElement(name = "Content")
private String content;
}
复制代码
4、URL接入校验接口,需公网可见或打开内网穿透工具。详细内容参考上一篇文章
@Controller
@RequestMapping("/api/v1/wechat1")
public class WeChatController {
/** * url接入校验 * @param signature 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。 * @param timestamp 时间戳 * @param nonce 随机数 * @param echostr 随机字符串 * @return 若校验成功,原样返回echostr参数内容 */
@GetMapping("/gzh")
@ResponseBody
public String validate(String signature,String timestamp,String nonce,String echostr){
if (!WeChatUtil.checkSignature(signature, timestamp, nonce)) {
WeChatUtil.getLogger().info("WeChatController.validate -- 公众号接入失败");
return null;
}
WeChatUtil.getLogger().info("WeChatController.validate -- 公众号接入成功,echostr:{}"+echostr);
return echostr;
}
}
复制代码
测试号管理配置如图:
5、接收消息接口(路径与接入验证URL的一致)
/** * 公众号消息处理 * @param inMsg 客户端输入的消息信息 * @return 服务端返回信息 */
@PostMapping("gzh")
@ResponseBody
public Object handleMessage(@RequestBody InMsgEntity inMsg) {
return null;
}
复制代码
6、断点调试
微信在测试公众号(已订阅)发送文本消息
查看断点信息,能够看到接收到文本消息的字段信息
放行断点,能够看到接收消息时的重试机制
参考技术文档,这里选择【被动回复消息】
7、封装【回复文本消息】的实体类
@Data
@XmlRootElement(name="xml")
@XmlAccessorType(XmlAccessType.FIELD)
public class MsgReplyEntity {
// 用户的OpenID
private String ToUserName;
// 测试号的微信号
private String FromUserName;
// 消息建立时间 (整型)
private Long CreateTime;
// 消息类型
private String MsgType;
// 文本消息内容
private String Content;
}
复制代码
8、完善消息处理接口的方法
@PostMapping("gzh")
@ResponseBody
public Object handleMessage(@RequestBody MsgSendEntity msgSend) {
// 服务端消息回复的实体类
MsgReplyEntity msgReply = new MsgReplyEntity();
// 根据接收的信息回复,接收和发送方相反
msgReply.setFromUserName(msgSend.getToUserName());
msgReply.setToUserName(msgSend.getFromUserName());
msgReply.setCreateTime(new Date().getTime());
msgReply.setMsgType(msgSend.getMsgType());
// 消息内容原样返回
msgReply.setContent(msgSend.getContent());
return msgReply;
}
复制代码
1、客户端发送消息测试
ok,公众号的简单被动文本消息回复就完成了。固然,其余的消息类型也相似处理,只需简单的判断便可。