微信公众号开发系列三:响应关注和取关事件

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/bifengmiaozhuan/article/details/78796701

一、实际需求      

       当我们关注某些微信公众号的时候,有的公众号会给我们回复一条文本信息。本节内容,我们就来实现如何在用户关注公众号后,由公众号给用户回复一条文本信息。同样在用户取消关注时,也可以给用户发送一条信息。

二、开发文档

      我们是基于微信的第三方平台来做二次开发,开发的依据必须是官方的API也就是开发文档。所以,我们要先查询开发文档来找到关注和取关事件说明。访问url为:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140454。如图:


      由此可知,我们的公众号服务接收到微信服务器回传的xml信息,从中获取MsgType和Event的值,可以区分出用户的关注和取消关注的行为,对不同的行为程序可以做出不同的响应。

三、编码实现

1、引入相关jar包:dom4j-1.6.1.jar、servlet-api-2.5.jar、xstream-1.3.1.jar用来处理xml文件。

2、根据开发文档中的xml内容,创建消息对象基础类BaseMessage:

/*
 * 消息体基础类
 */
public class BaseMessage {
	private String ToUserName;
	private String FromUserName;
	private long CreateTime;
	private String MsgType;
	public String getToUserName() {
		return ToUserName;
	}
	public void setToUserName(String toUserName) {
		ToUserName = toUserName;
	}
	public String getFromUserName() {
		return FromUserName;
	}
	public void setFromUserName(String fromUserName) {
		FromUserName = fromUserName;
	}
	public long getCreateTime() {
		return CreateTime;
	}
	public void setCreateTime(long createTime) {
		CreateTime = createTime;
	}
	public String getMsgType() {
		return MsgType;
	}
	public void setMsgType(String msgType) {
		MsgType = msgType;
	}
}
3、创建文本消息类TextMessage继承消息基础类:

/*
 * 文本消息类
 */
public class TextMessage extends BaseMessage{
	private String Content;
	private String MsgId;	
	public String getContent() {
		return Content;
	}
	public void setContent(String content) {
		Content = content;
	}
	public String getMsgId() {
		return MsgId;
	}
	public void setMsgId(String msgId) {
		MsgId = msgId;
	}
	
}
4、创建处理xml的工具类XmlUtil:

/*
 * xml处理工具类
 */
public class XmlUtil {
	/*
	 * xml转map
	 */
	public static Map<String, String> xmlToMap(HttpServletRequest request) throws IOException, DocumentException{
		HashMap<String, String> map = new HashMap<String,String>();
		SAXReader reader = new SAXReader();

		InputStream ins = request.getInputStream();
		Document doc = reader.read(ins);

		Element root = doc.getRootElement();
		@SuppressWarnings("unchecked")
		List<Element> list = (List<Element>)root.elements();

		for(Element e:list){
			map.put(e.getName(), e.getText());
		}
		ins.close();
		return map;
	}
	/*
	 * 文本消息对象转xml
	 */
	public static String textMsgToxml(TextMessage textMessage){
		XStream xstream = new XStream();
		xstream.alias("xml", textMessage.getClass());
		return xstream.toXML(textMessage);
	}
}
5、创建消息处理类MessageUtil:

/*
 * 消息处理工具类
 */
public class MessageUtil {
	public static final String MSGTYPE_EVENT = "event";//消息类型--事件
	public static final String MESSAGE_SUBSCIBE = "subscribe";//消息事件类型--订阅事件
	public static final String MESSAGE_UNSUBSCIBE = "unsubscribe";//消息事件类型--取消订阅事件
	public static final String MESSAGE_TEXT = "text";//消息类型--文本消息
	
	/*
	 * 组装文本消息
	 */
	public static String textMsg(String toUserName,String fromUserName,String content){
		TextMessage text = new TextMessage();
		text.setFromUserName(toUserName);
		text.setToUserName(fromUserName);
		text.setMsgType(MESSAGE_TEXT);
		text.setCreateTime(new Date().getTime());
		text.setContent(content);
		return XmlUtil.textMsgToxml(text);
	}
	
	/*
	 * 响应订阅事件--回复文本消息
	 */
	public static String subscribeForText(String toUserName,String fromUserName){
		return textMsg(toUserName, fromUserName, "欢迎关注,精彩内容不容错过!!!");
	}
	
	/*
	 * 响应取消订阅事件
	 */
	public static String unsubscribe(String toUserName,String fromUserName){
		//TODO 可以进行取关后的其他后续业务处理
		System.out.println("用户:"+ fromUserName +"取消关注~");
		return "";
	}
}
6、在WeixinServlet类中新增doPost方法,用来响应微信用户发来的操作请求:

        /*
	 * 响应post请求,微信中消息和菜单交互都是采用post请求
	 */
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException{
		req.setCharacterEncoding("UTF-8");
		resp.setCharacterEncoding("UTF-8");
		PrintWriter out = resp.getWriter();
		String message = "success";
		try {
			//把微信返回的xml信息转义成map
			Map<String, String> map = XmlUtil.xmlToMap(req);
			String fromUserName = map.get("FromUserName");//消息来源用户标识
			String toUserName = map.get("ToUserName");//消息目的用户标识
			String msgType = map.get("MsgType");//消息类型
			String content = map.get("Content");//消息内容
			
			String eventType = map.get("Event");
			if(MessageUtil.MSGTYPE_EVENT.equals(msgType)){//如果为事件类型
				if(MessageUtil.MESSAGE_SUBSCIBE.equals(eventType)){//处理订阅事件
					message = MessageUtil.subscribeForText(toUserName, fromUserName);
				}else if(MessageUtil.MESSAGE_UNSUBSCIBE.equals(eventType)){//处理取消订阅事件
					message = MessageUtil.unsubscribe(toUserName, fromUserName);
				}
			}
		} catch (DocumentException e) {
			e.printStackTrace();
		}finally{
			out.println(message);
			if(out!=null){
				out.close();
			}
		}
	}

7、代码结构图:


四、本节小结

       通过以上操作,我们在新增加一个功能的时候,首先要查看官方开发文档,依据其xml交互格式来封装自己的类和方法,在此基础上增加业务逻辑来实现符合自己的需求实现。

五、相关链接

源码地址:https://github.com/bifengmiaozhuan/weixinService

更多学习讨论, 请加入

官方爬虫、nlp技术qq群:320349384 

天亮教育官方群:318971238,

hadoop & spark & hive技术群:297585251, 

官网:myhope365.com

官方天亮论坛:http://bbs.myhope365.com/ 

天亮教育视频链接http://pan.baidu.com/s/1jIxI4IU 密码:zqa7

欢迎关注天亮教育公众号:




展开阅读全文

没有更多推荐了,返回首页