本篇以测试号为例,介绍如何接收微信的消息,同时回复消息hello world。
环境
jdk1.8,spring boot2,外网域名,内网穿透。
内网穿透
在开发微信公众号的时候,不仅我们需要调用微信的接口,微信也需要调用我们的接口,给我们发送各种消息。所以我们的项目要部署到互联网上才能接收到微信的消息。然而,在开发调试过程中我们往往处于局域网环境,不可能每改一次代码就部署到外网上去看效果。内网穿透的作用就是穿透我们的局域网,让外网域名直接绑定到我们的局域网电脑。当我们在本机修改代码时,外网可以马上看到效果。
花生壳
实现内网穿透方法有很多,但目前我知道的最简单方便的就是花生壳。我在上面申请了免费域名,并开通了内网穿透功能。配置非常简单,这里不多说了。内网穿透现在好像要6元钱,永久使用。双11有免费优惠,不知道双12还有没有。当解决了域名和内网穿透的问题,以下正式进入微信环节。
测试账号
登录地址 https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
点击登录按钮,然后用你的个人微信扫码即可确认登录。
基本信息
登录以后有很多信息,现在只看接口配置信息
URL:就是微信给我们发消息时,会调用到我们的接口url。这个接口需要我们自己开发并部署到网上,http://xxx.imwork.net是我在花生壳申请的免费域名,handler就是我在spring mvc中配置的Mapping地址,.xml是扩展url,因为微信要求的消息格式是xml。图中是已经配置成功的,新账号需要先开发这个接口的get方法并上线,然后配置URL和Token,提交后微信会用get方法请求这个URL,正确完成请求才算配置成功。
Token:请求URL接口的token,以后再讲,现在可以随便填,自己记得就行。
验证接口
只要将微信发过来的echostr参数返回给他,前面的URL和Token就可以配置成功。如下,这里并没有做验证,也是以后再讲,现在先把hello world走通。
@GetMapping("/handler")
public String handler(@RequestParam Map<String,String> map) {
return map.get("echostr");
当微信用get方法请求上面的handler成功之后,就算对接配置成功了。以后再有正式的业务消息,微信都会用post方法请求handler。比如当用户关注我们的微信号时,微信也会用post发消息给handler,我们下面就给他回复一条消息,hello world!
xml格式消息
微信给我们发送的消息是xml格式,同样我们回复的消息也必须是xml格式。如何接收和响应xml,参考spring boot2 (36)-xml。下面再重复一下必须的相关配置,引入依赖和全局参数
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
</dependency>
spring.mvc.contentnegotiation.favor-path-extension=true
spring.mvc.pathmatch.use-registered-suffix-pattern=true
文本消息参数
微信给我们发的关注消息,和我们回复的hello world消息都是文本消息类型,都有以下5个参数。注意,参数首字母要大写。
@JacksonXmlRootElement(localName = "xml")
public class TextMessage {
@JacksonXmlProperty(localName = "ToUserName")
private String toUserName; //消息接收者
@JacksonXmlProperty(localName = "FromUserName")
private String fromUserName; //消息发送者
@JacksonXmlProperty(localName = "CreateTime")
private long createTime; //当前时间(秒)
@JacksonXmlProperty(localName = "MsgType")
private String msgType; //消息类型
@JacksonXmlProperty(localName = "Content")
private String content; //消息内容
//省略get/set
ToUserName:消息接收者。
FromUserName:消息发送者。
注意:假如是用户触发的消息,FromUserName就是用户id,ToUserName就是我们公众号的id,这两个id都是由微信生成的。而当我们回复消息时,则需要将ToUserName和FromUserName的身份即id互换。
CreateTime:当前时间,在微信中是以秒为单位,即System.currentTimeMillis()/1000。
MsgType:消息类型,文本消息即text。
content:消息内容,即hello world。
post方法响应微信消息
@PostMapping(value="/handler")
public Object handler(@RequestBody Map<String,String> map) throws JsonProcessingException {
TextMessage textMessage = new TextMessage();
textMessage.setToUserName(map.get("FromUserName")); //map是微信发过来的消息参数
textMessage.setFromUserName(map.get("ToUserName"));
textMessage.setCreateTime(System.currentTimeMillis()/1000);
textMessage.setMsgType("text");
textMessage.setContent("hello world");
return textMessage;
关注微信测试账号,回复hello world
测试账号登录页面中间,有一个二维码,扫码即可关注。
关注后进入公众号即会收到一条消息,hello world