微信公众号开发消息推送以及图文推送 (2)

验签验完了之后,我们开始接受消息然后处理逻辑。

file

/** * 处理业务逻辑 * * @param request * @param response */ @RequestMapping(value = "sendMsg", method = RequestMethod.POST, produces = "text/html;charset=UTF-8") public void sendMsgPost(HttpServletRequest request, HttpServletResponse response) { // 调用核心业务类接收消息、处理消息 try { String respMessage = processRequest(request); System.err.println(respMessage); // 我们这里处理的是utf-8 微信要的是ios8859-1这是坑啊。。。。。 byte[] uMessage = respMessage.getBytes("UTF-8");// 编码:字符串变成字节数组 输入 参数(编码表) String iMessage = new String(uMessage, "ISO8859-1");// 解码:字节数组变成字符串,String参数(数组,编码表) 输出 if (respMessage != null) { // 响应消息 PrintWriter out = response.getWriter(); out.print(iMessage); out.close(); } } catch ( Exception e) { // 也许大概不会走到这里除非异常了。。。。。。 } } public String processRequest(HttpServletRequest request) { String respMessage = null; try { // xml请求解析 Map<String, String> requestMap = MessageUtil.parseXml(request); // 发送方帐号(open_id) String fromUserName = requestMap.get("FromUserName"); // 公众帐号 String toUserName = requestMap.get("ToUserName"); // 消息类型 String msgType = requestMap.get("MsgType"); TextMessage textMessage = new TextMessage(); textMessage.setToUserName(fromUserName); textMessage.setFromUserName(toUserName); textMessage.setCreateTime(new Date().getTime()); textMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_TEXT); // 文本消息 if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_TEXT)) { // 接收用户发送的文本消息内容 String content = requestMap.get("Content"); System.err.println(content); // 创建图文消息 NewsMessage newsMessage = new NewsMessage(); newsMessage.setToUserName(fromUserName); newsMessage.setFromUserName(toUserName); newsMessage.setCreateTime(new Date().getTime()); newsMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_NEWS); List<Article> articleList = new ArrayList<Article>(); // 单图文消息 if ("yifan".equals(content)) { Article article = new Article(); article.setTitle("欢迎关注KingYiFan\'s Blog"); article.setDescription("点击进入详情"); article.setPicUrl( "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1521808337402&di=515fdc032be051f5085c3f9c03af5646&imgtype=0&src=http%3A%2F%2F%2Fdata%2Fupload%2Fueditor%2F20170327%2F58d8c88855d9f.jpg"); article.setUrl("http://cnbuilder.cn/"); articleList.add(article); // 设置图文消息个数 newsMessage.setArticleCount(articleList.size()); // 设置图文消息包含的图文集合 newsMessage.setArticles(articleList); // 将图文消息对象转换成xml字符串 respMessage = MessageUtil.newsMessageToXml(newsMessage); } else { // 机器人api String jiqiren = HttpClientUtils.sendGetUtF8("http://i.itpk.cn/api.php", "limit=2&api_key=xxxxx&api_secret=xxxx&type=json&question=" + content); textMessage.setContent(jiqiren); respMessage = MessageUtil.textMessageToXml(textMessage); } // 事件处理开始 } else if (msgType.equals(MessageUtil.REQ_MESSAGE_TYPE_EVENT)) { NewsMessage newsMessage = new NewsMessage(); newsMessage.setToUserName(fromUserName); newsMessage.setFromUserName(toUserName); newsMessage.setCreateTime(new Date().getTime()); newsMessage.setMsgType(MessageUtil.RESP_MESSAGE_TYPE_NEWS); // 事件类型 String eventType = requestMap.get("Event"); List<Article> articleList = new ArrayList<Article>(); if (eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)) { Article article = new Article(); article.setTitle("欢迎关注KingYiFan\'s Blog"); article.setDescription("点击进入详情"); article.setPicUrl( "https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1521808337402&di=515fdc032be051f5085c3f9c03af5646&imgtype=0&src=http%3A%2F%2F%2Fdata%2Fupload%2Fueditor%2F20170327%2F58d8c88855d9f.jpg"); article.setUrl("http://cnbuilder.cn/"); articleList.add(article); // 设置图文消息个数 newsMessage.setArticleCount(articleList.size()); // 设置图文消息包含的图文集合 newsMessage.setArticles(articleList); // 将图文消息对象转换成xml字符串 respMessage = MessageUtil.newsMessageToXml(newsMessage); try { // 保存用户信息 wxMsgService.savaWxInfo(fromUserName); } catch (Exception e) { return respMessage; } } } else if (msgType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)) { // 取消关注,用户接受不到我们发送的消息了,可以在这里记录用户取消关注的日志信息 } } catch (Exception e) { e.printStackTrace(); } return respMessage; } package cn.cnbuilder.utils; import java.io.InputStream; import java.io.Writer; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletRequest; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.io.SAXReader; import com.thoughtworks.xstream.XStream; import com.thoughtworks.xstream.core.util.QuickWriter; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; import com.thoughtworks.xstream.io.xml.PrettyPrintWriter; import com.thoughtworks.xstream.io.xml.XppDriver; import cn.cnbuilder.entity.wx.sendMsg.Article; import cn.cnbuilder.entity.wx.sendMsg.MusicMessage; import cn.cnbuilder.entity.wx.sendMsg.NewsMessage; import cn.cnbuilder.entity.wx.sendMsg.TextMessage; public class MessageUtil { /** * 返回消息类型:文本 */ public static final String RESP_MESSAGE_TYPE_TEXT = "text"; /** * 返回消息类型:音乐 */ public static final String RESP_MESSAGE_TYPE_MUSIC = "music"; /** * 返回消息类型:图文 */ public static final String RESP_MESSAGE_TYPE_NEWS = "news"; /** * 请求消息类型:文本 */ 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_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"; /** * 解析微信发来的请求(XML) * * @param request * @return * @throws Exception */ @SuppressWarnings("unchecked") public static Map<String, String> parseXml(HttpServletRequest request) throws Exception { // 将解析结果存储在HashMap中 Map<String, String> map = new HashMap<String, String>(); // 从request中取得输入流 InputStream inputStream = request.getInputStream(); // 读取输入流 SAXReader reader = new SAXReader(); Document document = reader.read(inputStream); // 得到xml根元素 Element root = document.getRootElement(); // 得到根元素的所有子节点 List<Element> elementList = root.elements(); // 遍历所有子节点 for (Element e : elementList) map.put(e.getName(), e.getText()); // 释放资源 inputStream.close(); inputStream = null; return map; } /** * 文本消息对象转换成xml * * @param textMessage 文本消息对象 * @return xml */ public static String textMessageToXml(TextMessage textMessage) { xstream.alias("xml", textMessage.getClass()); return xstream.toXML(textMessage); } /** * 音乐消息对象转换成xml * * @param musicMessage 音乐消息对象 * @return xml */ public static String musicMessageToXml(MusicMessage musicMessage) { xstream.alias("xml", musicMessage.getClass()); return xstream.toXML(musicMessage); } /** * 图文消息对象转换成xml * * @param newsMessage 图文消息对象 * @return xml */ public static String newsMessageToXml(NewsMessage newsMessage) { xstream.alias("xml", newsMessage.getClass()); xstream.alias("item", new Article().getClass()); return xstream.toXML(newsMessage); } /** * 扩展xstream,使其支持CDATA块 * * @date 2013-05-19 */ private static XStream xstream = new XStream(new XppDriver() { public HierarchicalStreamWriter createWriter(Writer out) { return new PrettyPrintWriter(out) { // 对所有xml节点的转换都增加CDATA标记 boolean cdata = true; @SuppressWarnings("unchecked") public void startNode(String name, Class clazz) { super.startNode(name, clazz); } protected void writeText(QuickWriter writer, String text) { if (cdata) { writer.write("<![CDATA["); writer.write(text); writer.write("]]>"); } else { writer.write(text); } } }; } }); } package cn.cnbuilder.entity.wx.sendMsg; public class TextMessage extends BaseMessage { // 消息内容 private String Content; public String getContent() { return Content; } public void setContent(String content) { Content = content; } } package cn.cnbuilder.entity.wx.sendMsg; import java.util.List; public class NewsMessage extends BaseMessage{ // 图文消息个数,限制为10条以内 private int ArticleCount; // 多条图文消息信息,默认第一个item为大图 private List<Article> Articles; public int getArticleCount() { return ArticleCount; } public void setArticleCount(int articleCount) { ArticleCount = articleCount; } public List<Article> getArticles() { return Articles; } public void setArticles(List<Article> articles) { Articles = articles; } } package cn.cnbuilder.entity.wx.sendMsg; public class Article { // 图文消息名称 private String Title; // 图文消息描述 private String Description; // 图片链接,支持JPG、PNG格式,较好的效果为大图640*320,小图80*80,限制图片链接的域名需要与开发者填写的基本资料中的Url一致 private String PicUrl; // 点击图文消息跳转链接 private String Url; public String getTitle() { return Title; } public void setTitle(String title) { Title = title; } public String getDescription() { return null == Description ? "" : Description; } public void setDescription(String description) { Description = description; } public String getPicUrl() { return null == PicUrl ? "" : PicUrl; } public void setPicUrl(String picUrl) { PicUrl = picUrl; } public String getUrl() { return null == Url ? "" : Url; } public void setUrl(String url) { Url = url; } } package cn.cnbuilder.entity.wx.sendMsg; public class BaseMessage { // 开发者微信号 private String ToUserName; // 发送方帐号(一个OpenID) private String FromUserName; // 消息创建时间 (整型) private long CreateTime; // 消息类型(text/image/location/link) private String MsgType; // 消息id,64位整型 private long MsgId; 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; } public long getMsgId() { return MsgId; } public void setMsgId(long msgId) { MsgId = msgId; } } package cn.cnbuilder.utils; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.URL; import java.net.URLConnection; import java.util.List; import java.util.Map; import org.apache.http.HttpResponse; import org.apache.http.client.config.RequestConfig; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ContentType; import org.apache.http.entity.StringEntity; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClients; import org.apache.http.util.EntityUtils; import net.sf.json.JSONObject; public class HttpClientUtils { /** * 向指定URL发送GET方法的请求 * * @param url 发送请求的URL * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 * @return URL 所代表远程资源的响应结果 */ public static String sendGet(String url, String param) { String result = ""; BufferedReader in = null; try { String urlNameString = url + "?" + param; URL realUrl = new URL(urlNameString); // 打开和URL之间的连接 URLConnection connection = realUrl.openConnection(); // 设置通用的请求属性 connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("connection", "Keep-Alive"); // 建立实际的连接 connection.connect(); // 获取所有响应头字段 Map<String, List<String>> map = connection.getHeaderFields(); // 遍历所有的响应头字段 for (String key : map.keySet()) { System.out.println(key + "--->" + map.get(key)); } // 定义 BufferedReader输入流来读取URL的响应 in = new BufferedReader(new InputStreamReader(connection.getInputStream(), "gbk")); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { System.out.println("发送GET请求出现异常!" + e); e.printStackTrace(); } // 使用finally块来关闭输入流 finally { try { if (in != null) { in.close(); } } catch (Exception e2) { e2.printStackTrace(); } } return result; } /** * 向指定URL发送GET方法的请求 * * @param url 发送请求的URL * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 * @return URL 所代表远程资源的响应结果 */ public static String sendGetUtF8(String url, String param) { String result = ""; BufferedReader in = null; try { String urlNameString = url + "?" + param; URL realUrl = new URL(urlNameString); // 打开和URL之间的连接 URLConnection connection = realUrl.openConnection(); // 设置通用的请求属性 connection.setRequestProperty("accept", "*/*"); connection.setRequestProperty("connection", "Keep-Alive"); // 建立实际的连接 connection.connect(); // 获取所有响应头字段 Map<String, List<String>> map = connection.getHeaderFields(); // 遍历所有的响应头字段 for (String key : map.keySet()) { System.out.println(key + "--->" + map.get(key)); } // 定义 BufferedReader输入流来读取URL的响应 in = new BufferedReader(new InputStreamReader(connection.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { System.out.println("发送GET请求出现异常!" + e); e.printStackTrace(); } // 使用finally块来关闭输入流 finally { try { if (in != null) { in.close(); } } catch (Exception e2) { e2.printStackTrace(); } } return result; } /** * 向指定 URL 发送POST方法的请求 * * @param url 发送请求的 URL * @param param 请求参数,请求参数应该是 name1=value1&name2=value2 的形式。 * @return 所代表远程资源的响应结果 */ public static String sendPost(String url, String param) { PrintWriter out = null; BufferedReader in = null; String result = ""; try { URL realUrl = new URL(url); // 打开和URL之间的连接 URLConnection conn = realUrl.openConnection(); // 设置通用的请求属性 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1;SV1)"); // 发送POST请求必须设置如下两行 conn.setDoOutput(true); conn.setDoInput(true); // 获取URLConnection对象对应的输出流 out = new PrintWriter(conn.getOutputStream()); // 发送请求参数 out.print(param); // flush输出流的缓冲 out.flush(); // 定义BufferedReader输入流来读取URL的响应 in = new BufferedReader(new InputStreamReader(conn.getInputStream())); String line; while ((line = in.readLine()) != null) { result += line; } } catch (Exception e) { System.out.println("发送 POST 请求出现异常!" + e); e.printStackTrace(); } // 使用finally块来关闭输出流、输入流 finally { try { if (out != null) { out.close(); } if (in != null) { in.close(); } } catch (IOException ex) { ex.printStackTrace(); } } return result; } public static String doPostForJson(String url, String jsonParams) { CloseableHttpClient httpClient = HttpClients.createDefault(); HttpPost httpPost = new HttpPost(url); RequestConfig requestConfig = RequestConfig.custom().setConnectTimeout(180 * 1000) .setConnectionRequestTimeout(180 * 1000).setSocketTimeout(180 * 1000).setRedirectsEnabled(true).build(); httpPost.setConfig(requestConfig); httpPost.setHeader("Content-Type", "application/json"); // try { httpPost.setEntity(new StringEntity(jsonParams, ContentType.create("application/json", "utf-8"))); System.out.println("request parameters" + EntityUtils.toString(httpPost.getEntity())); HttpResponse response = httpClient.execute(httpPost); String str = EntityUtils.toString(response.getEntity()); /** 把json字符串转换成json对象 **/ JSONObject fromObject = JSONObject.fromObject(str); return fromObject.toString(); } catch (Exception e) { e.printStackTrace(); return "KingYiFan温馨提示你:post请求出异常了" + e.getMessage().toString(); } finally { if (null != httpClient) { try { httpClient.close(); } catch (IOException e) { e.printStackTrace(); } } } } } package cn.cnbuilder.entity.wx.sendMsg; public class Music { // 音乐名称 private String Title; // 音乐描述 private String Description; // 音乐链接 private String MusicUrl; // 高质量音乐链接,WIFI环境优先使用该链接播放音乐 private String HQMusicUrl; 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 getMusicU package cn.cnbuilder.entity.wx.sendMsg; public class MusicMessage { // 音乐 private Music Music; public Music getMusic() { return Music; } public void setMusic(Music music) { Music = music; } } rl() { return MusicUrl; } public void setMusicUrl(String musicUrl) { MusicUrl = musicUrl; } public String getHQMusicUrl() { return HQMusicUrl; } public void setHQMusicUrl(String musicUrl) { HQMusicUrl = musicUrl; } } package cn.cnbuilder.entity.wx.sendMsg; public class MusicMessage { // 音乐 private Music Music; public Music getMusic() { return Music; } public void setMusic(Music music) { Music = music; } }

这就是微信公众平台消息回复的教程,哪里不懂可以私信我哦!

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwypwy.html