1. 程式人生 > >微信公眾號(訊息回覆)

微信公眾號(訊息回覆)

首先申請微信公眾號,獲取到APPID、appsecret之類的就不用細說了吧!

當普通微信使用者向公眾賬號發訊息時,微信伺服器將POST訊息的XML資料包到開發者填寫的URL上。

訊息回覆原理: 使用者輸入Content(資訊)-->後臺接收到資訊,對資訊進行解析,判斷-->將組裝好的內容發生給使用者端顯示

這是後臺伺服器接收到的資訊(自己可在控制檯列印輸出檢視)

{Content=?, CreateTime=1530078502, ToUserName=gh_abb85570b5a7, FromUserName=oPR_X1ZiZXmcSk8RYk8Jw06NAj6Q, MsgType=text, MsgId=6571637126828028609}
引數描述
ToUserName開發者微訊號
FromUserName傳送方帳號(一個OpenID)
CreateTime訊息建立時間 (整型)
MsgTypetext
Content文字訊息內容
MsgId訊息id,64位整型

後臺根據使用者輸入的訊息進行處理,返回訊息給使用者端顯示。

處理後的結果是一串XML資料包,例如:

<xml>
  <ToUserName>oPR_X1ZiZXmcSk8RYk8Jw06NAj6Q</ToUserName>
  <FromUserName>gh_abb85570b5a7</FromUserName>
  <CreateTime>Wed Jun 27 13:48:22 CST 2018</CreateTime>
  <MsgType>text</MsgType>
  <Content>歡迎您的關注,請按照選單提示進行操作:
1.jspgou的簡介
2.jspgou技術概要
3.圖片顯示
4.音樂聆聽
回覆?調出此選單</Content>
</xml>

注意: 訊息回覆操作時,建議將XML資料包列印在控制檯,出現錯誤時,對照微信公眾平臺上的文件上的XML進行對比,對大小寫嚴格區分。

1.建立實體類

package com.wlw.po;

public class AccessToken {
	private String Token;
	private int ExpiresIn;
	public String getToken() {
		return Token;
	}
	public void setToken(String token) {
		this.Token = token;
	}
	public int getExpiresIn() {
		return ExpiresIn;
	}
	public void setExpiresIn(int expiresIn) {
		this.ExpiresIn = expiresIn;
	}
}
package com.wlw.po;

/**
 * 存放公共屬性的類
 * @author ASUS
 *
 */
public class BaseMessage {
	private String ToUserName; // 開發者微訊號
	private String FromUserName; // 傳送方帳號(一個OpenID)
	private String CreateTime; // 訊息建立時間 (整型)
	private String MsgType; // text
	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;
	}
}
圖片訊息的實體類
package com.wlw.po;

public class Image {
	private String MediaId;

	public String getMediaId() {
		return MediaId;
	}

	public void setMediaId(String mediaId) {
		MediaId = mediaId;
	}
}

package com.wlw.po;

public class ImageMessage extends BaseMessage{
	private Image Image;

	public Image getImage() {
		return Image;
	}

	public void setImage(Image image) {
		Image = image;
	}
}
音樂訊息的實體類
package com.wlw.po;

public class Music {
	private String Title;
	private String Description;
	private String MusicUrl;
	private String HQMusicUrl;
	private String ThumbMediaId;

	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 getMusicUrl() {
		return MusicUrl;
	}

	public void setMusicUrl(String musicUrl) {
		MusicUrl = musicUrl;
	}

	public String getHQMusicUrl() {
		return HQMusicUrl;
	}

	public void setHQMusicUrl(String hQMusicUrl) {
		HQMusicUrl = hQMusicUrl;
	}

	public String getThumbMediaId() {
		return ThumbMediaId;
	}

	public void setThumbMediaId(String thumbMediaId) {
		ThumbMediaId = thumbMediaId;
	}

}
package com.wlw.po;

public class MusicMessage extends BaseMessage{
  private Music Music;

public Music getMusic() {
	return Music;
}

public void setMusic(Music Music) {
	this.Music = Music;
}
  
}
圖文訊息實體類
package com.wlw.po;
/**
 * 圖文訊息的裡層
 * @author ASUS
 *
 */
public class News {
  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.wlw.po;

import java.util.List;
/**
 * 圖文訊息的外層
 * @author ASUS
 *
 */
public class NewsMessage extends BaseMessage{

