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

经过上一篇,大家成功进入开发者模式后,主要工作就是我们服务器的后台开发了,这个跟我们平时的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将在下一篇文章中继续讲解。



 

 

 

 

 

 

 

 

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

白玉梁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值