您的位置:首页 > 移动开发 > 微信开发

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

2017-07-08 11:09 537 查看
温馨提示:

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

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

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

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

 

 

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

 

/**
* 处理微信服务器发来的消息
*/
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, 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

 

封装消息处理工具:

import
java.io.InputStream;import java.io.Writer;import
java.util.HashMap;import java.util.List;import
java.util.Map;import javax.servlet.http.HttpServletRequest;import
org.dom4j.Document;import org.dom4j.Element;import
org.dom4j.io.SAXReader;import com.souvc.weixin.message.resp.Article;import
com.souvc.weixin.message.resp.ImageMessage;import
com.souvc.weixin.message.resp.MusicMessage;import
com.souvc.weixin.message.resp.NewsMessage;import
com.souvc.weixin.message.resp.TextMessage;import
com.souvc.weixin.message.resp.VideoMessage;import
com.souvc.weixin.message.resp.VoiceMessage;import
com.thoughtworks.xstream.XStream;import
com.thoughtworks.xstream.core.util.QuickWriter;import
com.thoughtworks.xstream.io.HierarchicalStreamWriter;import
com.thoughtworks.xstream.io.xml.PrettyPrintWriter;import
com.thoughtworks.xstream.io.xml.XppDriver;/*** 类名: MessageUtil </br>* 描述: 消息处理工具类</br>* 开发人员: souvc </br>* 创建时间: 2015-9-30 </br>* 发布版本:V1.0
</br> */public
class MessageUtil {
// 请求消息类型:文本
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_VOICE = "voice";
// 请求消息类型:视频
public
static
final String REQ_MESSAGE_TYPE_VIDEO = "video";
// 请求消息类型:小视频
public
static
final String REQ_MESSAGE_TYPE_SHORTVIDEO
= "shortvideo"; // 请求消息类型:地理位置
public
static
final String REQ_MESSAGE_TYPE_LOCATION =
"location"; // 请求消息类型:链接
public
static
final String REQ_MESSAGE_TYPE_LINK = "link";
// 请求消息类型:事件推送
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";
// 事件类型:scan(用户已关注时的扫描带参数二维码)
public
static
final String EVENT_TYPE_SCAN = "scan";
// 事件类型:LOCATION(上报地理位置)
public
static
final String EVENT_TYPE_LOCATION = "LOCATION";
// 事件类型:CLICK(自定义菜单)
public
static
final String EVENT_TYPE_CLICK = "CLICK";
// 响应消息类型:文本
public
static
final String RESP_MESSAGE_TYPE_TEXT = "text";
// 响应消息类型:图片
public
static
final String RESP_MESSAGE_TYPE_IMAGE = "image";
// 响应消息类型:语音
public
static
final String RESP_MESSAGE_TYPE_VOICE = "voice";
// 响应消息类型:视频
public
static
final String RESP_MESSAGE_TYPE_VIDEO = "video";
// 响应消息类型:音乐
public
static
final String RESP_MESSAGE_TYPE_MUSIC = "music";
// 响应消息类型:图文
public
static
final String RESP_MESSAGE_TYPE_NEWS = "news";
/** * 解析微信发来的请求(XML) * *
@param request *
@return Map<String,
String> * @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; }
/** * 扩展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, clazz); }
protected
void writeText(QuickWriter writer, String
text) { if (cdata) { writer.write("<![CDATA[");
writer.write(text); writer.write("]]>"); } else
{ writer.write(text); } } }; } }); /** * 文本消息对象转换成xml * *
@param textMessage
文本消息对象 * @return
xml */
public
static String messageToXml(TextMessage textMessage)
{ xstream.alias("xml", textMessage.getClass()); return
xstream.toXML(textMessage); } /** * 图片消息对象转换成xml * *
@param imageMessage
图片消息对象 * @return
xml */
public
static String messageToXml(ImageMessage imageMessage)
{ xstream.alias("xml", imageMessage.getClass()); return
xstream.toXML(imageMessage); } /** * 语音消息对象转换成xml * *
@param voiceMessage
语音消息对象 * @return
xml */
public
static String messageToXml(VoiceMessage voiceMessage)
{ xstream.alias("xml", voiceMessage.getClass()); return
xstream.toXML(voiceMessage); } /** * 视频消息对象转换成xml * *
@param videoMessage
视频消息对象 * @return
xml */
public
static String messageToXml(VideoMessage videoMessage)
{ xstream.alias("xml", videoMessage.getClass()); return
xstream.toXML(videoMessage); } /** * 音乐消息对象转换成xml * *
@param musicMessage
音乐消息对象 * @return
xml */
public
static String messageToXml(MusicMessage musicMessage)
{ xstream.alias("xml", musicMessage.getClass()); return
xstream.toXML(musicMessage); } /** * 图文消息对象转换成xml * *
@param newsMessage
图文消息对象 * @return
xml */
public
static String messageToXml(NewsMessage newsMessage)
{ xstream.alias("xml", newsMessage.getClass()); xstream.alias("item", new
Article().getClass()); return xstream.toXML(newsMessage);
}}

 

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

 