	private int ArticleCount;
	private List<News> Articles;
	
	public int getArticleCount() {
		return ArticleCount;
	}
	public void setArticleCount(int articleCount) {
		ArticleCount = articleCount;
	}
	public List<News> getArticles() {
		return Articles;
	}
	public void setArticles(List<News> articles) {
		Articles = articles;
	}
}
文字訊息
package com.wlw.po;

/**
 * 文字訊息物件的基本屬性
 * 
 * @author ASUS
 *
 */
public class TextMessage extends BaseMessage{
	
	private String Content; // 文字訊息內容
	private String MsgId; // 訊息id,64位整型

	
	public String getContent() {
		return Content;
	}

	public void setContent(String content) {
		Content = content;
	}

	public String getMsgId() {
		return MsgId;
	}

	public void setMsgId(String msgId) {
		MsgId = msgId;
	}
}
這個util類,一般都是相同。的不用記住,參考網上的就行了
package com.wlw.util;

import java.security.MessageDigest;
import java.util.Arrays;

public class CheckUtil {
   private static final String token="******";  //填寫自己的token
   public static boolean checkSignature(String signature,String timestamp,String nonce){
		String[] arr = new String[]{token,timestamp,nonce};
		//排序
		Arrays.sort(arr);
		
		//生成字串
		StringBuffer content = new StringBuffer();
		for(int i=0;i<arr.length;i++){
			content.append(arr[i]);
		}
		
		//sha1加密
		String temp = getSha1(content.toString());
		
		return temp.equals(signature);
	}
	
	/**
	 * Sha1加密方法
	 * @param str
	 * @return
	 */
	public static String getSha1(String str) {
		if (str == null || str.length() == 0) {
			return null;
		}
		char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
				'a', 'b', 'c', 'd', 'e', 'f' };

		try {
			MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
			mdTemp.update(str.getBytes("UTF-8"));

			byte[] md = mdTemp.digest();
			int j = md.length;
			char buf[] = new char[j * 2];
			int k = 0;
			for (int i = 0; i < j; i++) {
				byte byte0 = md[i];
				buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
				buf[k++] = hexDigits[byte0 & 0xf];
			}
			return new String(buf);
		} catch (Exception e) {
			return null;
		}
	}
}
微信工具類
package com.wlw.util;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONObject;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.ParseException;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

import com.wlw.menu.Button;
import com.wlw.menu.ClickButton;
import com.wlw.menu.Menu;
import com.wlw.menu.ViewButton;
import com.wlw.po.AccessToken;



/**
 * 微信工具類
 * @author Stephen
 *
 */
public class WeixinUtil {
	//測試帳號,擁有所有許可權
	private static final String APPID = "******************";  //填寫自己的APPID
	private static final String APPSECRET = "******************";
	
	private static final String ACCESS_TOKEN_URL = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET";
	
	private static final String UPLOAD_URL = "https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE";
	
	private static final String CREATE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN";
	
	private static final String QUERY_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/get?access_token=ACCESS_TOKEN";
	
	private static final String DELETE_MENU_URL = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN";
	/**
	 * get請求
	 * @param url
	 * @return
	 * @throws ParseException
	 * @throws IOException
	 */
	public static JSONObject doGetStr(String url) throws ParseException, IOException{
		DefaultHttpClient client = new DefaultHttpClient();
		HttpGet httpGet = new HttpGet(url);
		JSONObject jsonObject = null;
		HttpResponse httpResponse = client.execute(httpGet);
		HttpEntity entity = httpResponse.getEntity();
		if(entity != null){
			String result = EntityUtils.toString(entity,"UTF-8");
			jsonObject = JSONObject.fromObject(result);
		}
		return jsonObject;
	}
	
	/**
	 * POST請求
	 * @param url
	 * @param outStr
	 * @return
	 * @throws ParseException
	 * @throws IOException
	 */
	public static JSONObject doPostStr(String url,String outStr) throws ParseException, IOException{
		DefaultHttpClient client = new DefaultHttpClient();
		HttpPost httpost = new HttpPost(url);
		JSONObject jsonObject = null;
		httpost.setEntity(new StringEntity(outStr,"UTF-8"));
		HttpResponse response = client.execute(httpost);
		String result = EntityUtils.toString(response.getEntity(),"UTF-8");
		jsonObject = JSONObject.fromObject(result);
		return jsonObject;
	}
	
