欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

微信公众号(消息回复)

程序员文章站 2022-05-30 20:33:29
...

首先申请微信公众号,获取到APPID、appsecret之类的就不用细说了吧!

当普通微信用户向公众账号发消息时,微信服务器将POST消息的XML数据包到开发者填写的URL上。

消息回复原理: 用户输入Content(信息)-->后台接收到信息,对信息进行解析,判断-->将组装好的内容发生给用户端显示

这是后台服务器接收到的信息(自己可在控制台打印输出查看)

{Content=?, CreateTime=1530078502, ToUserName=gh_abb85570b5a7, FromUserName=oPR_X1ZiZXmcSk8RYk8Jw06NAj6Q, MsgType=text, MsgId=6571637126828028609}
参数 描述
ToUserName 开发者微信号
FromUserName 发送方帐号(一个OpenID)
CreateTime 消息创建时间 (整型)
MsgType text
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