The development of WeChat public account is generally aimed at enterprises and organizations. Individuals can only apply for subscription accounts, and the interfaces they call are limited. Let’s briefly describe the steps to access the public account :
1. First of all, you need an email address to register on the WeChat official account platform;
The registration methods include subscription accounts, official accounts, mini programs and corporate accounts. Individuals, we can only choose subscription accounts here.
2. After registration, we log in to the official account platform--->Development--->Basic configuration. You need to fill in the URL and token here. The URL is the interface where we use the server;
3. If the Java Web server program is compiled and deployed on the server and can be run, you can debug the online interface on the WeChat official account:
1) Select the appropriate interface
2) The system will generate a parameter table for this interface. You can directly fill in the corresponding parameter value in the text box (the red asterisk indicates that this field is required)
3) Click the Check Problem button to get the corresponding debugging information
eg: Steps to get access_token:
1) Interface type: Basic support
2) Interface list: Get access_token interface/token
3) Fill in the corresponding parameters: grant_type, appid, secret
4) Click to check the problem
5) The result and prompt will be returned after the verification is successful, and the result is: 200 ok, prompt: Request successful means the verification is successful
What we have more verification here is message interface debugging: text messages, picture messages, voice messages, video messages, etc.
4. If you don’t understand the interface, you can go to Development-->Developer Tools-->Developer Documents to query
5. Interface permissions: Subscription accounts mainly have basic support, message reception and some interfaces in web services.
Below we mainly talk about the case of how to receive messages by subscription accounts :
1. You need to apply for a personal WeChat subscription account
2. Url server and server-side code deployment (you can use Tencent Cloud or Alibaba Cloud Server)
1) AccountsServlet.java class to verify the message processing from the WeChat server and WeChat server
package cn.jon.wechat.servlet; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import cn.jon.wechat.service.AccountsService; import cn.jon.wechat.utils.SignUtil; public class AccountsServlet extends HttpServlet { public AccountsServlet() { super(); } public void destroy() { super.destroy(); // Put your code here } /** * Confirm the request comes from the WeChat server*/ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("Interface test starts!!!"); //WeChat encryption signature String signature = request.getParameter("signature"); //Timestamp String timestamp = request.getParameter("timestamp"); //Random number String nonce = request.getParameter("nonce"); //Random string String echostr = request.getParameter("echostr"); PrintWriter out = response.getWriter(); //Check the request by checking the signature. If the verification is successful, return echostr as it is, indicating that the access is successful, otherwise the access fails if(SignUtil.checkSignature(signature, timestamp, nonce)){ out.print(echostr); } out.close(); out = null; // response.encodeRedirectURL("success.jsp"); } /** * Process messages sent by WeChat server*/ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //Receive, process, and respond to message request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); //Calling core business type to accept messages and process messages String respMessage = AccountsService.processRequest(request); //Response message PrintWriter out = response.getWriter(); out.print(respMessage); out.close(); } public void init() throws ServletException { // Put your code here } } 2) SignUtil.java class, request verification tool class, the token needs to be consistent with the token filled in WeChat
package cn.jon.wechat.utils; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; /** * Request verification tool class* @author jon */ public class SignUtil { //Consistent with the Token in WeChat configuration private static String token = ""; public static boolean checkSignature(String signature, String timestamp, String nonce) { String[] array = new String[]{token,timestamp,nonce}; //Arrays.sort(arra); StringBuilder sb = new StringBuilder(); for(int i=0;i<arra.length;i++){ sb.append(arra[i]); } MessageDigest md = null; String stnStr = null; try { md = MessageDigest.getInstance("SHA-1"); byte[] digest = md.digest(sb.toString().getBytes()); stnStr = byteToStr(digest); } catch (NoSuchAlgorithmException e) { // TODO Auto-generated catch block e.printStackTrace(); } // Free memory sb = null; // Compare the encrypted string of sha1 with signature, identifying that the request comes from WeChat return stnStr!=null?stnStr.equals(signature.toUpperCase()):false; } /** * Convert byte array to hexadecimal string* @param digestArra * @return */ private static String byteToStr(byte[] digestArra) { // TODO Auto-generated method stub String digestStr = ""; for(int i=0;i<digestArra.length;i++){ digestStr += byteToHexStr(digestArra[i]); } return digestStr; } /** * Convert bytes to hexadecimal string*/ private static String byteToHexStr(byte dByte) { // TODO Auto-generated method stub char[] Digit = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'}; char[] tmpArr = new char[2]; tmpArr[0] = Digit[(dByte>>>4)&0X0F]; tmpArr[1] = Digit[dByte&0X0F]; String s = new String(tmpArr); return s; } public static void main(String[] args) { /*byte dByte = 'A'; System.out.println(byteToHexStr(dByte));*/ Map<String,String> map = new ConcurrentHashMap<String, String>(); map.put("4", "zhangsan"); map.put("100", "lisi"); Set set = map.keySet(); Iterator iter = set.iterator(); while(iter.hasNext()){ // String keyV = (String) iter.next(); String key =(String)iter.next(); System.out.println(map.get(key)); // System.out.println(map.get(iter.next())); } /*for(int i=0;i<map.size();i++){ }*/ } } 3) AccountsService.java service class, mainly for message request and response processing, and when users follow your official account, they can set default push messages
package cn.jon.wechat.service; import java.util.Date; import java.util.Map; import javax.servlet.http.HttpServletRequest; import cn.jon.wechat.message.req.ImageMessage; import cn.jon.wechat.message.req.LinkMessage; import cn.jon.wechat.message.req.LocationMessage; import cn.jon.wechat.message.req.VideoMessage; import cn.jon.wechat.message.req.VoiceMessage; import cn.jon.wechat.message.resp.TextMessage; import cn.jon.wechat.utils.MessageUtil; /** * Decoupling, separate the control layer from the business logic layer, mainly dealing with requests, and responding* @author jon */ public class AccountsService { public static String processRequest(HttpServletRequest request) { String respMessage = null; //The text message content returned by default String respContent = "Request handling exception, please try later!"; try { //xml request parsing Map<String,String> requestMap = MessageUtil.pareXml(request); //Sender account (open_id) String fromUserName = requestMap.get("FromUserName"); //Public account String toUserName = requestMap.get("ToUserName"); //Message type String msgType = requestMap.get("MsgType"); //Reply this text message by default TextMessage defaultTextMessage = new TextMessage(); defaultTextMessage.setToUserName(fromUserName); defaultTextMessage.setFromUserName(toUserName); defaultTextMessage.setCreateTime(new Date().getTime()); defaultTextMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_TEXT); defaultTextMessage.setFuncFlag(0); // Since the href attribute value must be caused in double quotes, this conflicts with the double quotes of the string itself, defaultTextMessage.setContent must be escaped("Welcome to <a href=/"http://blog.csdn.net/j086924/">jon's blog</a>!"); // defaultTextMessage.setContent(getMainMenu()); // Convert the text message object into the xml string respMessage = MessageUtil.textMessageToXml(defaultTextMessage); // Text message if(msgType.equals(MessageUtil.MESSSAGE_TYPE_TEXT)){ // respContent = "Hi, you are sending a text message! "; //Reply to text message TextMessage textMessage = new TextMessage(); // textMessage.setToUserName(toUserName); // textMessage.setFromUserName(fromUserName); // Note here, otherwise the message cannot be replied to the user textMessage.setToUserName(fromUserName); textMessage.setFromUserName(toUserName); textMessage.setCreateTime(new Date().getTime()); textMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_TEXT); textMessage.setFuncFlag(0); respContent = "Hi, the message you sent is: "+requestMap.get("Content"); textMessage.setContent(respContent); respMessage = MessageUtil.textMessageToXml(textMessage); } // Image message else if(msgType.equals(MessageUtil.MESSSAGE_TYPE_IMAGE)){ ImageMessage imageMessage=new ImageMessage(); imageMessage.setToUserName(fromUserName); imageMessage.setFromUserName(toUserName); imageMessage.setCreateTime(new Date().getTime()); imageMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_IMAGE); //respContent=requestMap.get("PicUrl"); imageMessage.setPicUrl("http://img24.pplive.cn//2013//07//24//12103112092_230X306.jpg"); respMessage = MessageUtil.imageMessageToXml(imageMessage); } //Geographic location else if(msgType.equals(MessageUtil.MESSSAGE_TYPE_LOCATION)){ LocationMessage locationMessage=new LocationMessage(); locationMessage.setToUserName(fromUserName); locationMessage.setFromUserName(toUserName); locationMessage.setCreateTime(new Date().getTime()); locationMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_LOCATION); locationMessage.setLocation_X(requestMap.get("Location_X")); locationMessage.setLocation_Y(requestMap.get("Location_Y")); locationMessage.setScale(requestMap.get("Scale")); locationMessage.setLabel(requestMap.get("Label")); respMessage = MessageUtil.locationMessageToXml(locationMessage); } //Video message else if(msgType.equals(MessageUtil.MESSSAGE_TYPE_VIDEO)){ VideoMessage videoMessage=new VideoMessage(); videoMessage.setToUserName(fromUserName); videoMessage.setFromUserName(toUserName); videoMessage.setCreateTime(new Date().getTime()); videoMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_VIDEO); videoMessage.setMediaId(requestMap.get("MediaId")); videoMessage.setThumbMediaId(requestMap.get("ThumbMediaId")); respMessage = MessageUtil.videoMessageToXml(videoMessage); } // Link Message else if(msgType.equals(MessageUtil.MESSSAGE_TYPE_LINK)){ LinkMessage linkMessage=new LinkMessage(); linkMessage.setToUserName(fromUserName); linkMessage.setFromUserName(toUserName); linkMessage.setCreateTime(new Date().getTime()); linkMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_LINK); linkMessage.setTitle(requestMap.get("Title")); linkMessage.setDescription(requestMap.get("Description")); linkMessage.setUrl(requestMap.get("Url")); respMessage = MessageUtil.linkMessageToXml(linkMessage); } //Voice message else if(msgType.equals(MessageUtil.MESSSAGE_TYPE_VOICE)){ VoiceMessage voiceMessage=new VoiceMessage(); voiceMessage.setToUserName(fromUserName); voiceMessage.setFromUserName(toUserName); voiceMessage.setCreateTime(new Date().getTime()); voiceMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_VOICE); voiceMessage.setMediaId(requestMap.get("MediaId")); voiceMessage.setFormat(requestMap.get("Format")); respMessage = MessageUtil.voiceMessageToXml(voiceMessage); } //Event push else if(msgType.equals(MessageUtil.MESSSAGE_TYPE_EVENT)){ //Event type String eventType = requestMap.get("Event"); //Subscribe if(eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)){ respContent = "Thank you for your attention! "; } //Unsubscribe else if(eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)){ // System.out.println("Unsubscribe"); } else if(eventType.equals(MessageUtil.EVENT_TYPE_CLICK)){ // Custom menu message processing System.out.println("Custom menu message processing"); } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return respMessage; } public static String getMainMenu() { StringBuffer buffer =new StringBuffer(); buffer.append("Hello, I am jon, please reply to the number selection service:").append("/n"); buffer.append("1. My blog").append("/n"); buffer.append("/n"); buffer.append("2. Song on demand").append("/n"); buffer.append("3. Classic Game").append("/n"); buffer.append("4. Chat and play cards").append("/n/n"); buffer.append("Reply"+"0"+"Show help menu"); return buffer.toString(); } } 4) MessageUtil.java help class, including constant definition and xml message conversion and processing
package cn.jon.wechat.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 cn.jon.wechat.message.req.ImageMessage; import cn.jon.wechat.message.req.LinkMessage; import cn.jon.wechat.message.req.LocationMessage; import cn.jon.wechat.message.req.VideoMessage; import cn.jon.wechat.message.req.VoiceMessage; import cn.jon.wechat.message.req.VoiceMessage; import cn.jon.wechat.message.resp.TextMessage; import cn.jon.wechat.message.resp.MusicMessage; import cn.jon.wechat.message.resp.TextMessage; import cn.jon.wechat.message.resp.TextMessage; import cn.jon.wechat.message.resp.TextMessage; import cn.jon.wechat.message.resp.TextMessage; 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; /** * Various message processing classes* @author jon */ public class MessageUtil { /** * Text type*/ public static final String MESSSAGE_TYPE_TEXT = "text"; /** * Music type*/ public static final String MESSSAGE_TYPE_MUSIC = "music"; /** * Picture type*/ public static final String MESSSAGE_TYPE_NEWS = "news"; /** * Video type*/ public static final String MESSSAGE_TYPE_VIDEO = "video"; /** * Image type*/ public static final String MESSSAGE_TYPE_IMAGE = "image"; /** * Link type*/ public static final String MESSSAGE_TYPE_LINK = "link"; /** * Geographic location type*/ public static final String MESSSAGE_TYPE_LOCATION = "location"; /** * Audio type*/ public static final String MESSSAGE_TYPE_VOICE = "voice"; /** * Push type*/ public static final String MESSSAGE_TYPE_EVENT = "event"; /** * Event type: subscribe (subscribe) */ public static final final String EVENT_TYPE_SUBSCRIBE = "subscribe"; /** * Event type: unsubscribe (unsubscribe) */ public static final String EVENT_TYPE_UNSUBSCRIBE = "unsubscribe"; /** * Event type: click (custom menu click event) */ public static final String EVENT_TYPE_CLICK= "CLICK"; /** * * Parsing request XML sent by WeChat */ @SuppressWarnings("unchecked") public static Map<String,String> pareXml(HttpServletRequest request) throws Exception { //Storage the parsed result in HashMap Map<String,String> reqMap = new HashMap<String, String>(); //Get the input stream from the request InputStream inputStream = request.getInputStream(); //Read the input stream SAXReader reader = new SAXReader(); Document document = reader.read(inputStream); //Get the xml root element Element root = document.getRootElement(); //Get all child nodes of the root element List<Element> elementList = root.elements(); //Transfuse all child nodes to obtain information class content for(Element elem:elementList){ reqMap.put(elem.getName(),elem.getText()); } //Release the resource inputStream.close(); inputStream = null; return reqMap; } /** * Convert the response message to xml to return * Text object to xml */ public static String textMessageToXml(TextMessage textMessage) { xstream.alias("xml", textMessage.getClass()); return xstream.toXML(textMessage); } /** * Conversion of voice object to xml * */ public static String voiceMessageToXml(VoiceMessage voiceMessage) { xstream.alias("xml", voiceMessage.getClass()); return xstream.toXML(voiceMessage); } /** * Conversion of video object to xml * */ public static String videoMessageToXml(VideoMessage videoMessage) { xstream.alias("xml", videoMessage.getClass()); return xstream.toXML(videoMessage); } /** * Conversion of music objects to xml * */ public static String musicMessageToXml(MusicMessage musicMessage) { xstream.alias("xml", musicMessage.getClass()); return xstream.toXML(musicMessage); } /** * Conversion of graphic objects to xml * */ public static String newsMessageToXml(NewsMessage newsMessage) { xstream.alias("xml", newsMessage.getClass()); xstream.alias("item", new Article().getClass()); return xstream.toXML(newsMessage); } /** * Convert the image object to xml * */ public static String imageMessageToXml(ImageMessage imageMessage) { xstream.alias("xml",imageMessage.getClass()); return xstream.toXML(imageMessage); } /** * Convert the link object to xml * */ public static String linkMessageToXml(LinkMessage linkMessage) { xstream.alias("xml",linkMessage.getClass()); return xstream.toXML(linkMessage); } /** * Convert the geolocation object to xml * */ public static String locationMessageToXml(LocationMessage locationMessage) { xstream.alias("xml",locationMessage.getClass()); return xstream.toXML(locationMessage); } /** * Expand xstream to support CDATA blocks* */ private static XStream xstream = new XStream(new XppDriver(){ public HierarchicalStreamWriter createWriter(Writer out){ return new PrettyPrintWriter(out){ //Add CDATA tag to all xml nodes 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); } } }; } }); } 5) BaseMessage.java message base class (including: developer WeChat account, user account, creation time, message type, message ID variable), text, video, and image messages will inherit this base class, and on this basis, it will expand its own variables and can be defined based on various message attributes in the developer's document.
package cn.jon.wechat.message.req; /** * Message base class (ordinary user-public account) * @author jon */ public class BaseMessage { //Developer WeChat ID private String ToUserName; //Sender account (one openId) private String FromUserName; //Message creation time (integer) private long CreateTime; //Message type (text/image/location/link...) private String MsgType; //Message id 64-bit integer private String MsgId; public BaseMessage() { super(); // TODO Auto-generated constructor stub } public BaseMessage(String toUserName, String fromUserName, long createTime, String msgType, String msgId) { super(); ToUserName = toUserName; FromUserName = fromUserName; CreateTime = createTime; MsgType = msgType; MsgId = 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 String getMsgId() { return MsgId; } public void setMsgId(String msgId) { MsgId = msgId; } } 6) TextMessage.java text message, inherited from the base class in 5, extending content attributes
package cn.jon.wechat.message.req; /** * Text message* @author jon */ public class TextMessage extends BaseMessage{ //Message content private String content; public String getContent() { return content; } public void setContent(String content) { this.content = content; } }7) ImageMessage.java image message
package cn.jon.wechat.message.req; /** * Image Message* @author jon */ public class ImageMessage extends BaseMessage{ //Pic link private String PicUrl; public String getPicUrl() { return PicUrl; } public void setPicUrl(String picUrl) { PicUrl = picUrl; } } 8) VideoMessage.java video message
package cn.jon.wechat.message.req; public class VideoMessage extends BaseMessage { private String mediaId; private String thumbMediaId; public String getMediaId() { return mediaId; } public void setMediaId(String mediaId) { this.mediaId = mediaId; } public String getThumbMediaId() { return thumbMediaId; } public void setThumbMediaId(String thumbMediaId) { this.thumbMediaId = thumbMediaId; } }Other message classes can be completed by themselves based on the developer's documentation. In addition, developers can also apply for a public platform test account to test the relevant content of the development.
This article has been compiled into "Android WeChat Development Tutorial Summary", and "Java WeChat Development Tutorial Summary" welcomes everyone to learn and read.
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.