1. 程式人生 > >微信開發系列(五)_訊息,事件的處理

微信開發系列(五)_訊息,事件的處理

來自微信端的事件可以有多種

1:文字訊息

2:圖片訊息

3:語音訊息

4:點選按鈕事件

5:掃碼事件等等

使用者傳送的訊息或者事件  都是以xml的形式傳送給我們開發者的(也就是伺服器端) 我們也是以xml的格式返回去的

所有首先 我們得把使用者的訊息給獲取並解析了(我給出一個工具類類  )

可以看出就是把傳過來的request直接傳進去就ok了

 public static Map<String,String> xmlToMap(HttpServletRequest request) throws IOException, DocumentException{
	  //用List列表的方式來解析xml,詳細見http://www.jb51.net/article/42323.htm
	  Map<String, String> map =new HashMap<String,String>();  //把客戶端傳過來的xml資料轉換成map格式的資料
	  
	  SAXReader reader =new SAXReader();
	  
	  
	  InputStream ins=request.getInputStream();//從request中獲取輸入流
	  Document doc =reader.read(ins);// 弄成文字???Xml
		
	  Element root =doc.getRootElement();
	  List<Element> list =root.elements();//獲取子節點元素
		//list相當於一個變數,List則是標明是何種變數,這樣來理解
		for(Element e :list){
		   map.put(e.getName(), e.getText());	                 //將遍歷的結果儲存到集合中
		}
	    ins.close();
	    return map;
	  
  }
然後當然就是獲取map裡面的資料了

所以我們得根據他們的型別(是文字 還在圖片 還是點選 ,,)

Map<String ,String> map =BaseMessageUtil.xmlToMap(req);  //把伺服器傳過來的xml格式的資料轉換成map
			String fromUserName =map.get("FromUserName");//傳送方帳號(一個OpenID)
			String toUserName =map.get("ToUserName");//開發者微訊號
			String msgType =map.get("MsgType");//text
			String content =map.get("Content");//文字訊息內容
請注意 圖片的msgtype是image

             文字的msgtype是text

             語音的msgtype是voice

             .....................

但是事件的msgtype都是event (包括點選事件click 關注事件 掃碼事件) 區分他們的唯一標示是 他們的map裡面有一個event欄位 可以將他們區分

獲取 String eventType = map.get("Event");   //事件的型別

好了事件獲取完畢就開始一一回擊吧

剛剛說過 回覆也要包裝成xml返回的

所以製作完回覆訊息後就要轉換成xml了再輸出到微信端【out.print(message);】

訊息的製作就以圖文訊息為例

首先新建一個基本訊息父類

package com.po;

public class BaseMessage {
	private String ToUserName;//微訊號
	 private String FromUserName;//使用者的openID
	 private long CreateTime;//建立時間
	 private String MsgType;//訊息型別
	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;
	}
}
圖文訊息類


一個總圖文(PicNews)訊息裡面可以包含多個圖文訊息(PicNewsMessage)

package com.po;

public class PicNews {
  private String Title;
  private String Description;
  private String PicUrl;
  private String Url;
public String getTitle() {
	return Title;
}
public void setTitle(String title) {
	Title = title;
}
public String getDescription() {
	return Description;
}
public void setDescription(String description) {
	Description = description;
}
public String getPicUrl() {
	return PicUrl;
}
public void setPicUrl(String picUrl) {
	PicUrl = picUrl;
}
public String getUrl() {
	return Url;
}
public void setUrl(String url) {
	Url = url;
}
}
package com.po;

import java.util.List;

public class PicNewsMessage extends BaseMessage{    //圖文訊息的基本設定
    private int ArticleCount;
    private List<PicNews> Articles;//該集合中存放的是PicNews物件,每個物件都代表著一條圖文訊息
	public int getArticleCount() {
		return ArticleCount;
	}
	public void setArticleCount(int articleCount) {
		ArticleCount = articleCount;
	}
	public List<PicNews> getArticles() {
		return Articles;
	}
	public void setArticles(List<PicNews> articles) {
		Articles = articles;
	}
}
返回的時候只要填寫資料就ok了
填寫好了之後就要把PicNewsMessage 物件轉化成xml了
話不多說  轉化的程式碼(這是圖文訊息的轉化)
<pre name="code" class="java">
 public static String PicNewsMessageToXml(PicNewsMessage picNewsMessage){
 //返回一個Xml
 XStream xstream = new XStream();
 xstream.alias("xml", picNewsMessage.getClass());
 xstream.alias("item", new PicNews().getClass());//<articles>下根為<items>
 return xstream.toXML(picNewsMessage);
}

把轉化完的訊息放在message中out一下就到微信端了
再把微信servlet程式碼貼上去
<pre name="code" class="java">package com.servlet;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.SQLException;
import java.util.Date;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.dom4j.DocumentException;

import com.po.TextMessage;
import com.util.CheckUtil;
import com.util.BaseMessageUtil;
import com.util.ImageMessageUtil;
import com.util.MusicMessageUtil;
import com.util.PicNewsMessageUtil;
import com.util.TextMessageUtil;
import com.util.WeixinUtil;
import com.xt.util.UserUtil;

