微信公共平台开发(二):回复文本消息

转载请注明出处:http://blog.csdn.net/xiaojimanman/article/details/45044051

http://www.llwjy.com/blogdetail/6c8ff7985249e119b6b683f9a65d6597.html

个人博客站已经上线了,网址 www.llwjy.com ~欢迎各位吐槽~
-------------------------------------------------------------------------------------------------

      在上一篇博客中,我们已经介绍了微信服务器的配置,这篇我们就介绍以下如何针对微信公共号做开发。由于自己现在的微信公共号是个人的,所以现在只能做一些简单的被动回复,等几天公司的公共号到手再开始其他功能的介绍。

      在上一篇博客中,在WeiXinServlet类中实现了对服务器时效性的验证,验证通过之后,这些代码就可以不用了,为了之后切换微信公共号,建议只注释掉即可。


接收消息

      在服务器接收到请求之后,解析request提交过来的xml,获取相关信息,代码实现如下:

private HashMap<String, String> parseRequestXml(HttpServletRequest request) throws Exception{
  // 将解析结果存储在HashMap中  
	HashMap<String, String> map = new HashMap<String, String>();  
	Document document = XmlUtil.createFromRequest(request);
    // 得到xml根元素  
    Element root = document.getRootElement();  
    // 得到根元素的所有子节点  
    List<Element> elementList = root.elements();  
  
    // 遍历所有子节点  
    for (Element e : elementList){
        map.put(e.getName(), e.getText());
    }
    return map;  
} 
      在map中,我们通过map.get("MsgType")可以获取到用户发送消息类型(具体xml结构,参照开发者文档中的接收消息--接收普通消息),对于不同的消息类型,选择不同的分支,当然这里就先对关注事件和文本消息做响应,其他的部分在之后的文档中介绍。根据消息类型不同选择不同的分支,代码实现如下:

public String reply(HttpServletRequest request) {
	try {
		HashMap<String, String> map = parseRequestXml(request);
		if (map == null) {
			return "";
		}
		String type = map.get("MsgType");
		if ("text".equals(type)){
			return textMessage(map);
		} else if ("event".equals(type)) {
			return subscribeMessage(map);
		}else {
			return "";
		}
	} catch (Exception e) {
		e.printStackTrace();
		return "";
	}
}


应答消息

      自己也是刚刚开始微信开发,对于微信消息的数据结构了解也不是太多,所以自己就先设计如下的消息结构来封装需要回复的消息内容,Message基类:

 /**  
 *@Description:  微信消息类型  
 */ 
package com.lulei.weixin.model;  

public class Message {
	private String toUser;
	private String fromUser;
	
	public String getToUser() {
		return toUser;
	}
	public void setToUser(String toUser) {
		this.toUser = toUser;
	}
	public String getFromUser() {
		return fromUser;
	}
	public void setFromUser(String fromUser) {
		this.fromUser = fromUser;
	}
}
      回复文本消息TextMessage:

 /**  
 *@Description:  文本消息
 */ 
package com.lulei.weixin.model;  
  
public class TextMessage extends Message{
	private String content;
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
}
      接口返回的内容是xml格式的字符串,因此我们需要把javabean转化为固定格式的字符串,所以创建ReplyMessage类,用来转化各种类型的消息,代码实现如下:

 /**  
 *@Description:   微信返回消息模版
 */ 
package com.lulei.weixin.model;  

import java.util.Date;
  
public class ReplyMessage {
	//文本消息模版
	private static String  textMessageModel = "<xml><ToUserName><![CDATA[_toUser_]]></ToUserName><FromUserName><![CDATA[_fromUser_]]></FromUserName><CreateTime>_time_</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[_content_]]></Content></xml>";
	private static String messageNull = "";
	
	/**
	 * @param message
	 * @return
	 * @Author:lulei  
	 * @Description: 创建文本消息
	 */
	public static String creatTextMessage(TextMessage message){
		if (message == null) {
			return messageNull;
		}
		return textMessageModel.replaceAll("_toUser_", message.getToUser())
				.replaceAll("_fromUser_", message.getFromUser())
				.replace("_content_", message.getContent())
				.replace("time_", new Date().getTime()+"");
	}
}

      结合接收消息部分,我们就可以完成WeiXinService类来完成相关的业务逻辑,代码如下:

 /**  
 *@Description:  微信业务层
 */ 
package com.lulei.weixin.service;  

import java.io.IOException;
import java.util.HashMap;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.httpclient.HttpException;
import org.dom4j.Document;
import org.dom4j.Element;

import com.lulei.crawl.baixiaodu.BaiduRobot;
import com.lulei.util.XmlUtil;
import com.lulei.weixin.model.ReplyMessage;
import com.lulei.weixin.model.TextMessage;


public class WeiXinService {
	@SuppressWarnings("unchecked")
	private HashMap<String, String> parseRequestXml(HttpServletRequest request) throws Exception{
		// 将解析结果存储在HashMap中  
		HashMap<String, String> map = new HashMap<String, String>();  
		Document document = XmlUtil.createFromRequest(request);
		// 得到xml根元素  
		Element root = document.getRootElement();  
		// 得到根元素的所有子节点  
		List<Element> elementList = root.elements();  
		
		// 遍历所有子节点  
		for (Element e : elementList){
			map.put(e.getName(), e.getText());
		}
		return map;  
	} 
	
