第四篇:微信公众平台开发实战Java版之完成消息接受与相应以及消息的处理

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

温馨提示:

这篇文章是依赖前几篇的文章的。

第一篇:微信公众平台开发实战之了解微信公众平台基础知识以及资料准备

第二篇 :微信公众平台开发实战之开启开发者模式,接入微信公众平台开发

第三篇 :微信公众平台开发实战之请求消息,响应消息以及事件消息类的封装

首先,我们看看原来写的dopost方法:

/*** 处理微信服务器发来的消息*/publicvoiddoPost(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {//TODO 消息的接收、处理、响应

}

doPost方法有两个参数:

1.request中封装了请求相关的所有内容,可以从request中取出微信服务器发来的消息;

2.response我们可以对接收到的消息进行响应,即发送消息。

一、解析微信服务器传来的消息

因为微信服务器发送过来的是xml格式的消息,所以我们可以采用开源框架dom4j去解析xml 。

所用到的jar 包是:dom4j-1.6.1.jar

官网下载地址:http://www.dom4j.org/dom4j-1.6.1/

网盘下载地址:http://yunpan.cn/cQyR8KkIXxHXn 访问密码 0f2e

二、将响应消息转换成xml返回给微信服务器

如何将响应消息转换成xml返回的问题,这里我们将 采用开源框架xstream来实现java类到xml的转换

所用到的jar包为:xstream-1.3.1.jar

网盘下载地址:http://yunpan.cn/cQyBU2vTYAe2f 访问密码 ad36

封装消息处理工具:

packagecom.souvc.weixin.util;importjava.io.InputStream;importjava.io.Writer;importjava.util.HashMap;importjava.util.List;importjava.util.Map;importjavax.servlet.http.HttpServletRequest;importorg.dom4j.Document;importorg.dom4j.Element;importorg.dom4j.io.SAXReader;importcom.souvc.weixin.message.resp.Article;importcom.souvc.weixin.message.resp.ImageMessage;importcom.souvc.weixin.message.resp.MusicMessage;importcom.souvc.weixin.message.resp.NewsMessage;importcom.souvc.weixin.message.resp.TextMessage;importcom.souvc.weixin.message.resp.VideoMessage;importcom.souvc.weixin.message.resp.VoiceMessage;importcom.thoughtworks.xstream.XStream;importcom.thoughtworks.xstream.core.util.QuickWriter;importcom.thoughtworks.xstream.io.HierarchicalStreamWriter;importcom.thoughtworks.xstream.io.xml.PRettyPrintWriter;importcom.thoughtworks.xstream.io.xml.XppDriver;/*** 类名: MessageUtil </br>

* 描述: 消息处理工具类</br>

* 开发人员: souvc </br>

* 创建时间: 2015-9-30 </br>

* 发布版本:V1.0 </br>*/publicclassMessageUtil {//请求消息类型:文本publicstaticfinalString REQ_MESSAGE_TYPE_TEXT = "text";//请求消息类型:图片publicstaticfinalString REQ_MESSAGE_TYPE_IMAGE = "image";//请求消息类型:语音publicstaticfinalString REQ_MESSAGE_TYPE_VOICE = "voice";//请求消息类型:视频publicstaticfinalString REQ_MESSAGE_TYPE_VIDEO = "video";//请求消息类型:小视频publicstaticfinalString REQ_MESSAGE_TYPE_SHORTVIDEO = "shortvideo";//请求消息类型:地理位置publicstaticfinalString REQ_MESSAGE_TYPE_LOCATION = "location";//请求消息类型:链接publicstaticfinalString REQ_MESSAGE_TYPE_LINK = "link";//请求消息类型:事件推送publicstaticfinalString REQ_MESSAGE_TYPE_EVENT = "event";//事件类型:subscribe(订阅)publicstaticfinalString EVENT_TYPE_SUBSCRIBE = "subscribe";//事件类型:unsubscribe(取消订阅)publicstaticfinalString EVENT_TYPE_UNSUBSCRIBE = "unsubscribe";//事件类型:scan(用户已关注时的扫描带参数二维码)publicstaticfinalString EVENT_TYPE_SCAN = "scan";//事件类型:LOCATION(上报地理位置)publicstaticfinalString EVENT_TYPE_LOCATION = "LOCATION";//事件类型:CLICK(自定义菜单)publicstaticfinalString EVENT_TYPE_CLICK = "CLICK";//响应消息类型:文本publicstaticfinalString RESP_MESSAGE_TYPE_TEXT = "text";//响应消息类型:图片publicstaticfinalString RESP_MESSAGE_TYPE_IMAGE = "image";//响应消息类型:语音publicstaticfinalString RESP_MESSAGE_TYPE_VOICE = "voice";//响应消息类型:视频publicstaticfinalString RESP_MESSAGE_TYPE_VIDEO = "video";//响应消息类型:音乐publicstaticfinalString RESP_MESSAGE_TYPE_MUSIC = "music";//响应消息类型:图文publicstaticfinalString RESP_MESSAGE_TYPE_NEWS = "news";/*** 解析微信发来的请求(XML)

*

*@paramrequest

*@returnMap<String, String>

*@throwsException*/@SuppressWarnings("unchecked")publicstaticMap<String, String> parseXml(HttpServletRequest request)throwsException {//将解析结果存储在HashMap中Map<String, String> map =newHashMap<String, String>();//从request中取得输入流InputStream inputStream =request.getInputStream();//读取输入流SAXReader reader =newSAXReader();

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;returnmap;

}/*** 扩展xstream使其支持CDATA*/privatestaticXStream xstream =newXStream(newXppDriver() {publicHierarchicalStreamWriter createWriter(Writer out) {returnnewPrettyPrintWriter(out) {//对所有xml节点的转换都增加CDATA标记booleancdata =true;

@SuppressWarnings("unchecked")publicvoidstartNode(String name, Class clazz) {super.startNode(name, clazz);

}protectedvoidwriteText(QuickWriter writer, String text) {if(cdata) {

writer.write("<![CDATA[");

writer.write(text);

writer.write("]]>");

}else{

writer.write(text);

}

}

};

}

});/*** 文本消息对象转换成xml

*

*@paramtextMessage 文本消息对象

*@returnxml*/publicstaticString messageToXml(TextMessage textMessage) {

xstream.alias("xml", textMessage.getClass());returnxstream.toXML(textMessage);

}/*** 图片消息对象转换成xml

*

*@paramimageMessage 图片消息对象

*@returnxml*/publicstaticString messageToXml(ImageMessage imageMessage) {

xstream.alias("xml", imageMessage.getClass());returnxstream.toXML(imageMessage);

}/*** 语音消息对象转换成xml

*

*@paramvoiceMessage 语音消息对象

*@returnxml*/publicstaticString messageToXml(VoiceMessage voiceMessage) {

xstream.alias("xml", voiceMessage.getClass());returnxstream.toXML(voiceMessage);

}/*** 视频消息对象转换成xml

*

*@paramvideoMessage 视频消息对象

*@returnxml*/publicstaticString messageToXml(VideoMessage videoMessage) {

xstream.alias("xml", videoMessage.getClass());returnxstream.toXML(videoMessage);

}/*** 音乐消息对象转换成xml

*

*@parammusicMessage 音乐消息对象

*@returnxml*/publicstaticString messageToXml(MusicMessage musicMessage) {

xstream.alias("xml", musicMessage.getClass());returnxstream.toXML(musicMessage);

}/*** 图文消息对象转换成xml

*

*@paramnewsMessage 图文消息对象

*@returnxml*/publicstaticString messageToXml(NewsMessage newsMessage) {

xstream.alias("xml", newsMessage.getClass());

xstream.alias("item",newArticle().getClass());returnxstream.toXML(newsMessage);

}

}

使用CoreServlet 类完成消息的接受与响应:

packagecom.souvc.weixin.servlet;importjava.io.IOException;importjava.io.PrintWriter;importjavax.servlet.ServletException;importjavax.servlet.http.HttpServlet;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importcom.souvc.weixin.service.CoreService;importcom.souvc.weixin.util.SignUtil;/*** 类名: CoreServlet </br>

* 描述: 来接收微信服务器传来信息 </br>

* 开发人员: souvc</br>

* 创建时间:2015-9-29 </br>

* 发布版本:V1.0 </br>*/publicclassCoreServletextendsHttpServlet {privatestaticfinallongserialVersionUID = 4323197796926899691L;/*** 确认请求来自微信服务器*/publicvoiddoGet(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {//微信加密签名String signature = request.getParameter("signature");//时间戳String timestamp = request.getParameter("timestamp");//随机数String nonce = request.getParameter("nonce");//随机字符串String echostr = request.getParameter("echostr");

PrintWriter out=response.getWriter();//通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败if(SignUtil.checkSignature(signature, timestamp, nonce)) {

out.print(echostr);

}

out.close();

out=null;

}/*** 处理微信服务器发来的消息*/publicvoiddoPost(HttpServletRequest request, HttpServletResponse response)throwsServletException, IOException {//消息的接收、处理、响应//将请求、响应的编码均设置为UTF-8(防止中文乱码)request.setCharacterEncoding("UTF-8");

response.setCharacterEncoding("UTF-8");//调用核心业务类接收消息、处理消息String respXml =CoreService.processRequest(request);//响应消息PrintWriter out =response.getWriter();

out.print(respXml);

out.close();

}

}

使用CoreService类完成消息的处理:

packagecom.souvc.weixin.service;importjava.util.Date;importjava.util.Map;importjavax.servlet.http.HttpServletRequest;importcom.souvc.weixin.message.resp.TextMessage;importcom.souvc.weixin.util.MessageUtil;/*** 类名: CoreService </br>

* 描述: 核心服务类 </br>

* 开发人员: souvc </br>

* 创建时间: 2015-9-30 </br>

* 发布版本:V1.0 </br>*/publicclassCoreService {/*** 处理微信发来的请求

*@paramrequest

*@returnxml*/publicstaticString processRequest(HttpServletRequest request) {//xml格式的消息数据String respXml =null;//默认返回的文本消息内容String respContent = "未知的消息类型!";try{//调用parseXml方法解析请求消息Map<String, String> requestMap =MessageUtil.parseXml(request);//发送方帐号String fromUserName = requestMap.get("FromUserName");//开发者微信号String toUserName = requestMap.get("ToUserName");//消息类型String msgType = requestMap.get("MsgType");//回复文本消息TextMessage textMessage =newTextMessage();

textMessage.setToUserName(fromUserName);

textMessage.setFromUserName(toUserName);

textMessage.setCreateTime(newDate().getTime());

textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);//文本消息if(msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) {

respContent= "您发送的是文本消息!";

}//图片消息elseif(msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_IMAGE)) {

respContent= "您发送的是图片消息!";

}//语音消息elseif(msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VOICE)) {