	/**
	 * 檔案上傳
	 * @param filePath
	 * @param accessToken
	 * @param type
	 * @return
	 * @throws IOException
	 * @throws NoSuchAlgorithmException
	 * @throws NoSuchProviderException
	 * @throws KeyManagementException
	 */
	public static String upload(String filePath, String accessToken,String type) throws IOException, NoSuchAlgorithmException, NoSuchProviderException, KeyManagementException {
		File file = new File(filePath);
		if (!file.exists() || !file.isFile()) {
			throw new IOException("檔案不存在");
		}

		String url = UPLOAD_URL.replace("ACCESS_TOKEN", accessToken).replace("TYPE",type);
		
		URL urlObj = new URL(url);
		//連線
		HttpURLConnection con = (HttpURLConnection) urlObj.openConnection();

		con.setRequestMethod("POST"); 
		con.setDoInput(true);
		con.setDoOutput(true);
		con.setUseCaches(false); 

		//設定請求頭資訊
		con.setRequestProperty("Connection", "Keep-Alive");
		con.setRequestProperty("Charset", "UTF-8");

		//設定邊界
		String BOUNDARY = "----------" + System.currentTimeMillis();
		con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + BOUNDARY);

		StringBuilder sb = new StringBuilder();
		sb.append("--");
		sb.append(BOUNDARY);
		sb.append("\r\n");
		sb.append("Content-Disposition: form-data;name=\"file\";filename=\"" + file.getName() + "\"\r\n");
		sb.append("Content-Type:application/octet-stream\r\n\r\n");

		byte[] head = sb.toString().getBytes("utf-8");

		//獲得輸出流
		OutputStream out = new DataOutputStream(con.getOutputStream());
		//輸出表頭
		out.write(head);

		//檔案正文部分
		//把檔案已流檔案的方式 推入到url中
		DataInputStream in = new DataInputStream(new FileInputStream(file));
		int bytes = 0;
		byte[] bufferOut = new byte[1024];
		while ((bytes = in.read(bufferOut)) != -1) {
			out.write(bufferOut, 0, bytes);
		}
		in.close();

		//結尾部分
		byte[] foot = ("\r\n--" + BOUNDARY + "--\r\n").getBytes("utf-8");//定義最後資料分隔線

		out.write(foot);

		out.flush();
		out.close();

		StringBuffer buffer = new StringBuffer();
		BufferedReader reader = null;
		String result = null;
		try {
			//定義BufferedReader輸入流來讀取URL的響應
			reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
			String line = null;
			while ((line = reader.readLine()) != null) {
				buffer.append(line);
			}
			if (result == null) {
				result = buffer.toString();
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (reader != null) {
				reader.close();
			}
		}

		JSONObject jsonObj = JSONObject.fromObject(result);
		System.out.println(jsonObj);
		String typeName = "media_id";
		if(!"image".equals(type)){
			typeName = type + "_media_id";
		}
		String mediaId = jsonObj.getString(typeName);
		return mediaId;
	}

	/**
	 * 獲取accessToken
	 * @return
	 * @throws ParseException
	 * @throws IOException
	 */
	public static AccessToken getAccessToken() throws ParseException, IOException{
		AccessToken token = new AccessToken();
		String url = ACCESS_TOKEN_URL.replace("APPID", APPID).replace("APPSECRET", APPSECRET);
		JSONObject jsonObject = doGetStr(url);
		if(jsonObject!=null){
			token.setToken(jsonObject.getString("access_token"));
			token.setExpiresIn(jsonObject.getInt("expires_in"));
		}
		return token;
	}
	}

訊息格式轉換和訊息組裝我寫一起了(可能有點亂)。大家也可以進行分離,封裝

package com.wlw.util;
/**
 * 訊息的格式轉換
 * @author ASUS
 * 
 */

import java.io.InputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.http.client.HttpClient;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.thoughtworks.xstream.XStream;
import com.wlw.po.Image;
import com.wlw.po.ImageMessage;
import com.wlw.po.Music;
import com.wlw.po.MusicMessage;
import com.wlw.po.News;
import com.wlw.po.NewsMessage;
import com.wlw.po.TextMessage;

