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

(Java)微信之个人公众账号开发(二)——接收并处理用户消息(上)

2014-03-05 16:55 771 查看
经过上一篇,大家成功进入开发者模式后,主要工作就是我们服务器的后台开发了,这个跟我们平时的web项目没什么两样,主要就是根据微信服务器传过来的消息类型及内容进行判断和处理,然后返回相应信息。而消息的处理则主要在servlet中的POST方法中,get方法主要用来验证消息是否来自微信服务器,而post方法则主要接收用户消息类型和内容进行处理。下面是servlet中的post方法的代码:

/**
* 处理微信服务器发来的消息
*/
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 将请求、响应的编码均设置为UTF-8(防止中文乱码)
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
// 接收消息、处理消息
String respMessage = BylService.processRequest(request);
// 响应消息
PrintWriter out = response.getWriter();
out.print(respMessage);
out.close();
}


其中最主要的便是BylService这个业务类(名字当然是自己定的了),业务类单独写有助于提高程序可读性和美观性。再写这个业务类前,我们有必要先了解下,消息都有那些类型,以及微信服务器发过来的各类型的xml数据包格式。具体情况大家参考微信公众平台开发者文档:http://mp.weixin.qq.com/wiki/index.php



~
在上图中我们看到,消息的几种类型:文本消息,图片消息,语音消息,视频消息,地理位置消息,链接消息,具体参数开发者文档中已经详细说明,需要强调的是,微信服务器发过来的是xml数据包,我们接收到这个数据包(输入流)后需要对其解析并得到里面包含的标签以及对应额参数值,返回的消息同样需要转换为固定的xml格式。具体步骤我们下面再讲,现在先看我们的消息类型,既然用java开发,我们就要知道java的特性——面向对象,所以我们可以把这些消息类型全部封装为对象,并抽取这几个消息类型相同的属性为父类,然后子类继承。具体结构如下图:



下面是requestBean包(接收的消息)中的BaseMessage.java(父类):

public class BaseMessage {
// 开发者微信号
private String ToUserName;
// 发送方帐号(一个OpenID)
private String FromUserName;
// 消息创建时间 (整型)
private long CreateTime;
// 消息类型(text/image/location/link)
private String MsgType;
// 消息id,64位整型
private long MsgId;

public String getToUserName() {
return ToUserName;
}

public void setToUserName(String toUserName) {
ToUserName = toUserName;
}

public String getFromUserName() {
return FromUserName;
}

public void setFromUserName(String fromUserName) {
FromUserName = fromUserName;
}

public long getCreateTime() {
return CreateTime;
}

public void setCreateTime(long createTime) {
CreateTime = createTime;
}

public String getMsgType() {
return MsgType;
}

public void setMsgType(String msgType) {
MsgType = msgType;
}

public long getMsgId() {
return MsgId;
}

public void setMsgId(long msgId) {
MsgId = msgId;
}

}

requestBean包中的TextMessage.java(文本消息类):

public class TextMessage extends BaseMessage{
// 消息内容
private String Content;

public String getContent() {
return Content;
}

public void setContent(String content) {
Content = content;
}
}

下面是responseBean包(回复的消息)中的BaseMessage.java(父类):

public class BaseMessage {
// 接收方帐号(收到的OpenID)
private String ToUserName;
// 开发者微信号
private String FromUserName;
// 消息创建时间 (整型)
private long CreateTime;
// 消息类型(text/music/news)
private String MsgType;
// 位0x0001被标志时,星标刚收到的消息
private int FuncFlag;

public String getToUserName() {
return ToUserName;
}

public void setToUserName(String toUserName) {
ToUserName = toUserName;
}

public String getFromUserName() {
return FromUserName;
}

public void setFromUserName(String fromUserName) {
FromUserName = fromUserName;
}

public long getCreateTime() {
return CreateTime;
}

public void setCreateTime(long createTime) {
CreateTime = createTime;
}

public String getMsgType() {
return MsgType;
}

public void setMsgType(String msgType) {
MsgType = msgType;
}

public int getFuncFlag() {
return FuncFlag;
}

public void setFuncFlag(int funcFlag) {
FuncFlag = funcFlag;
}
}

responseBean包中的TextMessage.java(文本消息类):

public class TextMessage extends BaseMessage {
// 回复的消息内容
private String Content;

public String getContent() {
return Content;
}

public void setContent(String content) {
Content = content;
}

现只举文本消息为例,其他类型类似,大家可以根据开发者文档中每种类型的参数进行封装,好,下面我们就来看具体的业务类BylService:

public class BylService {
/**
* 处理微信发来的请求
* @param request
* @return
*/
public static String processRequest(HttpServletRequest request) {
String respMessage = null;
// 默认返回的文本消息内容
String respContent = "请求处理异常,请稍候尝试!";
try {
// xml请求解析
Map<String, String> requestMap = MessageUtil.parseXml(request);
// 发送方帐号(open_id)
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);
textMessage.setFuncFlag(0);

String content = requestMap.get("Content");

// 文本消息
if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) {
//DisposeMsgUtil是对文本消息的处理工具类
textMessage.setContent(DisposeMsgUtil.disposeMsg(content));

textMessage.setContent(respContent);
respMessage = MessageUtil.textMessageToXml(textMessage);
}else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_IMAGE)) {// 图片消息
respContent = "您发送的是图片消息!";
textMessage.setContent(respContent);
respMessage = MessageUtil.textMessageToXml(textMessage);
}else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LOCATION)) {// 地理位置消息
respContent = "您发送的是地理位置消息!";
textMessage.setContent(respContent);
respMessage = MessageUtil.textMessageToXml(textMessage);
}else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_LINK)) {// 链接消息
respContent = "您发送的是链接消息!";
textMessage.setContent(respContent);
respMessage = MessageUtil.textMessageToXml(textMessage);
}else if (msgType.equals(MessageUtil.RESP_MESSAGE_TYPE_MUSIC)) {// 音频消息
respContent = "您发送的是音频消息!";
textMessage.setContent(respContent);
respMessage = MessageUtil.textMessageToXml(textMessage);
}else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_VOICE)) {// 音频消息
respContent = "您发送的是音频消息!";
textMessage.setContent(respContent);
respMessage = MessageUtil.textMessageToXml(textMessage);
}else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)) {// 事件推送
String eventType = requestMap.get("Event");// 事件类型
if (eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) {// 订阅
//当用户点击关注时,会立即发送该条消息
respContent = "欢迎关注ipastor生活小助手"+"/微笑";
textMessage.setContent(respContent);
respMessage = MessageUtil.textMessageToXml(textMessage);
}else if (eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)) {// 取消订阅
// 取消订阅后点击事件
}else if (eventType.equals(MessageUtil.EVENT_TYPE_CLICK)) {// 自定义菜单点击事件
// 自定义菜单权点击事件
}
}

} catch (Exception e) {
e.printStackTrace();
}
return respMessage;
}

}


我们先看消息处理工具类: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";


判断消息类型时便可根据是否与MessageUtil.xxx相同来判断消息类型,并做出相应处理。

MessageUtil对xml数据包的具体处理方法,以及文本消息处理类DisposeMsgUtil将在下一篇文章中继续讲解。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