(Java)微信之个人公众账号开发(二)——接收并处理用户消息 (中)
来源:互联网 发布:网络硬盘服务器软件 编辑:程序博客网 时间:2024/06/06 00:19
我们继续来看MessageUtil(消息解析工具类)的完整代码:
/** * 消息工具类 * * @author liufeng * @date 2013-05-19 */public class MessageUtil { // 返回消息类型:文本 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 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_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"; /** * 解析微信发来的请求(XML) * @param request * @return * @throws Exception */ @SuppressWarnings("unchecked") public static Map<String, String> parseXml(HttpServletRequest request) throws Exception { // 将解析结果存储在HashMap中 Map<String, String> map = new HashMap<String, String>(); // 从request中取得输入流 InputStream inputStream = request.getInputStream(); // 读取输入流 SAXReader reader = new SAXReader(); Document document = reader.read(inputStream); // 得到xml根元素 Element root = document.getRootElement(); // 得到根元素的所有子节点 List<Element> elementList = root.elements(); // 遍历所有子节点 for (Element e : elementList) map.put(e.getName(), e.getText()); // 释放资源 inputStream.close(); inputStream = null; return map; } //文本消息对象转换成xml public static String textMessageToXml(TextMessage textMessage) { xstream.alias("xml", textMessage.getClass()); return xstream.toXML(textMessage); } //音乐消息对象转换成xml public static String musicMessageToXml(MusicMessage musicMessage) { xstream.alias("xml", musicMessage.getClass()); return xstream.toXML(musicMessage); } // 图文消息对象转换成xml public static String newsMessageToXml(NewsMessage newsMessage) { xstream.alias("xml", newsMessage.getClass()); xstream.alias("item", new Article().getClass()); return xstream.toXML(newsMessage); }
//扩展xstream,使其支持CDATA块 private static XStream xstream = new XStream(new XppDriver() { public HierarchicalStreamWriter createWriter(Writer out) { return new PrettyPrintWriter(out) { // 对所有xml节点的转换都增加CDATA标记 boolean cdata = true; @SuppressWarnings("unchecked") public void startNode(String name, Class clazz) { super.startNode(name); } protected void writeText(QuickWriter writer, String text) { if (cdata) { writer.write("<![CDATA["); writer.write(text); writer.write("]]>"); } else { writer.write(text); } } }; } }); /** * 判断是否是QQ表情 * @param content * @return */ public static boolean isQqFace(String content) { boolean result = false; // 判断QQ表情的正则表达式 String qqfaceRegex = "/::\\)|/::~|/::B|/::\\||/:8-\\)|/::<|/::$|/::X|/::Z|/::'\\(|/::-\\||/::@|/::P|/::D|/::O|/::\\(|/::\\+|/:--b|/::Q|/::T|/:,@P|/:,@-D|/::d|/:,@o|/::g|/:\\|-\\)|/::!|/::L|/::>|/::,@|/:,@f|/::-S|/:\\?|/:,@x|/:,@@|/::8|/:,@!|/:!!!|/:xx|/:bye|/:wipe|/:dig|/:handclap|/:&-\\(|/:B-\\)|/:<@|/:@>|/::-O|/:>-\\||/:P-\\(|/::'\\||/:X-\\)|/::\\*|/:@x|/:8\\*|/:pd|/:<W>|/:beer|/:basketb|/:oo|/:coffee|/:eat|/:pig|/:rose|/:fade|/:showlove|/:heart|/:break|/:cake|/:li|/:bome|/:kn|/:footb|/:ladybug|/:shit|/:moon|/:sun|/:gift|/:hug|/:strong|/:weak|/:share|/:v|/:@\\)|/:jj|/:@@|/:bad|/:lvu|/:no|/:ok|/:love|/:<L>|/:jump|/:shake|/:<O>|/:circle|/:kotow|/:turn|/:skip|/:oY|/:#-0|/:hiphot|/:kiss|/:<&|/:&>"; Pattern p = Pattern.compile(qqfaceRegex); Matcher m = p.matcher(content); if (m.matches()) { result = true; } return result; } /** * 计算采用utf-8编码方式时字符串所占字节数 * @param content * @return */ public static int getByteSize(String content) { int size = 0; if (null != content) { try { // 汉字采用utf-8编码时占3个字节 size = content.getBytes("utf-8").length; } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } return size; } }
大家可以看到,它其实就是根据用户发来的信息,自定义的一些回复内容,以达到简单的人机交互目的,再回过头来看BylService:
这一步,Map<String,String> requestMap = MessageUtil.parseXml(request);,通过MessageUtil.parseXml将请求数据解析后数据放进map,然后就尅通过map去一一获得各参数值,默认回复的消息是文本类型,如上图,通过requestMap.get("MsgType");,可以得到请求消息类型,通过requestMap.get("Content");可以得到消息内容,接下来就是判断请求消息类型:
// 文本消息 if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) { //DisposeMsgUtil是对文本消息的处理工具类 textMessage.setContent(DisposeMsgUtil.disposeMsg(content)); textMessage.setContent(respContent); respMessage = MessageUtil.textMessageToXml(textMessage); }
如果是文本消息则执行里面的程序,通过DisposeMsgUtil.disposeMsg(content)获得返回内容,然后通过textMessage.setContent,封装回复消息内容,比如:
用户输入"你好",那么requestMap.get("MsgType")就等于"text",那么if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT))成立,则执行里面对应的程序,通过DisposeMsgUtil.disposeMsg(content),将返回字符串"ipastor很好,谢谢您的关心"+"/微笑",然后通过MessageUtil.textMessageToXml(textMessage)处理后转换为xml格式,回复给用户,如图:
当然,当消息类型为其他类型时,大家可以根据实际情况做相应的处理。上图中的表情符我直接用"/微笑"返回就可以了,因为表情符传输过来时,其实转换成了文本类型,每个表情符都对应相应的代码,在DisposeMsgUtil中有如下判断:
if(MessageUtil.isQqFace(content)){repMsg=content;}
而MessageUtil中的isQqFace方法就是判断用户是否发来的是表情,代码如下:
/** * 判断是否是QQ表情 * @param content * @return */ public static boolean isQqFace(String content) { boolean result = false; // 判断QQ表情的正则表达式 String qqfaceRegex = "/::\\)|/::~|/::B|/::\\||/:8-\\)|/::<|/::$|/::X|/::Z|/::'\\(|/::-\\||/::@|/::P|/::D|/::O|/::\\(|/::\\+|/:--b|/::Q|/::T|/:,@P|/:,@-D|/::d|/:,@o|/::g|/:\\|-\\)|/::!|/::L|/::>|/::,@|/:,@f|/::-S|/:\\?|/:,@x|/:,@@|/::8|/:,@!|/:!!!|/:xx|/:bye|/:wipe|/:dig|/:handclap|/:&-\\(|/:B-\\)|/:<@|/:@>|/::-O|/:>-\\||/:P-\\(|/::'\\||/:X-\\)|/::\\*|/:@x|/:8\\*|/:pd|/:<W>|/:beer|/:basketb|/:oo|/:coffee|/:eat|/:pig|/:rose|/:fade|/:showlove|/:heart|/:break|/:cake|/:li|/:bome|/:kn|/:footb|/:ladybug|/:shit|/:moon|/:sun|/:gift|/:hug|/:strong|/:weak|/:share|/:v|/:@\\)|/:jj|/:@@|/:bad|/:lvu|/:no|/:ok|/:love|/:<L>|/:jump|/:shake|/:<O>|/:circle|/:kotow|/:turn|/:skip|/:oY|/:#-0|/:hiphot|/:kiss|/:<&|/:&>"; Pattern p = Pattern.compile(qqfaceRegex); Matcher m = p.matcher(content); if (m.matches()) { result = true; } return result; }
当用户输入表情时,ipastor(我的个人公众账号)会返回相同的表情:
当然根据不同的消息类型,大家可以做相应的处理,这篇文章就先讲到这里。
- (Java)微信之个人公众账号开发(二)——接收并处理用户消息 (中)
- (Java)微信之个人公众账号开发(二)——接收并处理用户消息(上)
- (Java)微信之个人公众账号开发(二)——接收并处理用户消息(下)
- 3、微信公众号开发之接收用户消息
- (Java)微信之个人公众账号开发(一)——进入开发者模式
- Java微信公众平台开发(二)——微信服务器post消息体的接收
- PHP-微信公众平台开发-接收用户输入消息类型并响应
- dotNet微信公众号开发二:接收并回复普通文字消息
- 微信公众号开发手册<一>——接收消息的处理
- 公众号接收用户消息—《微信公众平台开发实战与应用案例》—陈小龙
- 微信公众平台 java示例 接收消息并回复
- 微信公众号开发模式之用户账号绑定
- 微信公众号开发之接收普通消息
- 微信公众号开发之接收普通消息
- 微信公众平台开发【接收消息】接收普通消息
- 微信公众号三方平台开发【代微信公众号接收消息事件并响应】
- 微信测试号开发之三 接收处理消息并响应
- java微信公众号开发总结(2)——文本消息处理
- WINDOWS下VIM配置
- BroadcastReceiver
- 数据结构--线段树--lazy延迟操作
- java判断字符串是否是数字
- html按钮需要规范填写
- (Java)微信之个人公众账号开发(二)——接收并处理用户消息 (中)
- 利用GDI+基于WIN32实现桌面雪花效果(一)
- Hardcoded string,should use @string resource警告 && eclipse中一次性导入用到的类 && 重命名多处调用的对象
- Python装饰器学习笔记
- hdu 1242 Rescue 解题报告
- HDU 1226 搜索
- hdu 1829 A Bug's Life
- hdu1002
- 字符设备驱动之led灯的控制实验