public class MessageUtil {
	public static final String URL="http://eb7f1067.ngrok.io";
	public static final String MESSAGE_TEXT = "text";
	public static final String MESSAGE_NEWS = "news";
	public static final String MESSAGE_IMAGE = "image";
	public static final String MESSAGE_VOICE = "voice";
	public static final String MESSAGE_MUSIC = "music";
	public static final String MESSAGE_VIDEO = "video";
	public static final String MESSAGE_LINK = "link";
	public static final String MESSAGE_LOCATION = "location";
	public static final String MESSAGE_EVNET = "event";
	public static final String MESSAGE_SUBSCRIBE = "subscribe";
	public static final String MESSAGE_UNSUBSCRIBE = "unsubscribe";
	public static final String MESSAGE_CLICK = "CLICK";
	public static final String MESSAGE_VIEW = "VIEW";
	public static final String MESSAGE_SCANCODE = "scancode_push";

	// XML資料轉成Map集合的方法
	public static Map<String, String> xmlToMap(HttpServletRequest request) throws Exception {
		Map<String, String> map = new HashMap<String, String>();
		SAXReader reader = new SAXReader();

		// 從request中獲取輸入流
		InputStream inputStream = request.getInputStream();
		Document document = reader.read(inputStream);
		// 獲取XML的根元素
		Element root = document.getRootElement();
		// 得到根元素的所有節點,放在list集合中
		List<Element> list = root.elements();
		// 遍歷集合
		for (Element e : list) {
			map.put(e.getName(), e.getText());
		}
		System.out.println(map);
		inputStream.close();
		return map;
	}

	/**
	 * 將文字訊息物件轉為XML
	 * 
	 * @param textMessage
	 * @return
	 */
	public static String textMessageToXML(TextMessage textMessage) {
		XStream xstream = new XStream();
		xstream.alias("xml", textMessage.getClass());
		return xstream.toXML(textMessage);
	}

	public static String initText(String toUserName, String fromUserName, String content) {
		TextMessage text = new TextMessage();
		text.setFromUserName(toUserName); // 設定從哪發出(發給誰)
		text.setToUserName(fromUserName);
		text.setMsgType(MESSAGE_TEXT);
		text.setCreateTime(new Date().toString());
		text.setContent(content);
		// 建立物件接受,將文字物件轉換為XML物件
		return textMessageToXML(text);
	}

	/**
	 * 主選單
	 * 
	 * @return
	 */
	public static String menuText() {
		StringBuffer sBuffer = new StringBuffer();
		sBuffer.append("歡迎您的關注,請按照選單提示進行操作:\n\n");
		sBuffer.append("1.jspgou的簡介\n");
		sBuffer.append("2.jspgou技術概要\n\n");
		sBuffer.append("3.圖片\n\n");
		sBuffer.append("回覆?調出此選單");
		return sBuffer.toString();
	}

	/**
	 * 選擇1的時候傳送
	 * 
	 * @return
	 */
	public static String firstMenu() {
		StringBuffer sb = new StringBuffer();
		sb.append("jspgou是基於java技術研發的電子商務管理軟體,以其強大、穩定、安全、高效、跨平臺等多方面的優點,");
		sb.append("網站模板統一在後臺管理,系統擁有強大、靈活的標籤,使用者自定義顯示內容和顯示方式。");
		sb.append("jspgou店中店版類似於京東商城,平臺提供商可以自己開店,也可以為其他商家提供開店服務,商家店鋪獨立經營管理,平臺採取統一收銀,按比例獲取銷售分成。");
		return sb.toString();
	}

	/**
	 * 選擇2的時候傳送
	 * 
	 * @return
	 */
	public static String secondMenu() {
		StringBuffer sb = new StringBuffer();
		sb.append("基於java技術開發,繼承其強大、穩定、安全、高效、跨平臺等多方面的優點,支援mysql、oracle、sqlserver等資料庫");
		sb.append("懂html就能建站,提供便利、合理的使用方式 ");
		sb.append("強大、靈活的標籤,使用者自定義顯示內容和顯示方式 ");
		sb.append("在設計上自身預先做了搜尋引擎優化,增強對搜尋引擎的友好性 ");
		return sb.toString();
	}

	/********************************* 圖文訊息 ***********************************/
	/**
	 * 將圖文訊息轉換為XML
	 * 
	 * @param newsMessage
	 * @return
	 */
	public static String newsMessageToXML(NewsMessage newsMessage) {
		XStream xstream = new XStream();
		xstream.alias("xml", newsMessage.getClass());
		xstream.alias("item", new News().getClass());
		return xstream.toXML(newsMessage);
	}
	
