zoukankan      html  css  js  c++  java
  • 微信开发(02)之处理微信客户端发来的消息

    在上一篇微信开发的博文中微信开发(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

  • 相关阅读:
    CentOS7 下部署 Iptables 环境纪录(关闭默认的firewalle)
    Linux系统下root密码遗忘等系统故障的修复方法
    LDAP学习笔记总结
    kvm虚拟化关闭虚拟网卡virbr0的方法
    Gradle使用指南
    Android 注解工具 ButterKnife
    Sublime Text + CTags + Cscope (部分替代Source Insight)
    win + linux + android 多任务分屏
    Ubuntu16.04 安装openjdk-7-jdk
    eclipse + Android Studio 集成 Genymotion 模拟器
  • 原文地址:https://www.cnblogs.com/digdeep/p/4361382.html
Copyright © 2011-2022 走看看