respContent= "您发送的是语音消息!";

}//视频消息elseif(msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VIDEO)) {

respContent= "您发送的是视频消息!";

}//视频消息elseif(msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_SHORTVIDEO)) {

respContent= "您发送的是小视频消息!";

}//地理位置消息elseif(msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LOCATION)) {

respContent= "您发送的是地理位置消息!";

}//链接消息elseif(msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LINK)) {

respContent= "您发送的是链接消息!";

}//事件推送elseif(msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)) {//事件类型String eventType = requestMap.get("Event");//关注if(eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) {

respContent= "谢谢您的关注!";

}//取消关注elseif(eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)) {//TODO 取消订阅后用户不会再收到公众账号发送的消息,因此不需要回复}//扫描带参数二维码elseif(eventType.equals(MessageUtil.EVENT_TYPE_SCAN)) {//TODO 处理扫描带参数二维码事件}//上报地理位置elseif(eventType.equals(MessageUtil.EVENT_TYPE_LOCATION)) {//TODO 处理上报地理位置事件}//自定义菜单elseif(eventType.equals(MessageUtil.EVENT_TYPE_CLICK)) {//TODO 处理菜单点击事件}

}//设置文本消息的内容textMessage.setContent(respContent);//将文本消息对象转换成xmlrespXml =MessageUtil.messageToXml(textMessage);

}catch(Exception e) {

e.printStackTrace();

}returnrespXml;

}

}

然后部署到我们的BAE上面,体验一下。(部署方法请参照 第二篇 :微信公众平台开发实战之开启开发者模式,接入微信公众平台开发)。

效果如下:

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航