	/**
	 * 圖片訊息轉為xml
	 * @param imageMessage
	 * @return
	 */
	public static String imageMessageToXml(ImageMessage imageMessage){
		XStream xstream = new XStream();
		xstream.alias("xml", imageMessage.getClass());
		return xstream.toXML(imageMessage);
	}
	
	/**
	 * 音樂訊息轉為xml
	 * @param musicMessage
	 * @return
	 */
	public static String musicMessageToXml(MusicMessage musicMessage){
		XStream xstream = new XStream();
		xstream.alias("xml", musicMessage.getClass());
		return xstream.toXML(musicMessage);
	}
    /**
     * 圖文訊息的組裝
     * @param toUserName
     * @param fromUserName
     * @return
     */
	public static String initNewsMessage(String toUserName, String fromUserName) {
		String message=null;
		List<News> newsList=new ArrayList<News>();
		NewsMessage newsMessage=new NewsMessage();
		News news=new News();
		news.setTitle("jspgou介紹");
		news.setDescription("基於java技術開發,繼承其強大、穩定、安全、高效、跨平臺等多方面的優點,支援mysql、oracle、sqlserver等資料庫,懂html就能建站,提供便利、合理的使用方式 強大、靈活的標籤,使用者自定義顯示內容和顯示方式 在設計上自身預先做了搜尋引擎優化,增強對搜尋引擎的友好性 ");
		news.setPicUrl(URL+"/we/image/1.jpg");
		news.setUrl("http://192.168.0.200:8000/jspgou/platform/start.html");
		
		News news2=new News();
		news2.setTitle("jspgou介紹");
		news2.setDescription("基於java技術開發,繼承其強大、穩定、安全、高效、跨平臺等多方面的優點,支援mysql、oracle、sqlserver等資料庫,懂html就能建站,提供便利、合理的使用方式 強大、靈活的標籤,使用者自定義顯示內容和顯示方式 在設計上自身預先做了搜尋引擎優化,增強對搜尋引擎的友好性 ");
		news2.setPicUrl(URL+"/we/image/1.jpg");
		news2.setUrl("http://192.168.0.200:8000/jspgou/platform/start.html");
		
		News news3=new News();
		news3.setTitle("jspgou介紹");
		news3.setDescription("基於java技術開發,繼承其強大、穩定、安全、高效、跨平臺等多方面的優點,支援mysql、oracle、sqlserver等資料庫,懂html就能建站,提供便利、合理的使用方式 強大、靈活的標籤,使用者自定義顯示內容和顯示方式 在設計上自身預先做了搜尋引擎優化,增強對搜尋引擎的友好性 ");
		news3.setPicUrl(URL+"/we/image/1.jpg");
		news3.setUrl("http://192.168.0.200:8000/jspgou/platform/start.html");
		
		newsList.add(news);
		newsList.add(news2);
		newsList.add(news3);
		newsMessage.setToUserName(fromUserName);
		newsMessage.setFromUserName(toUserName);
		newsMessage.setCreateTime(new Date().toString());
		newsMessage.setMsgType(MESSAGE_NEWS);
		newsMessage.setArticles(newsList);
		newsMessage.setArticleCount(newsList.size());
		
		message=newsMessageToXML(newsMessage);
		return message;
	}
	/**
	 * 組裝圖片訊息
	 * @param toUserName
	 * @param fromUserName
	 * @return
	 */
	public static String initImageMessage(String toUserName,String fromUserName){
		String message = null;
		Image image = new Image();
		image.setMediaId("8WLkg-lrNbTDrfdN-r2bJy6L2e-SrsTDPRyR1HUhBM3nqyWOQ4vY_7dvK1M_kkA4");
		ImageMessage imageMessage = new ImageMessage();
		imageMessage.setFromUserName(toUserName);
		imageMessage.setToUserName(fromUserName);
		imageMessage.setMsgType(MESSAGE_IMAGE);
		imageMessage.setCreateTime(new Date().toString());
		imageMessage.setImage(image);
		message = imageMessageToXml(imageMessage);
		return message;
	}
	
