转载请注明出处: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()); } }
这些开发完成之后,在我们的微信公共号中做下测试,效果图如下:
联想
在上述的文本类型的消息中,我们可以对用户发的文本信息做一下简单的过滤,即满足一定的要求,走我们自己的业务逻辑,否则走百小度的聊天接口,这样就可以完成更多的功能:比如业务推广、信息查询等等。
原文地址:http://blog.csdn.net/xiaojimanman/article/details/45044051