	/**
	 * @param request
	 * @return
	 * @Author:lulei  
	 * @Description: 应答
	 */
	public String reply(HttpServletRequest request) {
		try {
			HashMap<String, String> map = parseRequestXml(request);
			if (map == null) {
				return "";
			}
			String type = map.get("MsgType");
			if ("text".equals(type)){
				return textMessage(map);
			} else if ("event".equals(type)) {
				return subscribeMessage(map);
			}else {
				return "";
			}
		} catch (Exception e) {
			e.printStackTrace();
			return "";
		}
	}
	
	/**
	 * @return
	 * @throws HttpException
	 * @throws IOException
	 * @Author:lulei  
	 * @Description: 应答文本信息
	 */
	private String textMessage(HashMap<String, String> mes) throws HttpException, IOException{
		TextMessage message = new TextMessage();
		message.setFromUser(mes.get("ToUserName"));
		message.setToUser(mes.get("FromUserName"));
		message.setContent(new BaiduRobot(mes.get("Content")).getAnswer());
		return ReplyMessage.creatTextMessage(message);
	}
	
	/**
	 * @param mes
	 * @return
	 * @throws HttpException
	 * @throws IOException
	 * @Author:lulei  
	 * @Description: 事件应答
	 */
	private String subscribeMessage(HashMap<String, String> mes) throws HttpException, IOException{
		TextMessage message = new TextMessage();
		message.setFromUser(mes.get("ToUserName"));
		message.setToUser(mes.get("FromUserName"));
		if ("subscribe".equals(mes.get("Event"))) { //关注应答
			message.setContent("欢迎关注小鸡慢慢~\n回复内容可以和我聊天呦~\n回复“笑话”给您说个笑话~\n更过内容等待您挖掘~");
		} else {
			message.setContent("未知事件");
		}
		return ReplyMessage.creatTextMessage(message);
	}

}
      最后一步只需要在上一篇博客中的WeiXinServlet类中添加一个属性,如下:

private static WeiXinService weixin = new WeiXinService();
      将parseString方法做如下修改即可:

protected String parseString(HttpServletRequest request) {
	//微信首次验证
	//return check(request);
	//微信应答
	return weixin.reply(request);
}

百小度机器人

      在上面的代码中,提到了一个百小度机器人的数据采集,对于百小度的介绍可以自行百度,目前这个机器人好像只是小范围测试,自己有幸在测试范围内,所以就对他的接口做了下应用。百小度的信息采集BaiduRobot类还是基于之前介绍的CrawBase类,具体如何模拟分析可以参照之前的相关博客,这里给出具体的实现的源代码:

 /**  
 *@Description:     
 */ 
package com.lulei.crawl.baixiaodu;  

import java.io.IOException;
import java.util.HashMap;

import org.apache.commons.httpclient.HttpException;

import com.lulei.crawl.CrawlBase;
import com.lulei.util.DoRegex;
  
  
/**  
 *@Description:  
 *@Author:lulei  
 *@Version:1.1.0  
 */
public class BaiduRobot extends CrawlBase {
	private static HashMap<String, String> params;
	private static String answerRegex = "answer\\\\\":\\\\\"(.*?)\\\\\",";
	private static String urlModel = "https://sp0.baidu.com/yLsHczq6KgQFm2e88IuM_a/s?sample_name=bear_brain&request_query=%text%&bear_type=2&request_time=1428543613075&callback=jQuery110204140488877892494_1428543517759&_=1428543517773";
	static {
		params = new HashMap<String, String>();
		params.put("Host", "www.baidu.com");
		params.put("Referer", "https://www.baidu.com");
		params.put("User-Agent", "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36");
		params.put("cookie", "这里是cookie内容,为了个人帐号安全,这里就省略了");
	}
	
	public BaiduRobot(String key) throws HttpException, IOException {
		String url = urlModel.replaceAll("%text%", key);
		super.readPageByGet(url, "utf-8", params);
	}
	
	public String getAnswer(){
		return DoRegex.getFirstString(getPageSourceCode(), answerRegex, 1);
	}
	
	public static void main(String[] args) throws HttpException, IOException {
		// TODO Auto-generated method stub  
		System.out.println(new BaiduRobot("我怀孕了,怎么办").getPageSourceCode());
	}

}

运行结果

      这些开发完成之后,在我们的微信公共号中做下测试,效果图如下:

微信公共平台开发(二):回复文本消息


联想

      在上述的文本类型的消息中,我们可以对用户发的文本信息做一下简单的过滤,即满足一定的要求,走我们自己的业务逻辑,否则走百小度的聊天接口,这样就可以完成更多的功能:比如业务推广、信息查询等等。


微信公共平台开发(二):回复文本消息

上一篇:iscroll


下一篇:教你用FLASH画天天连萌中的绿小兔