	/**
	 * 組裝音樂訊息
	 * @param toUserName
	 * @param fromUserName
	 * @return
	 */
	public static String initMusicMessage(String toUserName,String fromUserName){
		String message = null;
		Music music = new Music();
		music.setThumbMediaId("oPSaANAdutQ3ALNjJsqIBYeAN2QrOSylSCe_DagftdnuTRe1ymUM51S-7IUT78Rt");
		music.setTitle("誰來剪月光.mp3");
		music.setDescription("陳奕迅");
		music.setMusicUrl(URL+"/we/resource/SeeYouAgain.mp3");
		music.setHQMusicUrl(URL+"/we/resource/SeeYouAgain.mp3");
		MusicMessage musicMessage = new MusicMessage();
		musicMessage.setFromUserName(toUserName);
		musicMessage.setToUserName(fromUserName);
		musicMessage.setMsgType(MESSAGE_MUSIC);
		musicMessage.setCreateTime(new Date().toString());
		musicMessage.setMusic(music);
		message = musicMessageToXml(musicMessage);
		return message;
	}
}

servlet

package com.wlw.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.wlw.util.CheckUtil;
import com.wlw.util.MessageUtil;

public class WexinServlet extends HttpServlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		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);
		}
	}
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		req.setCharacterEncoding("UTF-8");
		resp.setCharacterEncoding("UTF-8");
		//返回訊息
		PrintWriter out=resp.getWriter();
		try {
			Map<String, String> map=MessageUtil.xmlToMap(req);
			String fromUserName=map.get("FromUserName");
			String toUserName=map.get("ToUserName");
			//String createTime=map.get("CreateTime");
			String msgType=map.get("MsgType");
			String content=map.get("Content");
			//String msgId=map.get("MsgId");
			
			String message=null;
			//判斷是否屬於文字訊息
			if (MessageUtil.MESSAGE_TEXT.equals(msgType)) {
				//關鍵字回覆判斷
				if ("1".equals(content)) {
					message=MessageUtil.initText(toUserName, fromUserName, MessageUtil.firstMenu());
					System.out.println(message);
				}else if ("2".equals(content)){
					message=MessageUtil.initText(toUserName, fromUserName, MessageUtil.secondMenu());
				}else if ("3".equals(content)) {
					message=MessageUtil.initImageMessage(toUserName, fromUserName);
				}else if ("4".equals(content)) {
					message=MessageUtil.initMusicMessage(toUserName, fromUserName);
				}else if ("5".equals(content)) {
					message=MessageUtil.initNewsMessage(toUserName, fromUserName);
				}else if("?".equals(content)||"?".equals(content)){
					message=MessageUtil.initText(toUserName, fromUserName, MessageUtil.menuText());
				}else {
					message="";
				}
				
			}else if (MessageUtil.MESSAGE_EVNET.equals(msgType)) {
				String eventType=map.get("Event");
				if (MessageUtil.MESSAGE_SUBSCRIBE.equals(eventType)) {
					message=MessageUtil.initText(toUserName, fromUserName, MessageUtil.menuText());
				}else if(MessageUtil.MESSAGE_CLICK.equals(eventType)){
					message=MessageUtil.initText(toUserName, fromUserName, MessageUtil.menuText());
				}else if(MessageUtil.MESSAGE_VIEW.equals(eventType)){
					 String url=map.get("EventKey");
					 message=MessageUtil.initText(toUserName, fromUserName, url);
				}else if(MessageUtil.MESSAGE_SCANCODE.equals(eventType)){
					 String url=map.get("EventKey");
					 message=MessageUtil.initText(toUserName, fromUserName, url);
				}
			}else if (MessageUtil.MESSAGE_LOCATION.equals(msgType)) {
				String label=map.get("Label");
				message=MessageUtil.initText(toUserName, fromUserName, label);
			}
			System.out.println(message);
			out.print(message);
		} catch (Exception e) {
			e.printStackTrace();
		}finally{
			out.close();
		}
	}
}

建立MsgConstant類,將請求訊息型別進行封裝

package com.wlw.msg;

/**
 * 請求訊息型別
 * @author ASUS
 *
 */
public class MsgConstant {
	     //請求訊息型別:文字
		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_VIDEO = "video";

		//請求訊息型別: 短視訊訊息
		public static final String REQ_MESSAGE_TYPE_SHORTVIDEO = "shortvideo";

		//請求訊息型別:推送
		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";

		//事件型別: view(自定義選單view事件)
		public static final String EVENT_TYPE_VIEW = "VIEW";

		//事件型別:scan(使用者已關注時的事件推送)
		public static final String EVENT_TYPE_SCAN = "SCAN";