public class WeixinServlet extends HttpServlet {
    
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	@Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
    		throws ServletException, IOException {  //驗證方式為get
    	String signature = req.getParameter("signature");
    	String timestamp = req.getParameter("timestamp");
    	String nonce = req.getParameter("nonce");
    	String echostr = req.getParameter("echostr");
    	
    	PrintWriter out = resp.getWriter();
    	if(CheckUtil.checkSignature(signature, timestamp, nonce)){
    		out.print(echostr);
    	}
    	
    }
     protected void doPost(HttpServletRequest req ,HttpServletResponse resp) throws IOException {
    	 
    	 req.setCharacterEncoding("UTF-8");
    	 resp.setCharacterEncoding("UTF-8");
    	 
    	 /**
    	  * out是輸出字元流,即servlet接受到request請求後,
    	  * servlet使用out來返回結果,不管客戶端是什麼(瀏覽器或者httpclient 或者別的serlvet等等),
    	  * 它都和客戶端建立一個流輸出管道,然後把字元流輸出給請求端。
          */
    	 PrintWriter out =resp.getWriter(); 
		 
		    
    	 try {
			Map<String ,String> map =BaseMessageUtil.xmlToMap(req);  //把伺服器傳過來的xml格式的資料轉換成map
			String fromUserName =map.get("FromUserName");//傳送方帳號(一個OpenID)
			String toUserName =map.get("ToUserName");//開發者微訊號
			String msgType =map.get("MsgType");//text
			String content =map.get("Content");//文字訊息內容
			//String 
			
			//判斷該訊息是否為文字訊息
			String message =null;
			if(BaseMessageUtil.MESSAGE_TEXT.equals(msgType)){  //發過來的時文字訊息時
				if("1".equals(content)){  //回覆文字訊息
					System.out.println(this+"使用者輸入的是1");
//					message = TextMessageUtil.initText(toUserName, fromUserName, TextMessageUtil.firstMenu(fromUserName)); 
					message = PicNewsMessageUtil.initPicNewsMessage(toUserName, fromUserName,12);
				}else if("2".equals(content)){  //回覆圖文訊息
					//message = PicNewsMessageUtil.initPicNewsMessage(toUserName, fromUserName);
					 
				}else if("3".equals(content)){  //回覆圖片訊息
					message = ImageMessageUtil.initImageMessage(toUserName, fromUserName);
				}else if("4".equals(content)){  //回覆音樂訊息
					message = MusicMessageUtil.initMusicMessage(toUserName, fromUserName);
				}
				else if("5".equals(content)){  //回覆文字訊息
					message = TextMessageUtil.initText(toUserName, fromUserName,TextMessageUtil.threeMenu());
				}
				else if("?".equals(content)||"?".equals(content)){ //選單
					message = TextMessageUtil.initText(toUserName, fromUserName, TextMessageUtil.menuText(fromUserName));
				}else if(content.startsWith("翻譯")){
					String word = content.replaceAll("^翻譯", "").trim();
					if("".equals(word)){
						message = TextMessageUtil.initText(toUserName, fromUserName,TextMessageUtil.threeMenu());
					}else{
						//message = TextMessageUtil.initText(toUserName, fromUserName, WeixinUtil.translate(word));//翻譯
					}
				}
				
			/**	   
				   text.setFromUserName(toUserName);
				   text.setToUserName(fromUserName);
				   text.setMsgType("text");
				   text.setCreateTime(new Date().getTime());
				   text.setContent("您傳送的訊息是:"+content);
				   TextMessage text =new TextMessage();
				   message = TextMessageUtil.textMessageToXml(text);
				 
				*/
				
			}else if(BaseMessageUtil.MESSAGE_EVENT.equals(msgType)){  //當發過來的是事件
				
				String eventType = map.get("Event");   //點選事件的型別
				if(BaseMessageUtil.MESSAGE_SUBSCRIBE.equals(eventType)){  //調出主選單
					message = TextMessageUtil.initText(toUserName, fromUserName, TextMessageUtil.menuText(fromUserName));
					UserUtil userUtil=new UserUtil();
					try {
						userUtil.saveUser(fromUserName);//關注的時候往資料庫裡面插入使用者的資訊
					} catch (ClassNotFoundException | SQLException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}else if(BaseMessageUtil.MESSAGE_CLICK.equals(eventType)){  //點選事件時,推送圖文訊息
					int Key = Integer.parseInt(map.get("EventKey"));  //得到按鈕的key值
					message = PicNewsMessageUtil.initPicNewsMessage(toUserName, fromUserName,Key);
					
				}else if(BaseMessageUtil.MESSAGE_VIEW.equals(eventType)){  //連結事件
					System.out.println("你點選了ViewButton");
					message = TextMessageUtil.initText(toUserName, fromUserName, TextMessageUtil.menuText(fromUserName));
//					String url = map.get("EventKey"); 
//					message = TextMessageUtil.initText(toUserName, fromUserName, url);
				}else if(BaseMessageUtil.MESSAGE_SCANCODE.equals(eventType)){  //掃碼事件,推送訊息
					
					String key =map.get("EventKey");
					System.out.println(key);
					//message = TextMessageUtil.initText(toUserName, fromUserName, key);

				}else if(BaseMessageUtil.MESSAGE_LOCATION.equals(eventType)){
					String label = map.get("Label");
					message = TextMessageUtil.initText(toUserName, fromUserName, label);
				}
				else if(BaseMessageUtil.MESSAGE_SCAN.equals(eventType)){
					String scene_id = map.get("EventKey");
					System.out.println(scene_id);
					
				}
				
				
				
				
            }
			
			//System.out.println(message);
			
			out.print(message);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (DocumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    	 finally{
    		 out.close();
    		 
    	 }
	}
}