import
java.io.IOException;import java.io.PrintWriter;import
javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import
javax.servlet.http.HttpServletRequest;import
javax.servlet.http.HttpServletResponse;import
com.souvc.weixin.service.CoreService;import
com.souvc.weixin.util.SignUtil;/** * 类名: CoreServlet </br> * 描述: 来接收微信服务器传来信息 </br> * 开发人员: souvc</br> * 创建时间:2015-9-29 </br> * 发布版本:V1.0
</br> */public
class CoreServlet
extends HttpServlet {
private
static
final
long serialVersionUID = 4323197796926899691L;
/** * 确认请求来自微信服务器 */
public
void doGet(HttpServletRequest request, HttpServletResponse
response) throws ServletException, 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;
} /** * 处理微信服务器发来的消息 */
public
void doPost(HttpServletRequest request, HttpServletResponse
response) throws ServletException, 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类完成消息的处理:

 


 
import
java.util.Date;import java.util.Map;import
javax.servlet.http.HttpServletRequest;import
com.souvc.weixin.message.resp.TextMessage;import
com.souvc.weixin.util.MessageUtil;/*** 类名: CoreService </br>* 描述: 核心服务类 </br>* 开发人员: souvc </br>* 创建时间: 2015-9-30 </br>* 发布版本:V1.0 </br> */public
class CoreService {
/** * 处理微信发来的请求 *
@param request *
@return xml */
public
static String 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 = new TextMessage();
textMessage.setToUserName(fromUserName); textMessage.setFromUserName(toUserName); textMessage.setCreateTime(new
Date().getTime()); textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT);
// 文本消息
if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT))
{ respContent = "您发送的是文本消息!"; } // 图片消息
else
if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_IMAGE))
{ respContent = "您发送的是图片消息!"; } // 语音消息
else
if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VOICE))
{ respContent = "您发送的是语音消息!"; } // 视频消息
else
if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VIDEO))
{ respContent = "您发送的是视频消息!"; } // 视频消息
else
if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_SHORTVIDEO))
{ respContent = "您发送的是小视频消息!"; } // 地理位置消息
else
if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LOCATION))
{ respContent = "您发送的是地理位置消息!"; } // 链接消息
else
if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LINK))
{ respContent = "您发送的是链接消息!"; } // 事件推送
else
if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT))
{ // 事件类型 String eventType = requestMap.get("Event");
// 关注
if (eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE))
{ respContent = "谢谢您的关注!"; } // 取消关注
else
if (eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE))
{ // TODO 取消订阅后用户不会再收到公众账号发送的消息,因此不需要回复
} // 扫描带参数二维码
else
if (eventType.equals(MessageUtil.EVENT_TYPE_SCAN))
{ // TODO 处理扫描带参数二维码事件 }
// 上报地理位置
else
if (eventType.equals(MessageUtil.EVENT_TYPE_LOCATION))
{ // TODO 处理上报地理位置事件 }
// 自定义菜单
else
if (eventType.equals(MessageUtil.EVENT_TYPE_CLICK))
{ // TODO 处理菜单点击事件 } }
// 设置文本消息的内容 textMessage.setContent(respContent);
// 将文本消息对象转换成xml respXml = MessageUtil.messageToXml(textMessage);
} catch (Exception e) { e.printStackTrace();
} return respXml; }}

 

 

 

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

 

效果如下:

 



 

 



---------------------------------------------------------------------------------------------------------------------------------------- 
如果您认为本教程质量不错,读后觉得收获很大,预期工资能蹭蹭蹭的往上涨,那么不妨小额赞助我一下,让我有动力继续写出高质量的教程。 
---------------------------------------------------------------------------------------------------------------------------------------- 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