站内搜索

微信开发之处理微信客户端发来的消息

在上一篇微信开发的博文中微信开发(01)之如何成为开发者,我们开启了微信开发者模式,本篇博文我们简单的处理微信关注者发给我们公众号的消息。

在开启微信开发者模式时,我们配置了一个URL地址,当我们提交开启微信开发者模式,腾讯的微信服务器会向该URL地址发送一个get请求,并且携带一些参数,让我们来验证。说到get请求,就必须说到post请求,关注我们公众号的微信粉丝发来的消息,触发的事件,腾讯的微信服务器则会像该URL地址发送一个post请求,请求的内容就是以xml文档形式的字符串。

所以该URL地址的get请求的处理方法,专门用于开启微信开发者模式;而post请求则用于处理微信粉丝发给我们的消息,或者触发的事件,所以我们后面的微信开发工作的起点就是该URL地址的post处理方法。

下面我们处理一个最简单的例子:粉丝发送任意一个文本信息给我们,我们给他回复一个消息:“你好,+ 他微信的openId”

下面直接贴代码:

URL对应的处理servlet:

public class CoreServlet extends HttpServlet {	private static final long serialVersionUID = 4440739483644821986L;	/**	 * 请求校验(确认请求来自微信服务器)	 */	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();		// 请求校验,若校验成功则原样返回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 signature = request.getParameter("signature");		String timestamp = request.getParameter("timestamp");		String nonce = request.getParameter("nonce");		PrintWriter out = response.getWriter();		// 请求校验		if (SignUtil.checkSignature(signature, timestamp, nonce)) {			Message msgObj = XMLUtil.getMessageObject(request);	// 读取微信客户端发来的消息(xml字符串),并将其转换为消息对象			if(msgObj != null){				String xml = "<xml>" +						 "<ToUserName><![CDATA[" + msgObj.getFromUserName() + "]]></ToUserName>" +	// 接收方帐号(收到的OpenID)						 "<FromUserName><![CDATA[" + msgObj.getToUserName() + "]]></FromUserName>" +	// 开发者微信号						 "<CreateTime>12345678</CreateTime>" +						 "<MsgType><![CDATA[text]]></MsgType>" +						 "<Content><![CDATA[你好,"+ msgObj.getFromUserName() +"]]></Content>" +						 "</xml>";				out.write(xml);	// 回复微信客户端的消息(xml字符串)				out.close();				return;			}		}		out.write("");		out.close();	}}

xml字符串的处理工具类,实现xml消息到消息对象的转换:

public class XMLUtil {	/**	 * 从request中读取用户发给公众号的消息内容	 * @param request	 * @return 用户发给公众号的消息内容	 * @throws IOException	 */	public static String readRequestContent(HttpServletRequest request) throws IOException	{		// 从输入流读取返回内容		InputStream inputStream = request.getInputStream();		InputStreamReader inputStreamReader = new InputStreamReader(inputStream, "utf-8");		BufferedReader bufferedReader = new BufferedReader(inputStreamReader);		String str = null;		StringBuilder buffer = new StringBuilder();				while ((str = bufferedReader.readLine()) != null) {			buffer.append(str);		}				// 释放资源		bufferedReader.close();		inputStreamReader.close();		inputStream.close();				return buffer.toString();	}		/**	 * 将xml文档的内容转换成map	 * @param xmlDoc	 * @return map	 */	public static Map<String, String> xmlToMap(String xmlDoc)	{		//创建一个新的字符串        StringReader read = new StringReader(xmlDoc);        //创建新的输入源SAX 解析器将使用 InputSource 对象来确定如何读取 XML 输入        InputSource source = new InputSource(read);        //创建一个新的SAXBuilder        SAXBuilder sb = new SAXBuilder();                Map<String, String> xmlMap = new HashMap<String, String>();        try {            Document doc = sb.build(source);	//通过输入源构造一个Document            Element root = doc.getRootElement();	//取的根元素                        List<Element> cNodes = root.getChildren();	//得到根元素所有子元素的集合(根元素的子节点,不包括孙子节点)            Element et = null;            for(int i=0;i<cNodes.size();i++){                et = (Element) cNodes.get(i);	//循环依次得到子元素                xmlMap.put(et.getName(), et.getText());            }        } catch (JDOMException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        }        return xmlMap;	}		/**	 * 将保存xml内容的map转换成对象	 * @param map	 * @return	 */	public static Message getMessageObject(Map<String, String> map)	{		if(map != null){			String MsgType = map.get("MsgType");						// 消息类型(文本消息:text, 图片消息:image, 语音消息:voice, 视频消息:video, 			// 地理位置消息:location, 链接消息:link)			if("text".equals(MsgType)){				TextMessage msg = new TextMessage();				XMLUtil.initCommonMsg(msg, map);								msg.setContent(map.get("Content"));				return msg;			}			if("ImageMessage".equals(MsgType)){				ImageMessage msg = new ImageMessage();				XMLUtil.initCommonMsg(msg, map);								msg.setPicUrl(map.get("PicUrl"));				msg.setMediaId(map.get("MediaId"));				return msg;			}			if("video".equals(MsgType)){				VideoMessage msg = new VideoMessage();				XMLUtil.initCommonMsg(msg, map);								msg.setMediaId(map.get("MediaId"));				msg.setThumbMediaId(map.get("ThumbMediaId"));				return msg;			}			if("voice".equals(MsgType)){				VoiceMessage msg = new VoiceMessage();				XMLUtil.initCommonMsg(msg, map);								msg.setMediaId(map.get("MediaId"));				msg.setFormat(map.get("Format"));				return msg;			}			if("location".equals(MsgType)){				LocationMessage msg = new LocationMessage();				msg.setLocation_X(map.get("Location_X"));				msg.setLocation_Y(map.get("Location_Y"));				msg.setScale(map.get("Scale"));				msg.setLabel(map.get("Label"));				return msg;			}			if("link".equals(MsgType)){				LinkMessage msg = new LinkMessage();				XMLUtil.initCommonMsg(msg, map);								msg.setTitle(map.get("Title"));				msg.setDescription(map.get("Description"));				msg.setUrl(map.get("Url"));				return msg;			}		}		return null;	}		/**	 * 将保存xml内容的map转换成对象	 * @param map	 * @return	 * @throws IOException 	 */	public static Message getMessageObject(HttpServletRequest request) throws IOException	{		String xmlDoc = XMLUtil.readRequestContent(request);	// 读取微信客户端发了的消息(xml)		Map<String, String> map = XMLUtil.xmlToMap(xmlDoc);		// 将客户端发来的xml转换成Map		if(map != null){			String MsgType = map.get("MsgType");						// 消息类型(文本消息:text, 图片消息:image, 语音消息:voice, 视频消息:video, 			// 地理位置消息:location, 链接消息:link)			if("text".equals(MsgType)){				TextMessage msg = new TextMessage();				XMLUtil.initCommonMsg(msg, map);								msg.setContent(map.get("Content"));				return msg;			}			/*if("ImageMessage".equals(MsgType)){				ImageMessage msg = new ImageMessage();				XMLUtil.initCommonMsg(msg, map);								msg.setPicUrl(map.get("PicUrl"));				msg.setMediaId(map.get("MediaId"));				return msg;			}			if("video".equals(MsgType)){				VideoMessage msg = new VideoMessage();				XMLUtil.initCommonMsg(msg, map);								msg.setMediaId(map.get("MediaId"));				msg.setThumbMediaId(map.get("ThumbMediaId"));				return msg;			}			if("voice".equals(MsgType)){				VoiceMessage msg = new VoiceMessage();				XMLUtil.initCommonMsg(msg, map);								msg.setMediaId(map.get("MediaId"));				msg.setFormat(map.get("Format"));				return msg;			}			if("location".equals(MsgType)){				LocationMessage msg = new LocationMessage();				msg.setLocation_X(map.get("Location_X"));				msg.setLocation_Y(map.get("Location_Y"));				msg.setScale(map.get("Scale"));				msg.setLabel(map.get("Label"));				return msg;			}			if("link".equals(MsgType)){				LinkMessage msg = new LinkMessage();				XMLUtil.initCommonMsg(msg, map);								msg.setTitle(map.get("Title"));				msg.setDescription(map.get("Description"));				msg.setUrl(map.get("Url"));				return msg;			}*/		}		return null;	}		public static void initCommonMsg(Message msg, Map<String, String> map)	{		msg.setMsgId(map.get("MsgId"));		msg.setMsgType(map.get("MsgType"));		msg.setToUserName(map.get("ToUserName"));		msg.setFromUserName(map.get("FromUserName"));		msg.setCreateTime(map.get("CreateTime"));	}}

粉丝发来的消息分为了6中类型(文本消息, 图片消息, 语音消息, 视频消息, 地理位置消息, 链接消息):

/** * 微信消息基类 * @author yuanfang * @date 2015-03-23 */public class Message {	private String MsgId;	// 消息id,64位整型	private String MsgType;	// 消息类型(文本消息:text, 图片消息:image, 语音消息:voice, 视频消息:video, 地理位置消息:location, 链接消息:link)	private String ToUserName;	//开发者微信号	private String FromUserName; // 发送方帐号(一个OpenID)	private String CreateTime;	// 消息创建时间 (整型)		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 String getCreateTime() {		return CreateTime;	}	public void setCreateTime(String createTime) {		CreateTime = createTime;	}	public String getMsgType() {		return MsgType;	}	public void setMsgType(String msgType) {		MsgType = msgType;	}	public String getMsgId() {		return MsgId;	}	public void setMsgId(String msgId) {		MsgId = msgId;	}	}

文本消息类:

package com.sinaapp.wx.msg;public class TextMessage extends Message {	private String Content;	// 文本消息内容	public String getContent() {		return Content;	}	public void setContent(String content) {		Content = content;	}	}

OK,对粉丝发送给我们公众号的任意的文本消息的最简单处理就完成,我们简单的回复他:你好,然后加上他微信的openId,类似于:你好,orJydljfkg3-r0_dj3rkdfvjl

更多微信开发之处理微信客户端发来的消息相关文章请关注PHP中文网!

  • 上一篇:微信开发之如何成为开发者
  • 下一篇:微信开发之新建按钮时报错 errcode 40054