		//事件型別:LOCATION(上報地理位置事件)
		public static final String EVENT_TYPE_LOCATION = "LOCATION";

		//建立回話(接入回話) 事件: kf_create_session
		public static final String KF_CREATE_SESSION = "kf_create_session";

		//關閉回話事件: kf_close_session
		public static final String KF_CLOSE_SESSION = "kf_close_session";

		//轉接回話事件: kf_switch_session
		public static final String KF_SWITCH_SESSION = "kf_switch_session";
}
測試   上傳音樂回覆時需要獲得mediaId
package test;

import com.wlw.po.AccessToken;
import com.wlw.util.WeixinUtil;
public class weixinTest2 {
	  public static void main(String[] args) {
		  try {
				AccessToken token = WeixinUtil.getAccessToken();
				System.out.println("票據:"+token.getToken());
				System.out.println("有效時間:"+token.getExpiresIn());
			String path="D:/1.jpg";
			String mediaId=WeixinUtil.upload(path, token.getToken(), "thumb");
			System.out.println("mediaId:"+mediaId);
			} catch (Exception e) {
				e.printStackTrace();
			}
	}
}


(訊息回覆和自定義選單的建立、查詢、刪除的程式碼)連結: https://pan.baidu.com/s/1hSfIWUHON2W2_51OW6tyCQ 密碼: 5a33

相關推薦

解決公眾訊息回覆五秒限制最好方法

如題 很多朋友發現在訊息回覆處理業務的時候,可能時間不固定,甚至超過5s,親測可用 我的辦法是不用訊息回覆介面,全部改用客服訊息介面 1.收到訊息後,首先回復“處理中,請稍等” 2.直接上程式碼 ob_

公眾(訊息回覆)

首先申請微信公眾號,獲取到APPID、appsecret之類的就不用細說了吧!當普通微信使用者向公眾賬號發訊息時,微信伺服器將POST訊息的XML資料包到開發者填寫的URL上。訊息回覆原理: 使用者輸入Content(資訊)-->後臺接收到資訊,對資訊進行解析,判斷--

公眾被動回覆訊息

本文寫的是使用者公眾號輸入關鍵詞,微信伺服器被動回覆內容。首先在後臺上傳關鍵詞與回覆內容前臺頁面內容如下<form class="layui-form" action="{:U('replyText')}" style="padding-right: 10px;" me

公眾實現回覆圖文訊息

圖文訊息的主要引數說明通過微信官方的訊息介面指南,可以看到對圖文訊息的引數介紹,如下圖所示:從上圖可以瞭解到:1、圖文訊息的個數限制為10,也就是圖文中ArticleCount的值(圖文訊息的個數,限制在10條以內)2、對於圖文訊息,第一條圖文的圖片顯示為大圖,其他圖文的圖片

開發系列】1. python開發微公眾訊息回覆開發者模式

背景 最近申請了一個微信公眾號,想根據使用者的訊息進行智慧動態回覆。於是有了這篇文章。 公眾號申請:https://mp.weixin.qq.com。 想根據具體訊息進行智慧動態回覆,需要開啟開發者模式。 開發者模式需要進入開發者中心進行編碼認證。這裡面只講主要的程

公眾自動回覆設定教程

微信公眾號選單等功能如何開通 自定義選單最大的優點是減少了使用者的認知門檻,可以將公眾賬號裡的重點資訊入口直觀的暴露給使用者。當用戶進入到公眾賬號時,可以一目瞭然的瞭解相關的服務,只需要點選,不需要再通過一系列的命令列互動(或者簡化了命令列互動的方式,提供了更低門檻的入口) ①:《微信公眾號

flask+新浪sae+圖靈機器人實現超簡單公眾智慧回覆功能

人工智慧很火,但是智慧演算法對於大多數人來說門檻兒還是挺高的對於我們這種喜歡折騰的碼農來說,就算不會演算法也要又一顆想折騰的心我們不會演算法,可以基於已經成熟的演算法成果來做一些好玩兒的東西本文介紹下微信公眾號接入圖靈機器人實現智慧回覆功能申請微信公眾號;申請新浪SAE,初次

公眾自動回覆業務邏輯五秒不能處理完成

主要思路,首先返給微信伺服器success 然後呼叫客服介面//請求進來 返回success ignore_user_abort(true); ob_start(); //開啟輸出控制緩衝 echo 'success'; // 返給微信伺服器的字串 header('Conne

