Spring Boot 如何给微信公众号返回消息

文本消息在前面消息的基础上多了一个 Content 属性,因此文本消息继承自 BaseMessage ,再额外添加一个 Content 属性即可。

其他的消息类型也是类似的定义,我就不一一列举了,至于其他消息的格式,大家可以参考微信开放文档(http://1t.click/aPXK)。

返回消息生成


消息类型的 Bean 定义完成之后,接下来就是将实体类生成 XML。

首先我们定义一个消息工具类,将常见的消息类型枚举出来:

/**

  • 返回消息类型:文本

*/

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 RESP_MESSAGE_TYPE_Image = “image”;

/**

  • 返回消息类型:语音

*/

public static final String RESP_MESSAGE_TYPE_Voice = “voice”;

/**

  • 返回消息类型:视频

*/

public static final String RESP_MESSAGE_TYPE_Video = “video”;

/**

  • 请求消息类型:文本

*/

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_VIDEO = “video”;

/**

  • 请求消息类型:推送

*/

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”;

/**

  • 事件类型:VIEW(自定义菜单 URl 视图)

*/

public static final String EVENT_TYPE_VIEW = “VIEW”;

/**

  • 事件类型:LOCATION(上报地理位置事件)

*/

public static final String EVENT_TYPE_LOCATION = “LOCATION”;

/**

  • 事件类型:LOCATION(上报地理位置事件)

*/

public static final String EVENT_TYPE_SCAN = “SCAN”;

大家注意这里消息类型的定义,以 RESP 开头的表示返回的消息类型,以 REQ 表示微信服务器发来的消息类型。然后在这个工具类中再定义两个方法,用来将返回的对象转换成 XML:

public static String textMessageToXml(TextMessage textMessage) {

xstream.alias(“xml”, textMessage.getClass());

return xstream.toXML(textMessage);

}

private static XStream xstream = new XStream(new XppDriver() {

public HierarchicalStreamWriter createWriter(Writer out) {

return new PrettyPrintWriter(out) {

boolean cdata = true;

@SuppressWarnings(“rawtypes”)

public void startNode(String name, Class clazz) {

super.startNode(name, clazz);

}

protected void writeText(QuickWriter writer, String text) {

if (cdata) {

writer.write(“<![CDATA[”);

writer.write(text);

writer.write(“]]>”);

} else {

writer.write(text);

}

}

};

}

});

textMessageToXML 方法用来将 TextMessage 对象转成 XML 返回给微信服务器,类似的方法我们还需要定义 imageMessageToXml、voiceMessageToXml 等,不过定义的方式都基本类似,我就不一一列出来了。

返回消息分发


由于用户发来的消息可能存在多种情况,我们需要分类进行处理,这个就涉及到返回消息的分发问题。因此我在这里再定义一个返回消息分发的工具类,如下:

public class MessageDispatcher {

public static String processMessage(Map<String, String> map) {

String openid = map.get(“FromUserName”); //用户 openid

String mpid = map.get(“ToUserName”); //公众号原始 ID

if (map.get(“MsgType”).equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) {

//普通文本消息

TextMessage txtmsg = new TextMessage();

txtmsg.setToUserName(openid);

txtmsg.setFromUserName(mpid);

txtmsg.setCreateTime(new Date().getTime());

txtmsg.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);

txtmsg.setContent(“这是返回消息”);

return MessageUtil.textMessageToXml(txtmsg);

}

return null;

}

public String processEvent(Map<String, String> map) {

//在这里处理事件

}

}

这里我们还可以多加几个 elseif 去判断不同的消息类型,我这里因为只有普通文本消息,所以一个 if 就够用了。

在这里返回值我写死了,实际上这里需要根据微信服务端传来的 Content 去数据中查询,将查询结果返回,数据库查询这一套相信大家都能搞定,我这里就不重复介绍了。

最后在消息接收 Controller 中调用该方法,如下:

@PostMapping(value = “/verify_wx_token”,produces = “application/xml;charset=utf-8”)

public String handler(HttpServletRequest request, HttpServletResponse response) throws Exception {

request.setCharacterEncoding(“UTF-8”);

Map<String, String> map = MessageUtil.parseXml(request);

String msgType = map.get(“MsgType”);

if (MessageUtil.REQ_MESSAGE_TYPE_EVENT.equals(msgType)) {

return messageDispatcher.processEvent(map);

}else{

return messageDispatcher.processMessage(map);

}

}

在 Controller 中,我们首先判断消息是否是事件,如果是事件,进入到事件处理通道,如果不是事件,则进入到消息处理通道。

注意,这里需要配置一下返回消息的编码,否则可能会出现中文乱码。

如此之后,我们的服务器就可以给公众号返回消息了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值