In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-01 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article will explain in detail the sample analysis of how to get started with Wechat development. The editor thinks it is very practical, so I share it with you for reference. I hope you can get something after reading this article.
I. the basic principles of Wechat public platform
Before starting to do it, the basic principles of Wechat public platform are briefly introduced.
Wechat server is like a forwarding server. The terminal (mobile phone, Pad, etc.) initiates a request to Wechat server, and Wechat server then forwards the request to our application server. After the application server has finished processing, the response data is sent back to the Wechat server, and the Wechat server replies the specific response information to the Wechat App terminal.
The communication protocol is: HTTP
The data transfer format is: XML
The specific process is shown in the following figure:
Let's take a more intuitive picture:
What we need to do is to respond to the HTTP request forwarded by the Wechat server. The specific request content is parsed according to the specific XML format, and after processing, it is also returned according to the specific XML format.
II. Access to the official account of Wechat
In the Wechat public platform developer documentation, the section on the access of official accounts is written in more detail in the access guide. It is said in the document that three steps are required to connect official accounts, which are:
1. Fill in the server configuration
2. Verify the validity of the server address
3. Realize the business logic according to the interface document
In fact, step 3 can no longer be counted as an official account access step, but after the access, developers can do some development according to the interface provided by the Wechat official account.
The server configuration in step 1 includes the server address (URL), Token, and EncodingAESKey.
The server address is the entry address of the business logic provided by the official account backend. Currently, only port 80 is supported. Requests including access verification and any other operations (such as message sending, menu management, material management, etc.) should be entered from this address. The difference between access authentication and other requests is that access authentication is a get request, and other times it is a post request.
The Token can be entered by the developer as a signature (the Token is compared with the Token contained in the interface URL to verify the security)
EncodingAESKey is manually filled in or randomly generated by developers and will be used as the encryption and decryption key of the message body. In this example, it is all in the form of unencrypted plaintext messages, and this configuration item is not involved.
Step 2, verify the validity of the server address. When the "submit" button is clicked, the Wechat server will send a get request for http to the server address just entered with four parameters:
After receiving the request, we need to take the following three steps. If we confirm that the GET request is from Wechat server and return the echostr parameter content as is, the connection will take effect, otherwise the connection will fail.
1. The three parameters token, timestamp and nonce are sorted in dictionary order.
two。 Concatenate three parameter strings into one string for sha1 encryption
3. The encrypted string obtained by the developer can be compared with signature, indicating that the request originated from Wechat
Let's demonstrate this verification process with Java code.
Create a JavaWeb project using IDE (Eclipse or IntelliJ IDEA). Here I use IntelliJ IDEA, and the project directory structure is shown in the following figure:
Write a servlevt in which the check method is defined in the doGet method, as follows:
Package me.gacl.wx.web.servlet;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 java.io.IOException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;import java.util.Arrays;/** * Created by xdp on 2016-1-25. * configure the WxServlet,urlPatterns attribute with @ WebServlet annotation to indicate the access path to WxServlet * / @ WebServlet (urlPatterns= "/ WxServlet") public class WxServlet extends HttpServlet {/ * Token can be entered by the developer and used as a signature (the Token is compared with the Token contained in the interface URL to verify security) * for example, here I set Token to gacl * / private final String TOKEN = "gacl" Protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {} protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {System.out.println ("start verifying signature"); / * * 4 parameters passed when receiving a request sent by Wechat server * / String signature = request.getParameter ("signature") / / Wechat encryption signature signature combines the token parameter entered by the developer with the timestamp parameter and nonce parameter in the request. String timestamp = request.getParameter ("timestamp"); / / timestamp String nonce = request.getParameter ("nonce"); / / Random number String echostr = request.getParameter ("echostr"); / / Random string / / sort String sortString = sort (TOKEN, timestamp, nonce); / / encrypted String mySignature = sha1 (sortString) / / verify the signature if (mySignature! = null & & mySignature! = "& & mySignature.equals (signature)) {System.out.println (" signature verification passed. ") ; / / if the verification succeeds in outputting echostr, the Wechat server will receive the output before confirming that the verification is complete. / / response.getWriter () .println (echostr); response.getWriter () .write (echostr);} else {System.out.println ("signature verification failed.") }} / * sorting method * * @ param token * @ param timestamp * @ param nonce * @ public String sort (String token, String timestamp, String nonce) {String [] strArray = {token, timestamp, nonce}; Arrays.sort (strArray); StringBuilder sb = new StringBuilder () For (String str: strArray) {sb.append (str);} return sb.toString () } / * sha1 encryption of strings * * @ string that needs to be encrypted by param str * @ return encrypted content * / public String sha1 (String str) {try {MessageDigest digest = MessageDigest.getInstance ("SHA-1"); digest.update (str.getBytes ()); byte messageDigest [] = digest.digest () / / Create Hex String StringBuffer hexString = new StringBuffer (); / / Byte array is converted 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); } return hexString.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; }} 我这里用的Servlet3.0,使用Servlet3.0的好处就是可以直接使用@WebServlet注解映射Servlet的访问路径,不再需要在web.xml文件中进行配置. 将WxStudy项目部署到Tomcat服务器中运行,直接启动项目,然后用ngrok将本地8080端口映射到外网(如何使用ngrok请参考博客《微信开发-微信开发环境搭建》)。如下图所示:Test whether it can be accessed properly through the http://xdp.ngrok.natapp.cn address. The test results are as follows:
As you can see, our project can be accessed normally by the external network.
Enter the official account management interface of Wechat test, and enter the mapped public network address and token in the interface configuration information, as shown below:
Click the submit button, and the page will indicate that the configuration is successful.
The verified information is output in the console of IDE, as shown in the following figure:
At this point, our official account application has been able to communicate normally with the Wechat server, that is to say, our official account has been connected to the Wechat public platform.
III. Introduction to access_token Management 3.1and access_token
After the successful connection between our official account and Wechat server, the next thing we need to do is to call the interface provided by Wechat official account to implement the corresponding logic according to our business needs. You need an access_token when using the official account of Wechat.
About access_token, please see the API call credentials in the Wechat public platform developer documentation for more details: access_token is the only global ticket for the official account, and the official account needs to use access_token when calling each API. Developers need to keep the access_token storage at least 512 characters. The access_token is valid for 2 hours and needs to be refreshed regularly. Repeated acquisition will invalidate the last acquired access_token. And the maximum number of calls to get access_token API is 2000 times per day.
To sum up, access_token needs to do the following two things:
1. Because access_token has a timeliness of 2 hours, there should be a mechanism to ensure that it can be reacquired in a maximum of 2 hours.
two。 Because the maximum number of calls to the interface is 2000 per day, it cannot be called too frequently.
3.2.The API for obtaining access_token provided by Wechat public platform
As for how to obtain access_token, there are instructions in the Wechat public platform developer's documentation that the official account can call an API called "get access token" to obtain access_token.
Get the access token API call request description
Http request method: GET
Requested URL address: https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
We can see that appID, AppSecret,appID and AppSecret are automatically assigned to the official account when applying for the official account, which is equivalent to the identity of the official account. Using the registered account of Wechat to log in to the Wechat official account management backend provided by Tencent, you can see the AppID and AppSecret of the official account you applied for, as shown below:
This is the AppID and AppSecret assigned to me when I applied for the official account test account.
3.3.Obtain the access_token scheme and its implementation
The solution here is to define a default startup servlet and start a Thread in the init method. In this process, an infinite loop method is defined to obtain the access_token. When the process is successfully obtained, the process hibernates for 7000 seconds (7000 seconds = 1.9444444444444 hours), otherwise dormant for 3 seconds to continue to obtain. The flow chart is as follows:
Now we officially start to implement the above ideas in the project, because the returned data are all in json format. Ali's fastjson library will be used here to provide support for data serialization and deserialization after constructing and processing requests.
1. Define an AccessToken entity class
Package me.gacl.wx.entry;/** * AccessToken data model * Created by xdp on 2016-1-25. * private String accessToken; / / the valid time of the credential obtained by public class AccessToken {/ /, in seconds: private int expiresin; public String getAccessToken () {return accessToken;} public void setAccessToken (String accessToken) {this.accessToken = accessToken;} public int getExpiresin () {return expiresin;} public void setExpiresin (int expiresin) {this.expiresin = expiresin;}}
two。 Define an AccessTokenInfo class to store the acquired AccessToken. The code is as follows:
Package me.gacl.wx.Common;import me.gacl.wx.entry.AccessToken;/** * Created by xdp on 2016-1-25. * / public class AccessTokenInfo {/ / Note: static public static AccessToken accessToken = null;}
3. Write a utility class NetWorkHelper for initiating https requests with the following code:
Package me.gacl.wx.util;import javax.net.ssl.*;import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.net.URL;import java.security.cert.CertificateException;import java.security.cert.X509Certificate / * tools used to access the network * / public class NetWorkHelper {/ * the URL address of the Https request * @ param reqUrl request * @ param requestMethod * @ return response string * / public String getHttpsResponse (String reqUrl, String requestMethod) {URL url; InputStream is; String resultData = "" Try {url = new URL (reqUrl); HttpsURLConnection con = (HttpsURLConnection) url.openConnection (); TrustManager [] tm = {xtm}; SSLContext ctx = SSLContext.getInstance ("TLS"); ctx.init (null, tm, null); con.setSSLSocketFactory (ctx.getSocketFactory ()) Con.setHostnameVerifier (new HostnameVerifier () {@ Override public boolean verify (String arg0, SSLSession arg1) {return true;}}); con.setDoInput (true) / / allow input stream, that is, allow download / / this must be set to false con.setDoOutput (false) in android; / / allow output stream, that is, allow upload of con.setUseCaches (false); / / do not use buffered if (null! = requestMethod & &! requestMethod.equals (")) {con.setRequestMethod (requestMethod) / / use the specified method} else {con.setRequestMethod ("GET"); / / use the get request} is = con.getInputStream (); / / get the input stream, and then establish the link InputStreamReader isr = new InputStreamReader (is); BufferedReader bufferReader = new BufferedReader (isr); String inputLine While ((inputLine = bufferReader.readLine ())! = null) {resultData + = inputLine + "\ n";} System.out.println (resultData);} catch (Exception e) {e.printStackTrace ();} return resultData } X509TrustManager xtm = new X509TrustManager () {@ Override public X509Certificate [] getAcceptedIssuers () {return null;} @ Override public void checkServerTrusted (X509Certificate [] arg0, String arg1) throws CertificateException {} @ Override public void checkClientTrusted (X509Certificate [] arg0, String arg1) throws CertificateException {}};}
The getHttpsResponse method requests a https address, and the parameter requestMethod is the string "GET" or "POST". Pass null or "" to get by default.
4. Define a servlet that starts by default and start a new thread in the init method to get the accessToken
Package me.gacl.wx.web.servlet;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONObject;import me.gacl.wx.Common.AccessTokenInfo;import me.gacl.wx.entry.AccessToken;import me.gacl.wx.util.NetWorkHelper;import javax.servlet.ServletException;import javax.servlet.annotation.WebInitParam;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;/** * Servlet used to obtain accessToken * Created by xdp on 2016-1-25. * / @ WebServlet (name = "AccessTokenServlet", urlPatterns = {"/ AccessTokenServlet"}, loadOnStartup = 1, initParams = {@ WebInitParam (name = "appId", value = "wxbe4d433e857e8bb1"), @ WebInitParam (name = "appSecret", value = "ccbc82d560876711027b3d43a6f2ebda")} public class AccessTokenServlet extends HttpServlet {@ Override public void init () throws ServletException {System.out.println ("launch WebServlet") Super.init (); final String appId = getInitParameter ("appId"); final String appSecret = getInitParameter ("appSecret") / / start a new thread new Thread (new Runnable () {@ Override public void run () {while (true) {try {/ / get accessToken AccessTokenInfo.accessToken = getAccessToken (appId, appSecret)) / / obtain successful if (AccessTokenInfo.accessToken! = null) {/ / get access_token hibernation for 7000 seconds, about 2 hours Thread.sleep (7000 * 1000); / / Thread.sleep (10 * 1000) / / get once every 10 seconds} else {/ / get failed Thread.sleep (1000 * 3) / / the access_token obtained is empty sleep for 3 seconds}} catch (Exception e) {System.out.println ("exception occurs:" + e.getMessage ()); e.printStackTrace () Try {Thread.sleep (1000 * 10); / / abnormal hibernation for 1 second} catch (Exception E1) {}) .start () } / * * get access_token * * @ return AccessToken * / private AccessToken getAccessToken (String appId, String appSecret) {NetWorkHelper netHelper = new NetWorkHelper (); / * API address is https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET, where grant_type is always written as client_credential. * / String Url = String.format ("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", appId, appSecret); / / this request is a get request of https. The returned data format is {" access_token ":" ACCESS_TOKEN "," expires_in ": 7200} String result = netHelper.getHttpsResponse (Url,"). System.out.println ("acquired access_token=" + result); / / use FastJson to parse Json strings into Json objects JSONObject json = JSON.parseObject (result); AccessToken token= new AccessToken (); token.setAccessToken (json.getString ("access_token")); token.setExpiresin (json.getInteger ("expires_in")); return token;}}
AccessTokenServlet is configured with annotations.
After the implementation of the code is complete, deploy the project and see the console output as follows:
To make it easier to see the effect, you can set the sleep time to be shorter, such as getting it once in 10 seconds, and then output the access_token.
Let's test the jsp page and set the sleep time to 10 seconds, so that we can refresh the page in 10 seconds and see the change.
The access_token of Wechat Learning is:
After 10 seconds, the page is refreshed and the access_token changes, as shown in the following figure:
Receive and respond to messages sent by Wechat server
After the above three steps, our preparatory work before development has been completed, and the next thing we need to do is to receive the message sent by the Wechat server and respond.
We can learn from the Wechat Public platform Interface message Guide that when a user sends a message to a public account, the Wechat server will submit the message to the URL entered in the interface configuration information through POST, and we need to receive the message, process the message and respond to the message in the doPost method of the request processing class WxServlet pointed to by the URL.
4.1. Write a tool class for handling messages
Write a toolbar to process messages. The tool class code is as follows:
Package me.gacl.wx.util;import org.dom4j.Document;import org.dom4j.Element;import org.dom4j.io.SAXReader;import javax.servlet.http.HttpServletRequest;import java.io.InputStream;import java.text.DateFormat;import java.text.SimpleDateFormat;import java.util.Date;import java.util.HashMap;import java.util.List;import java.util.Map;/** * message processing tool class * Created by xdp on 2016-1-26. * / public class MessageHandlerUtil {/ * parse the request sent by Wechat (XML) * @ param request * @ return map * @ throws Exception * / public static Map parseXml (HttpServletRequest request) throws Exception {/ / store the parsing result in HashMap Map map = new HashMap (); / / get the input stream InputStream inputStream = request.getInputStream () from request System.out.println ("get input stream"); / / read the input stream SAXReader reader = new SAXReader (); Document document = reader.read (inputStream); / / get the xml root element Element root = document.getRootElement (); / / get all the child nodes of the root element List elementList = root.elements () / / traverse all child nodes for (Element e: elementList) {System.out.println (e.getName () + "|" + e.getText ()); map.put (e.getName (), e.getText ());} / / release resource inputStream.close (); inputStream = null; return map } / / the return message public static String buildXml (Map map) {String result; String msgType = map.get ("MsgType") .toString (); System.out.println ("MsgType:" + msgType) is constructed according to the message type If (msgType.toUpperCase (). Equals ("TEXT")) {result = buildTextMessage (map, "Lonely Wolf is learning and summing up Wechat development and building a text message: Hello World!");} else {String fromUserName = map.get ("FromUserName"); / / developer Wechat String toUserName = map.get ("ToUserName") Result = String .format ("" + "% s" + "" + " FromUserName, toUserName, getUtcTime (), "Please reply with the following keywords:\ ntext\ nPicture\ nVoice\ nVideo\ nMusic\ nPicture and text") } return result;} / * construct a text message * * @ param map * @ param content * @ return * / private static String buildTextMessage (Map map, String content) {/ / sender account String fromUserName = map.get ("FromUserName"); / / developer Wechat String toUserName = map.get ("ToUserName") / * * text message XML data format * 1348831860 1234567890123456 * / return String.format ("+" + "" + "% s" + "+"+" FromUserName, toUserName, getUtcTime (), content) } private static String getUtcTime () {Date dt = new Date (); / / if the format is not needed, you can directly use dt,dt as the current system time DateFormat df = new SimpleDateFormat ("yyyyMMddhhmm"); / / set the display format String nowTime = df.format (dt); long dd = (long) 0; try {dd = df.parse (nowTime). GetTime () } catch (Exception e) {} return String.valueOf (dd);}}
In order to facilitate the parsing of the xml format data sent to us by the Wechat server, here we parse xml with the help of the open source framework dom4j (dom4j-2.0.0-RC1.jar is used here)
4.2. Process the request in the doPost method of WxServlet
The code for the doPost method of WxServlet is as follows:
/ * handle messages sent by Wechat server * / protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {/ / TODO receives, processes and responds to messages forwarded by Wechat server users to public accounts / / sets the code of request and response to UTF-8 (prevent Chinese garbled) request.setCharacterEncoding ("UTF-8") Response.setCharacterEncoding ("UTF-8"); System.out.println ("request entry"); String result = ""; try {Map map = MessageHandlerUtil.parseXml (request); System.out.println ("start Construction message"); result = MessageHandlerUtil.buildXml (map); System.out.println (result) If (result.equals (")) {result =" incorrect response ";}} catch (Exception e) {e.printStackTrace (); System.out.println (" exception occurs: "+ e.getMessage ());} response.getWriter () .println (result);}
At this point, our WxServlet can normally process the user's request and respond. Next, let's test whether the official account application we developed can interact with Wechat users properly.
Deploy WxStudy to the Tomcat server, start the server, and remember to use ngrok to map port 8080 of the local Tomcat server to the public network to ensure the URL address of the interface configuration information: http://xdp.ngrok.natapp.cn/WxServlet can communicate with the Wechat server normally.
Log in to the administrative backend of our test official account, and then scan the QR code of the test account with Wechat, as shown below:
After following successfully, the official account application we developed will first send a text message prompting the user to take action, and Wechat users will enter "text" according to the prompt. After receiving the user's request, our official account app will reply to the user a text message that we have built, as shown below:
The XML data of the text message sent by our official account application to Wechat users is as follows:
1453755900000
The management background of the test official account can also see the list of users who follow the test account, as shown in the following figure:
This is the end of the article on "sample Analysis of getting started with Wechat Development". I hope the above content can be helpful to you, so that you can learn more knowledge. if you think the article is good, please share it for more people to see.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.