How to get and reply to messages from WeChat development API, I will introduce you below
1. Explanation
* This example is developed and demonstrated according to the WeChat development document: http://mp.weixin.qq.com/wiki/home/index.html latest version (4/3/2016 5:34:36 PM).
* Editing platform: myeclipse10.7+win32+jdk1.7+tomcat7.0
* Server: Alibaba Cloud Windows Server 2008 64bits
* Platform requirements: servlet usage annotation method, platform requirements: j2ee6.0+, jdk6.0+, tomcat7.0+
* Demo focuses more on API parsing.
* For the sake of testing instructions, each test case is independent and does not depend on other methods. Don't consider the packaging much.
* The demonstration is carried out as much as possible according to the API requirements. Purpose: understand how the document is used and achieve the effect of learning from one example and applying it to others.
* Knowledge requirements: solid Java foundation, understanding http network communication knowledge, having enough understanding of Javaweb, json analysis
* This part of the demo source code will be given at the end of each article. After analyzing the API, all the demo source codes will be given in the form of a source code package.
* Current time: 4/3/2016 5:32:57 PM, this time shall prevail.
2. Document original text-Message management (abstract)
• Document address: http://mp.weixin.qq.com/wiki/17/f298879f8fb29ab98b2f2971d42552fd.html
•Message Management
◦Receive message-Receive normal message
◦Receive message-receive event push
◦Send message-passive reply message
◦Send message-encryption and decryption when passive reply
◦Send message-Customer service message
◦Send message-massage interface
◦Send message-template message interface
◦Send message-Template message operation specifications
◦ Obtain automatic reply configuration for official account
3. Document understanding
•Receive messages
◦The document explains this: When an ordinary WeChat user sends a message to a public account, the WeChat server will package the XML data of the POST message to the URL filled in by the developer.
◦Understanding: The WeChat server returns the message sent by the user to req in the form of a Post stream. When we want to get the message sent by the user, we can get it through req.getInputStream(). Of course, we can perform necessary parsing based on the XML format of the return message in the document.
◦
accomplish:
/* * In this part, we get the information sent by the user and parse it into <K,V> for display*/// parse the information sent by the user. InputStream is = req.getInputStream();// Get the request stream// Store the parsed result in HashMap Map<String, String> map = new HashMap<String, String>();// parse xml, parse the obtained return result into the text information we are used to SAXReader reader = new SAXReader();// Third-party jar:dom4j [Baidu: saxreader parsing xml] Document document = null;try { document = reader.read(is);} catch (DocumentException e1) { // TODO Auto-generated catch block e1.printStackTrace();}// Get xml root element Element root = document.getRootElement();// Get all child nodes of the root element List<Element> elementList = root.elements();// Traversing all child nodes for (Element e : elementList) map.put(e.getName(), e.getText());// Test output Set<String> keySet = map.keySet();// After the test output is parsed, the information sent by the user is sent by the user System.out.println(TAG + ": start to parse the information sent by the user"); for (String key : keySet) { System.out.println(key + ":" + map.get(key));}System.out.println(TAG + ": end to parse the information sent by the user"); •Send a message
◦The document explains this: When a user sends a message to the official account (or when an event is pushed by a specific user operation), a POST request will be generated. The developer can return a specific XML structure in the response package (Get) to respond to the message (now supports reply text, pictures, pictures, text, voice, video, and music). Strictly speaking, sending passive response messages is not actually an interface, but a reply to a message sent to a WeChat server.
◦Understanding: When a user sends a request, a POST request will be generated, and we can reply to messages through Respone. However, the reply content has strict format requirements. Only when the format requirements are met will the WeChat server process and return it to the user. By viewing the document "Message Management" module, we can see that there are various messages in WeChat, and each type of message has its own specific format requirements. We must follow the requirements to return specific information to the user normally. We try to reply to users with text information and graphic messages in the required format of the document. Focus: Construct required parameters according to the document requirements. Special note: Parameters are case sensitive.
◦Implement 1-Reply to normal text messages:
//Example 1: Send a normal text message, please check the xml format of the document about the "reply text message"// Step 1: Construct the required parameters TextMsg textMsg = new TextMsg();textMsg.setToUserName(map.get("FromUserName"));// Send and receive the message "User" just the opposite textMsg.setFromUserName(map.get("ToUserName"));textMsg.setCreateTime(new Date().getTime());// Message creation time (integer) textMsg.setMsgType("text");// Text type message textMsg.setContent("I am the server reply to the user");// // The second step is to convert the constructed information into the xml format recognized by WeChat [Baidu: xstream bean to xml]XStream xStream = new XStream();xStream.alias("xml", textMsg.getClass());String textMsg2Xml = xStream.toXML(textMsg);System.out.println(textMsg2Xml);// // The third step is to send the xml format information to the WeChat server, and the server forwards it to the user PrintWriter printWriter = resp.getWriter();printWriter.print(textMsg2Xml); ◦Implement 2-reply to the text message:
//Example 2, send graphic and text messages. Please check the xml format of the document "Reply to the text message" // Step 1: Construct the parameters required by the replies to the text message List<Article> articles = new ArrayList<Article>();Article a = new Article();a.setTitle("I am the picture title");a.setUrl("www.baidu.com");// This address is after clicking on the picture and jumping a.setPicUrl("http://b.hiphotos.baidu.com/image/pic/item/08f790529822720ea5d058ba7ccb0a46f21fab50.jpg");// This address is a valid image address a.setDescription("I am the description of the image");articles.add(a);PicAndTextMsg picAndTextMsg = new PicAndTextMsg();picAndTextMsg.setToUserName(map.get("FromUserName"));// Send and receive the message "User" just the opposite picAndTextMsg.setFromUserName(map.get("ToUserName"));picAndTextMsg.setCreateTime(new Date().getTime());// Message creation time (integer) picAndTextMsg.setMsgType("news");// Graphic and text type message picAndTextMsg.setArticleCount(1); picAndTextMsg.setArticles(articles);// The second step is to convert the constructed information into the xml format recognized by WeChat [Baidu: xstream bean to xml] XStream xStream = new XStream();xStream.alias("xml", picAndTextMsg.getClass());xStream.alias("item", a.getClass());String picAndTextMsg2Xml = xStream.toXML(picAndTextMsg);System.out.println(picAndTextMsg2Xml);// The third step is to send the format information of the xml to the WeChat server, and the server forwards it to the user PrintWriter printWriter = resp.getWriter();printWriter.print(picAndTextMsg2Xml); All operation source codes in this part can be used directly
•CoreServlet.java (including server access, receiving user sending messages, replying to ordinary text messages, and replying to graphic messages. Third-party jars: dom4j, xstream)
package com.gist.servlet;import java.io.IOException;import java.io.InputStream;import java.io.PrintWriter;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.util.ArrayList;import java.util.Arrays;import java.util.Date;import java.util.HashMap;import java.util.List;import java.util.Map;import java.util.Set;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.dom4j.Document;import org.dom4j.DocumentException;import org.dom4j.Element;import org.dom4j.io.SAXReader;import com.gist.bean.Article;import com.gist.bean.PicAndTextMsg;import com.thoughtworks.xstream.XStream;/** * @author Gao Yuan</n> Email: [email protected]</n> Blog http://blog.csdn.net/wgyscsf</n> * Writing period 2016-4-3 4:34:05 pm */@WebServlet("/CoreServlet")public class CoreServlet extends HttpServlet { private static final long serialVersionUID = 1L; String TAG = "CoreServlet"; /* * Step 2: Verify the validity of the server address After the developer submits the information, the WeChat server will send a GET request to the filled-in server address URL. * The GET request carries four parameters: signature, timestamp, nonce, echostr * The developer verifies the request by verifying the signature (there is a verification method below). If you confirm that the GET request is from the WeChat server, please return the echostr parameter content as it is. *, the access will take effect and become a developer successfully, otherwise the access will fail. * * The encryption/checking process is as follows: 1. Sort dictionary order of token, timestamp, and nonce 2. * Splice the three parameter strings into a string for sha1 encryption 3. The strings after the developer obtains the encrypted strings can be compared with signature, identifying that the request comes from WeChat */ /* * Dictionary sorting (lexicographical * order) is a sorting method for random variables to form sequences. The method is to form a sequence from small to large in alphabetical order or in the order of small and large numbers. */ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // Set encoding req.setCharacterEncoding("utf-8"); resp.setContentType("html/text;charset=utf-8"); resp.setCharacterEncoding("utf-8"); // Get output stream PrintWriter printWriter = resp.getWriter(); // Set a global token, the developer sets it himself. api explains this: the token can be filled in at will by the developer, // Used as a generation signature (the token will be compared with the token contained in the interface URL to verify security) String token = "wgyscsf"; // According to the API description, obtain the above four parameters String signature = req.getParameter("signature"); String timestamp = req.getParameter("timestamp"); String nonce = req.getParameter("nonce"); String echostr = req.getParameter("echostr"); // // temp: temporary printing, watch the return parameter situation // System.out.println(TAG + ":signature:" + signature + ",timestamp:" // + timestamp + ",nonce:" + nonce + ",echostr:" + echostr); // Access according to the "encryption/verification process" mentioned by the API. There are three steps in total // Step 1: Sort dictionary order of token, timestamp, nonce three parameters String[] parms = new String[] { token, timestamp, nonce };// Put the strings that need to be sorted dictionary in the array Arrays.sort(parms);// Sort dictionary order according to API requirements // Step 2: Splice the three parameter strings into a string for sha1 encryption // Splice the string String parmsString = "";// Note that it cannot =null here. for (int i = 0; i < parms.length; i++) { parmsString += parms[i]; } // sha1 encryption String mParms = null;// Encrypted result MessageDigest digest = null; try { digest = java.security.MessageDigest.getInstance("SHA"); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } digest.update(parmsString.getBytes()); byte messageDigest[] = digest.digest(); // Create Hex String StringBuffer hexString = new StringBuffer(); // Convert byte array to hexadecimal number for (int i = 0; i < messageDigest.length; i++) { String shaHex = Integer.toHexString(messageDigest[i] & 0xFF); if (shaHex.length() < 2) { hexString.append(0); } hexString.append(shaHex); } mParms = hexString.toString();// Encryption result/* * api requirements: If you confirm that the GET request comes from the WeChat server, please return the echostr parameter content as it is, and the access will take effect and become a developer successfully. Otherwise, the access will fail. */ // Step 3: The developer obtains the encrypted string and can compare it with the signature to identify that the request comes from the successful access of WeChat. // System.out.println(TAG + ":" + mParms + "--->" + signature); if (mParms.equals(signature)) { // System.out.println(TAG + ":" + mParms + "---->" + signature); printWriter.write(echostr); } else { // Access failed, no need to write back // System.out.println(TAG + "Access failed"); } } /* * Check the API document for sending and receiving messages and pushing basically the same message format. As in the following format: <xml> * <ToUserName><![CDATA[toUser]]></ToUserName> * <FromUserName><![CDATA[fromUser]]></FromUserName> * <CreateTime>1348831860</CreateTime> <MsgType><![CDATA[text]]></MsgType> * <Content><![CDATA[this is a test]]></Content> * <MsgId>1234567890123456</MsgId> </xml> Then, we can perform unified processing. */ /* * Let’s first obtain the input stream and see the information in the input stream. By testing the printout flow, we can see that every time the user requests, we receive a req request. The request format is in xml format, which is explained in the document. */ /* * Note that req.getInputStream() can only be retrieved once and can only be read once. If you want to read it multiple times, you need to find another way. For simplicity, * we only get req.getInputStream() once and no longer print out the output stream information. Directly print the parsed information. */ @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // Set encoding req.setCharacterEncoding("utf-8"); resp.setContentType("html/text;charset=utf-8"); resp.setCharacterEncoding("utf-8"); /* * In this part we get the information sent by the user and parse it into <K,V> for display*/ // Analyze the information sent by the user InputStream is = req.getInputStream();// Get the request stream// Store the parsed results in HashMap Map<String, String> map = new HashMap<String, String>(); // Parses xml, parsing the obtained return result xml into the text information we are used to SAXReader reader = new SAXReader();// Third-party jar:dom4j [Baidu: saxreader parsing xml] Document document = null; try { document = reader.read(is); } catch (DocumentException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } // Get xml root element Element root = document.getRootElement(); // Get all child nodes of the root element List<Element> elementList = root.elements(); // traverse all child nodes for (Element e : elementList) map.put(e.getName(), e.getText()); // Test output Set<String> keySet = map.keySet(); // Test output message sent by the user after the analysis System.out.println(TAG + ": start to parse the information sent by the user"); for (String key : keySet) { System.out.println(key + ":" + map.get(key)); } System.out.println(TAG + ": end of parsing the information sent by the user"); /* * In this part, we try to reply text information and graphic messages to the user according to the required format of the document. Focus: Construct required parameters according to the document requirements. Special note: Parameters are case sensitive. */ // // Example 1: Send a normal text message, please check the xml format of the document about "reply text message" // // // Step 1: Construct the required parameters according to the reply text information // TextMsg textMsg = new TextMsg(); // textMsg.setToUserName(map.get("FromUserName"));// Send and receive the message "User" exactly the opposite // textMsg.setFromUserName(map.get("ToUserName")); // textMsg.setCreateTime(new Date().getTime());// Message creation time (integer) // textMsg.setMsgType("text");// Text type message// textMsg.setContent("I am the server reply to the user"); // // // // // // The second step is to convert the constructed information into the xml format recognized by WeChat [Baidu: xstream bean to xml] // XStream xStream = new XStream(); // xStream.alias("xml", textMsg.getClass()); // String textMsg2Xml = xStream.toXML(textMsg); // System.out.println(textMsg2Xml); // // // // // // // The third step is to send the format information of the xml to the WeChat server, and the server forwards it to the user // PrintWriter printWriter = resp.getWriter(); // printWriter.print(textMsg2Xml); // // Example 2, send graphic and text messages. Please check the document about the xml format of "Reply to the text message" // Step 1: Construct the required parameters according to the replies to the text message List<Article> articles = new ArrayList<Article>(); Article a = new Article(); a.setTitle("I am the picture title"); a.setUrl("www.baidu.com");// This address is after clicking on the picture and jumping a.setPicUrl("http://b.hiphotos.baidu.com/image/pic/item/08f790529822720ea5d058ba7ccb0a46f21fab50.jpg");// This address is a valid image address a.setDescription("I am the description of the image"); articles.add(a); PicAndTextMsg picAndTextMsg = new PicAndTextMsg(); picAndTextMsg.setToUserName(map.get("FromUserName"));// Send and receive the message "User" just the opposite picAndTextMsg.setFromUserName(map.get("ToUserName")); picAndTextMsg.setCreateTime(new Date().getTime());// Message creation time (integer) picAndTextMsg.setMsgType("news");// graphic type message picAndTextMsg.setArticleCount(1); picAndTextMsg.setArticles(articles); // The second step is to convert the constructed information into the xml format recognized by WeChat [Baidu: xstream bean to xml] XStream xStream = new XStream(); xStream.alias("xml", picAndTextMsg.getClass()); xStream.alias("item", a.getClass()); String picAndTextMsg2Xml = xStream.toXML(picAndTextMsg); System.out.println(picAndTextMsg2Xml); // The third step is to send the format information of the xml to the WeChat server, and the server forwards it to the user PrintWriter printWriter = resp.getWriter(); printWriter.print(picAndTextMsg2Xml); }}
•TestMsg.java (normal text message bean)
package com.gist.bean;/** * @author Gao Yuan</n> Email: [email protected]</n> Blog http://blog.csdn.net/wgyscsf</n> * Writing period 2016-4-4 2:09:27 pm */public class TextMsg { private String ToUserName; private String FromUserName; private long CreateTime; private String MsgType; @Override public String toString() { return "TextMsg [ToUserName=" + ToUserName + ", FromUserName=" + FromUserName + ", CreateTime=" + CreateTime + ", MsgType=" + MsgType + ", Content=" + Content + "]"; } private String Content; public TextMsg(String toUserName, String fromUserName, long createTime, String msgType, String content) { super(); ToUserName = toUserName; FromUserName = fromUserName; CreateTime = createTime; MsgType = msgType; Content = content; } public TextMsg() { super(); } 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 String getContent() { return Content; } public void setContent(String content) { Content = content; }}
•Article.java (Article bean inside the text message)
package com.gist.bean;/** * @author Gao Yuan</n> Email: [email protected]</n> Blog http://blog.csdn.net/wgyscsf</n> * Writing period 2016-4-4 2:47:08 pm */public class Article { private String Title; @Override public String toString() { return "item [Title=" + Title + ", Description=" + Description + ", PicUrl=" + PicUrl + ", Url=" + 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; } private String Description; private String PicUrl; private String Url;}
•PicAndTextMsg.java (graphic text message bean)
package com.gist.bean;import java.util.List;/** * @author Gao Yuan</n> Email: [email protected]</n> Blog http://blog.csdn.net/wgyscsf</n> * Writing period 2016-4-4 2:47:08 pm */public class PicAndTextMsg { private String ToUserName; private String FromUserName; private long CreateTime; private String MsgType; private int ArticleCount; private List<Article> Articles; @Override public String toString() { return "PicAndTextMsg [ToUserName=" + ToUserName + ", FromUserName=" + FromUserName + ", CreateTime=" + CreateTime + ", MsgType=" + MsgType + ", ArticleCount=" + ArticleCount + ", Articles=" + Articles + "]"; } 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 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; }}
The above is all the content of this article. I hope it will be helpful to everyone's learning and I hope everyone will support Wulin.com more.