【项目实战】微信公众号关注、取关触发回复功能

一、实际需求

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

二、开发文档

      我们是基于微信的第三方平台来做二次开发,开发的依据必须是官方的API也就是开发文档。所以,我们要先查询开发文档来找到关注和取关事件说明。访问url为:https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_event_pushes.html如图:

 由此可知,我们的公众号服务接收到微信服务器回传的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交互格式来封装自己的类和方法,在此基础上增加业务逻辑来实现符合自己的需求实现。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值