node(koa)完成公眾自動回覆功能

首先需要在微信公眾平臺 - 基礎設定 - 設定伺服器地址 配置伺服器地址時可能出現“引數錯誤,。。。。”的情況,可能是因為域名被攔截,不能使用。 如果前端人員進行測試,可以使用ngrok,花生殼

公眾-訊息推送-實現固定模式下的私人訂製

開發微信已經將近4個月了,但是還是不會本地除錯,只能部署到伺服器上,通過打日誌,來看是否有錯,@ALL哪位同志,如果有好的方法,可以告訴我。 先簡要介紹一下微信公眾號,訊息推送的原理。 微信公眾號只是一個平臺,這個平臺的功能是一樣的,但是這個功能的內容卻可以由這個公眾號

Python-快速實現公眾自動回覆(聊天機器人)

原理:通過微信公眾號提供的開發者模式,利用Python搭建環境,實現自動回覆,回覆內容通過呼叫圖靈機器人的API 配置:伺服器(這裡是阿里雲主機,Ubuntu),公眾號,圖靈機器人 一,公眾平臺上進行開發配置 三種加密方式,按需選擇。第一種最簡單,最不安全(我這裡選擇的第

手把手教你用圖靈機器人做公眾自動回覆助手

本文首發於我的個人部落格:尾尾部落 閱讀這篇文章,你將會學會以下內容: 如何用flask搭建微信公眾平臺服務 如何將在微信公眾平臺呼叫圖靈機器人 如何用uwsgi+supervisor+nginx部署flask應用 實驗

公眾開發--接收與回覆訊息(Java)

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

909422229_公眾接收訊息進行回覆

一、基於上一篇文章已經說了如何配置伺服器,配置完成後給公眾號傳送訊息會返回接收的訊息內容,一個json串。 二、開啟上一篇提供的專案地址,開啟WechatController 程式碼如下:這個程式碼是我經過接收的訊息處理過的,使用的是加密後的訊息,經過解密後得到一個XML訊息串。

公眾開發學習(2)_____訊息接收與被動回覆

訊息接收(只以文字訊息為例,其它訊息類似,具體官網檢視) XML有4種解析方式,如果不瞭解,可以看看 /*獲取XML資料*/ InputStream is = request.getInputStream(); DocumentBuilderFactory dbf =

公眾開發-實現服務端回覆訊息為空

微信側提供的被動回覆使用者訊息文件: 如果你回覆 的是一個物件格式,content為“”,這時微信側會顯示: 如果你對使用者輸入的某些資訊不進行回覆,那麼你應該這樣做: private void noReply(HttpServletResponse respo

公眾開發之回覆圖文訊息(被動) 公眾開發之VS遠端除錯

目錄 (一)微信公眾號開發之VS遠端除錯 (二)微信公眾號開發之基礎梳理 (三)微信公眾號開發之自動訊息回覆和自定義選單 (四)微信公眾號開發之網頁授權獲取使用者基本資訊 (五)微信公眾號開發之網頁中及時獲取當前使用者Openid及注意事項 (六)微信公眾號開發之掃碼支付 (七)微信公眾號開發之

公眾開發(六)-- 關注公眾自動回覆兩條訊息

昨天晚上臨下班,客戶提了個新需求,關注公眾號的時候希望呢能自動回覆兩條資訊。我,一個野生的菜雞程式媛當時眼前就一黑,昨天還是聖誕節呢嘿。 咳。查了下,自動回覆兩條訊息,其實除了歡迎資訊再呼叫一次客服介面。 呼叫客服介面,回覆文字資訊 $content = 'Hello

公眾接收訊息密文解密及明文加密後自動回覆

1.使用token驗證後的地址接收訊息 /** * 將微信公眾號接收資訊(引數微信會攜帶過來) * @params timestamp 時間戳 * @params nonce 隨機串 * @params msg_signature 訊息簽名 * @params req

公眾之Spring mvc訊息伺服器實現自定義規則回覆

微信公眾號的訊息自動回覆是微信公眾平臺給公眾賬號提供的一種基礎能力。在微信公眾號的管理平臺,微信開放了三種簡單基礎的訊息自動回覆規則,用Spring mvc實現訊息伺服器還是比較簡單高效。 關鍵詞回覆:根據使用者傳送內容進行關鍵字的匹配回覆,相應關鍵字可觸發相應的回覆。此類