前面完成了服务器的对接,这一篇主要是实现各类消息的接收,并封装成map形式,供后面的使用,以及回复文本消息。
前面介绍的服务器的对接是通过get请求,而微信服务器准发过来用户的信息则是通过post请求,因此我们的方法要在post中实现。
同样,sae在接收微信服务器发过来消息时仍需要验证消息的可靠性,与上一讲中类似,只不过当验证成功后不是返回echostr,而是对
微信服务器发过来的消息进行解析处理。
1 protected void doPost(HttpServletRequest request, HttpServletResponse response) 2 throws ServletException, IOException { 3 request.setCharacterEncoding("UTF-8"); 4 response.setCharacterEncoding("UTF-8"); 5 // 微信加密签名 6 String signature = request.getParameter("signature"); 7 // 时间戳 8 String timestamp = request.getParameter("timestamp"); 9 // 随机数 10 String nonce = request.getParameter("nonce"); 11 if (SignUtil.checkSignature(signature, timestamp, nonce)) { 12 // 调用核心业务类接收消息、处理消息 13 String respMessage = null; 14 try { 15 respMessage = processReqest.process(request,response); 16 } catch (Exception e) { 17 e.printStackTrace(); 18 } 19 PrintWriter out = response.getWriter(); 20 out.print(respMessage); 21 out.close(); 22 } 23 }
用户发过来的消息主要有1 文本消息2 图片消息3 语音消息4 视频消息5小视频消息6 地理位置消息7 链接消息。我们从request中拿到微信服务器发过来
的数据,由于发过来的是xml格式的数据(具体的形式,可以查看微信公众平台开发者文档),解析xml方法有很多,这里我们用Dom4j进
行xml的解析,并将解析的结果封装在map集合中。
1 //从request中拿到xml并封装在map中 2 public class RequestXML2Map { 3 public static Map parseXml(HttpServletRequest request) throws Exception { 4 Map<String, String> map = new HashMap<String, String>(); 5 // 从request中取得输入流 6 StringBuffer sb = new StringBuffer(); 7 InputStream is = request.getInputStream(); 8 InputStreamReader isr = new InputStreamReader(is, "UTF-8"); 9 BufferedReader br = new BufferedReader(isr); 10 String s = ""; 11 while ((s = br.readLine()) != null) { 12 sb.append(s); 13 } 14 String xml = sb.toString(); 15 16 // 读取输入流 17 Document document = null; 18 try { 19 document = DocumentHelper.parseText(xml); 20 } catch (DocumentException e1) { 21 e1.printStackTrace(); 22 } 23 // 得到xml根元素 24 Element root = document.getRootElement(); 25 // 得到根元素的所有子节点 26 List<Element> elementList = root.elements(); 27 // 遍历所有子节点 28 for (Element e : elementList) { 29 // 对于CDATA区域内的内容,XML解析程序不会处理,而是直接原封不动的输出。 30 map.put(e.getName(), e.getText()); 31 } 32 return map; 33 } 34 }
通过上面的过程,我们已经完成了对微信服务器发送过来的数据封装,下面就是根据用户发送过来的消息进行回复,这里主要完成
回复文本消息。我们从之前解析好的map集合中得到用户发过来消息的类型,根据用户发过来消息的类型做出相应的回复,当然这里只
回复基本的文本消息,以后还会完成其他消息的回复。
1 public class processReqest { 2 public static String process(HttpServletRequest request,HttpServletResponse response) throws Exception{ 3 @SuppressWarnings("unchecked") 4 Map<String, String> map = RequestXML2Map.parseXml(request); 5 String result = ""; 6 String msgType = map.get("MsgType"); 7 String respContent = ""; 8 //文本消息 9 if (msgType.equals("text")) { 10 respContent = TulingRobot.robot(map.get("Content")); 11 TextMessage textMessage = Map2Bean.parseText(map,respContent); 12 result = Bean2ResponseXML.textMessageToXml(textMessage); 13 } 14 //图片消息 15 else if (msgType.equals("image")) { 16 respContent = ""; 17 return null; 18 } 19 //声音消息 20 else if (msgType.equals("voice")) { 21 respContent = ""; 22 return null; 23 } 24 //视频消息 25 else if (msgType.equals("video")) { 26 respContent = ""; 27 return null; 28 } 29 //地理位置 30 else if (msgType.equals("location")) { 31 respContent = ""; 32 return null; 33 } 34 //事件类型 35 else if (msgType.equals("event")) { 36 String eventType = map.get("Event"); 37 //订阅 38 if (eventType.equals("subscribe")) { 39 respContent = "欢迎订阅我的公众号!"; 40 TextMessage textMessage = Map2Bean.parseText(map,respContent); 41 result = Bean2ResponseXML.textMessageToXml(textMessage); 42 } 43 //取消订阅 44 else if (eventType.equals("unsubscribe")) { 45 // TODO 46 return null; 47 } 48 //点击菜单 49 else if (eventType.equals("CLICK")) { 50 // TODO 51 return null; 52 } 53 } 54 return result; 55 } 56 }
就此我们已经完成了基本的实现,接收用户发过来的消息并对其进行回复,赶快打开微信试一试吧!