Wechat public platform provides a great service model. Make the communication between users and businesses more convenient, can provide better membership services. Message push, preferential information push. It also provides the ability to customize menus. Let’s look at how to do development from a programmer’s perspective:
Platform structure:
When users operate mobile phones to send messages:
User APP(wechat) -> wechat public platform -> Website background developed by us (based on wechat public platform REST API development)
When the background replies to the message sent by the user:
User APP(wechat) <- wechat public platform <- Website background developed by us (based on wechat public platform REST API development)
Because it is based on wechat development. What we need to do is to build a website to receive and reply to “messages from the wechat public platform”, and the wechat public platform will send “messages” to the user’s phone.
How to do?
Prepare: Define a Servlet with a GET method that handles verifying message authenticity and a POST method that handles receiving and replying messages
Step 1: Verify message authenticity reference:Development of guidelines
To process a GET message, go to the following code:
/** * Verify that the message request is valid * @param request * @param Response * @throws IOException */ public void rerifyRequest(HttpServletRequest request, HttpServletResponse Response) throws IOException {if(token == null) throw new IllegalArgumentException(" Token not specified to validate "); ** After the developer submits the information, the wechat server will send a GET request to the filled URL with four parameters: * * Signature * wechat encryption signature. Signature combines the token parameter entered by the developer with the timestamp parameter and nonce parameter in the request. Timestamp * timestamp nonce random number echostr random string * the developer verifies the request by checking signature (see below). If you confirm that the GET request is from the wechat server *, please return the echostr parameter content as is. Then the access takes effect and you become a developer. Otherwise, the access fails. * * The encryption/verification process is as follows: 1. Lexicographically sort the token, TIMESTAMP, and nonce parameters. 2. * * */ Logger Logger = logger.getLogger ("pdwy"); Logger. log(level. INFO, "log start "); String signature = request.getParameter("signature"); String nonce = request.getParameter("nonce"); String timestamp = request.getParameter("timestamp"); String echostr = request.getParameter("echostr"); // logger.log(level. INFO, string. format(// "Received: signature=%s,nonce=%s,timestamp=%s,echostr=%s", signature, // nonce, timestamp, echostr)); if (null == signature || "".equals(signature)) { response.sendError(500); return; } String[] arrs = new String[] { token, timestamp, nonce }; Arrays.sort(arrs); StringBuilder sb = new StringBuilder(); for (int i = 0; i < arrs.length; i++) { sb.append(arrs[i]); } String newSignature = sha1(sb.toString()); if (signature.equals(newSignature)) { PrintWriter pw = response.getWriter(); pw.write(echostr); pw.close(); }}Copy the code
View Code
Step 2: Receive and reply messages
To process a POST message, use the following code:
/** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse * response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setCharacterEncoding("utf-8"); request.setCharacterEncoding("utf-8"); / / read the message String messageBody = readMessageBodyFromRequest (request); Loghelper. I ("\r\n Received the POST message: "+ messageBody); String replayMsgStr = handleMsg(messageBody); // Write message if (replaymsgid! = null) writeResponse(replayMsgStr, response); else writeResponse("", response); }Copy the code
View Code
We’re going to get some messages in XML format, and when we get a POST message, we need to parse it. How do we parse it? Here is an example of text message parsing:
/** * text message ** ToUserName FromUserName sender account (an OpenID) CreateTime Message creation time (integer) MsgType * text Content Text message Content MsgId @author yunfei * */ Public class TextMessage {/* * <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> */ public String ToUserName; public String FromUserName; public String CreateTime; public String MsgType = "text"; public String Content; public String MsgId; @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(String.format("%s=%s", "ToUserName", ToUserName)); sb.append(String.format("%s=%s", "FromUserName", FromUserName)); sb.append(String.format("%s=%s", "CreateTime", CreateTime)); sb.append(String.format("%s=%s", "MsgType", MsgType)); sb.append(String.format("%s=%s", "Content", Content)); sb.append(String.format("%s=%s", "MsgId", MsgId)); return sb.toString(); } public static TextMessage fromXml(String xml){ return TextMessageReader.readTextMessage(xml); } } class TextMessageReader { public static TextMessage readTextMessage(String xmlStr) { try { DocumentBuilderFactory factory = DocumentBuilderFactory .newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); InputSource inputSource = new InputSource(new StringReader( xmlStr)); inputSource.setEncoding("utf-8"); Document doc = builder.parse(inputSource); NodeList nl = doc.getElementsByTagName("xml"); if (nl ! = null && nl.getLength() > 0) { Element rootElement = (Element) nl.item(0); String ToUserName = rootElement .getElementsByTagName("ToUserName").item(0) .getTextContent(); String FromUserName = rootElement .getElementsByTagName("FromUserName").item(0) .getTextContent(); String CreateTime = rootElement .getElementsByTagName("CreateTime").item(0) .getTextContent(); String MsgType = rootElement.getElementsByTagName("MsgType") .item(0).getTextContent(); String Content = rootElement.getElementsByTagName("Content") .item(0).getTextContent(); String MsgId = rootElement.getElementsByTagName("MsgId") .item(0).getTextContent(); TextMessage bean; bean = new TextMessage(); bean.ToUserName = ToUserName; bean.FromUserName = FromUserName; bean.CreateTime = CreateTime; bean.MsgType = MsgType; bean.Content = Content; bean.MsgId = MsgId; return bean; } } catch (Exception e) { e.printStackTrace(); Loghelper. e("Error: "+ LLDB etMessage()); } return null; }}Copy the code
View Code
All right. We’ve finished parsing. We parse XML messages into entities, and then do our business processing according to different messages and different message content. When we receive “Hello”, we reply “Hello to you” and so on. Example:
package weixinmobile.services.handlers; import weixinFundation.core.common.WeixinMessageHandler; import weixinFundation.core.messages.MusicMessageReply; import weixinFundation.core.messages.TextAndImageMessageReply; import weixinFundation.core.messages.TextAndImageMessageReply.Article; import weixinFundation.core.messages.TextMessage; import weixinFundation.core.messages.TextMessageReply; import weixinFundation.core.utils.DateUtil; import weixinFundation.core.utils.LogHelper; import weixinmobile.services.handlers.TalkManager.TaskResponse; public class TextMessageHandler implements WeixinMessageHandler { @Override public boolean handleMsg(String messageType, String messageBody, WeixinMessageHandlerResult result) {/ / reading the message type, If ("text".equals(messageType)) {TextMessage MSG = textmessage.fromxml (messageBody); String content = msg.Content; TaskResponse response = new TaskResponse(); if ( TalkManager.talk(content, response)) { String replyMsgStr = response.content; TextMessageReply replayMsg = null; replayMsg = TextMessageReply.createTextReplyMessage(msg.ToUserName, msg.FromUserName, replyMsgStr); String replayMsgStr = replayMsg.toXml(); result.result = replayMsgStr; return true; } // When the user sends a message, there is no corresponding processing content. Default processing. TextMessageReply replayMsg = null; replayMsg = TextMessageReply.createTextReplyMessage(msg.ToUserName, msg.FromUserName, DEFALUT_MESSAGE); String replayMsgStr = replayMsg.toXml(); result.result = replayMsgStr; return true; } return false; } public static final String DEFALUT_MESSAGE = "please select your action as prompted :\r\n" + "1. Example graphic message. \r\n" + "2. \r\n" + "3. Contact information. \r\n" + "4. Reply to text message with hyperlink demo. \r\n" + "5. Example of reply to music message. \r\n"; } /** * @author yunfei ** / public class TalkManager {/** * @param Content * @return */ public static boolean talk(String content, TaskResponse response) {if (" 2 ". The equals (content) | | content. the contains (" company ")) {response. The content = "Beijing development co., LTD. -- -- -- -- -- - Department of Agricultural Resources Management "; return true; } else if (" 3 ". The equals (content) | | content. the contains (" phone ")) {response. The content = "we contact number is: 010 - XXXXX"; return true; }else if ("4".equals(content)) {response.content = "<a href='http://www.baidu.com'> details </a>"; return true; } return false; / / return the String. Format (" "% s"??? I didn't hear you. Say it again." , content); } public static class TaskResponse { public String content; }}Copy the code
View Code
The last step in processing a POST message is to write “the content of the reply to the POST is the content of the reply message”. We usually build a “reply message entity” and convert the entity into an XML string, which is written to the response stream. Example:
@author yunfei ** / public class TextMessageReply implements IReplyMessage{** < XML >< ToUserName><! [CDATA[toUser]]></ToUserName> <FromUserName><! [CDATA[fromUser]]></FromUserName> <CreateTime>12345678</CreateTime> <MsgType><! [CDATA[text]]></MsgType> <Content><! [CDATA]></Content> </ XML > * */ public String ToUserName; public String FromUserName; public String CreateTime; public String MsgType = "text"; public String Content; public String toXml() { return TextMessageReplyWriter.toXml(this); } --------------------------- class TextMessageReplyWriter { /** * <xml> <ToUserName><! [CDATA[toUser]]></ToUserName> * <FromUserName><! [CDATA[fromUser]]></FromUserName> * <CreateTime>12345678</CreateTime> <MsgType><! [CDATA[text]]></MsgType> * <Content><! [CDATA]></Content> </ XML > * * @param replayMsg * @return */ public static String toXml(TextMessageReply replayMsg) { DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder dbuilder = null; try { dbuilder = dbf.newDocumentBuilder(); } catch (Exception ex) { ex.printStackTrace(); } Document doc = dbuilder.newDocument(); Element root = doc.createElement("xml"); doc.appendChild(root); Element e; e = doc.createElement("ToUserName"); e.appendChild(doc.createCDATASection(replayMsg.ToUserName)); root.appendChild(e); e = doc.createElement("FromUserName"); e.appendChild(doc.createCDATASection(replayMsg.FromUserName)); root.appendChild(e); e = doc.createElement("CreateTime"); e.setTextContent(replayMsg.CreateTime); root.appendChild(e); e = doc.createElement("MsgType"); e.appendChild(doc.createCDATASection(replayMsg.MsgType)); root.appendChild(e); e = doc.createElement("Content"); e.appendChild(doc.createCDATASection(replayMsg.Content)); root.appendChild(e); StringWriter sw = new StringWriter(); XmlWriteUtil.callDomWriter(doc, sw, "utf-8"); String xmlRes = sw.getBuffer().toString(); return xmlRes; }}Copy the code
View Code
Writing the contents of the XML reply to the response flow completes a message response.
Still, much remains to be done. There are many other types of messages, as well as event handling. We need to do different message encapsulation for different messages, and encapsulate the various types of messages in the reply.
I wrote my own library, weinxinFundation,
- Realized the basic receiving message, reply message (text message, music message, etc.)
- Basic events (attention, geography, QR code scanning, etc.) encapsulated class library.
- Support for extensible message handlers that customize how messages are processed. Message implementation methods processor logic and class library logic are separated. Facilitate secondary development.
- In message list mode, a message that is not processed continues along the list until it is processed.
WeinxinFundation provides demo source code developed using the weinxinFundation framework, here you can also decomcompile to get my weinxinFundation source code.
Click on the download http://yunpan.cn/QaceVpHfIiInj access password 16 f1
The weinxinFundation source code is not available for free download, please contact me at [email protected]
My other articles:
Wechat public platform development – Basic chapter