Home > Article > WeChat Applet > Using java to develop WeChat public account case code
This article uses Java to develop the WeChat public account case code, how to access the public account, how about the subscription accountReceive messages, has certain reference value, interested friends can refer to it
WeChat public account development is generally aimed at enterprises and organizations. Individuals can generally only apply for a subscription account, and the interface called is limited. Let’s briefly describe the access. Steps for public account :
1. First, you need an email address to register on the WeChat public account platform;
Registration methods include subscription account, public account, mini program and enterprise account , personally we can only choose the subscription account
2. After registration, we log in to the official account platform --->Development--->Basic configuration, here we need to fill in the URL and token , the URL is the interface we use the server;
3. If the Java Web server program is compiled and deployed on the server and can run, the online interface can be performed on the WeChat official accountDebugging :
1). Select the appropriate interface
2) The system will generate the parameter table of the interface. You can directly fill in the corresponding parameter value in the text box (red asterisk indicates This field is required)
3) Click the Check Problem button to get the corresponding debugging information
eg: Steps to obtain 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 Question
5) If the verification is successful, the result and prompt will be returned. The result is: 200 ok. The prompt: Request successful means the verification is successful.
What we verify more here is the message interface debugging: text Messages, picturesmessages, voice messages, videomessages, etc
4. If you don’t understand the interface, you can enter development-->Development Developer tools-->Developer documentation for query
5. Interface permissions: Subscription accounts mainly have basic support, receiving messages and some interfaces in web services
Below we will mainly talk about the case of how subscription accounts receive messages:
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, verification comes from WeChat Message processing of the 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 } /** * 确认请求来自于微信服务器 */ public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("接口测试开始!!!"); //微信加密签名 String signature = request.getParameter("signature"); //时间戳 String timestamp = request.getParameter("timestamp"); //随机数 String nonce = request.getParameter("nonce"); //随机字符串 String echostr = request.getParameter("echostr"); PrintWriter out = response.getWriter(); //通过校验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败 if(SignUtil.checkSignature(signature,timestamp,nonce)){ out.print(echostr); } out.close(); out = null; // response.encodeRedirectURL("success.jsp"); } /** * 处理微信服务器发来的消息 */ public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //消息的接受、处理、响应 request.setCharacterEncoding("utf-8"); response.setCharacterEncoding("utf-8"); //调用核心业务类型接受消息、处理消息 String respMessage = AccountsService.processRequest(request); //响应消息 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; /** * 请求校验工具类 * @author jon */ public class SignUtil { //与微信配置中的的Token一致 private static String token = ""; public static boolean checkSignature(String signature, String timestamp, String nonce) { String[] arra = new String[]{token,timestamp,nonce}; //将signature,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(); } //释放内存 sb = null; //将sha1加密后的字符串与signature对比,标识该请求来源于微信 return stnStr!=null?stnStr.equals(signature.toUpperCase()):false; } /** * 将字节数组转换成十六进制字符串 * @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; } /** * 将字节转换成为十六进制字符串 */ 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 the user follows your official account, you can set the default Push message
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; /** * 解耦,使控制层与业务逻辑层分离开来,主要处理请求,响应 * @author jon */ public class AccountsService { public static String processRequest(HttpServletRequest request) { String respMessage = null; //默认返回的文本消息内容 String respContent = "请求处理异常,请稍后尝试!"; try { //xml请求解析 Map<String,String> requestMap = MessageUtil.pareXml(request); //发送方账号(open_id) String fromUserName = requestMap.get("FromUserName"); //公众账号 String toUserName = requestMap.get("ToUserName"); //消息类型 String msgType = requestMap.get("MsgType"); //默认回复此文本消息 TextMessage defaultTextMessage = new TextMessage(); defaultTextMessage.setToUserName(fromUserName); defaultTextMessage.setFromUserName(toUserName); defaultTextMessage.setCreateTime(new Date().getTime()); defaultTextMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_TEXT); defaultTextMessage.setFuncFlag(0); // 由于href属性值必须用双引号引起,这与字符串本身的双引号冲突,所以要转义 defaultTextMessage.setContent("欢迎访问<a href=\"http://blog.csdn.net/j086924\">jon的博客</a>!"); // defaultTextMessage.setContent(getMainMenu()); // 将文本消息对象转换成xml字符串 respMessage = MessageUtil.textMessageToXml(defaultTextMessage); //文本消息 if(msgType.equals(MessageUtil.MESSSAGE_TYPE_TEXT)){ //respContent = "Hi,您发送的是文本消息!"; //回复文本消息 TextMessage textMessage = new TextMessage(); // textMessage.setToUserName(toUserName); // textMessage.setFromUserName(fromUserName); //这里需要注意,否则无法回复消息给用户了 textMessage.setToUserName(fromUserName); textMessage.setFromUserName(toUserName); textMessage.setCreateTime(new Date().getTime()); textMessage.setMsgType(MessageUtil.MESSSAGE_TYPE_TEXT); textMessage.setFuncFlag(0); respContent = "Hi,你发的消息是:"+requestMap.get("Content"); textMessage.setContent(respContent); respMessage = MessageUtil.textMessageToXml(textMessage); } //图片消息 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); } //地理位置 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); } //视频消息 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); } //链接消息 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); } //语音消息 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); } //事件推送 else if(msgType.equals(MessageUtil.MESSSAGE_TYPE_EVENT)){ //事件类型 String eventType = requestMap.get("Event"); //订阅 if(eventType.equals(MessageUtil.EVENT_TYPE_SUBSCRIBE)){ respContent = "谢谢关注!"; } //取消订阅 else if(eventType.equals(MessageUtil.EVENT_TYPE_UNSUBSCRIBE)){ // System.out.println("取消订阅"); } else if(eventType.equals(MessageUtil.EVENT_TYPE_CLICK)){ //自定义菜单消息处理 System.out.println("自定义菜单消息处理"); } } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } return respMessage; } public static String getMainMenu() { StringBuffer buffer =new StringBuffer(); buffer.append("您好,我是jon,请回复数字选择服务:").append("\n"); buffer.append("1、我的博客").append("\n"); buffer.append("2、 歌曲点播").append("\n"); buffer.append("3、 经典游戏").append("\n"); buffer.append("4 、聊天打牌").append("\n\n"); buffer.append("回复"+"0"+"显示帮助菜单"); return buffer.toString(); } }
4), MessageUtil.java help class, including definition of constants 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.resp.Article; import cn.jon.wechat.message.resp.MusicMessage; import cn.jon.wechat.message.resp.NewsMessage; 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; /** * 各种消息的处理类 * @author jon */ public class MessageUtil { /** * 文本类型 */ public static final String MESSSAGE_TYPE_TEXT = "text"; /** * 音乐类型 */ public static final String MESSSAGE_TYPE_MUSIC = "music"; /** * 图文类型 */ public static final String MESSSAGE_TYPE_NEWS = "news"; /** * 视频类型 */ public static final String MESSSAGE_TYPE_VIDEO = "video"; /** * 图片类型 */ public static final String MESSSAGE_TYPE_IMAGE = "image"; /** * 链接类型 */ public static final String MESSSAGE_TYPE_LINK = "link"; /** * 地理位置类型 */ public static final String MESSSAGE_TYPE_LOCATION = "location"; /** * 音频类型 */ public static final String MESSSAGE_TYPE_VOICE = "voice"; /** * 推送类型 */ public static final String MESSSAGE_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 */ @SuppressWarnings("unchecked") public static Map<String,String> pareXml(HttpServletRequest request) throws Exception { //将解析的结果存储在HashMap中 Map<String,String> reqMap = 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 elem:elementList){ reqMap.put(elem.getName(),elem.getText()); } //释放资源 inputStream.close(); inputStream = null; return reqMap; } /** * 响应消息转换成xml返回 * 文本对象转换成xml */ public static String textMessageToXml(TextMessage textMessage) { xstream.alias("xml", textMessage.getClass()); return xstream.toXML(textMessage); } /** * 语音对象的转换成xml * */ public static String voiceMessageToXml(VoiceMessage voiceMessage) { xstream.alias("xml", voiceMessage.getClass()); return xstream.toXML(voiceMessage); } /** * 视频对象的转换成xml * */ public static String videoMessageToXml(VideoMessage videoMessage) { xstream.alias("xml", videoMessage.getClass()); return xstream.toXML(videoMessage); } /** * 音乐对象的转换成xml * */ public static String musicMessageToXml(MusicMessage musicMessage) { xstream.alias("xml", musicMessage.getClass()); return xstream.toXML(musicMessage); } /** * 图文对象转换成xml * */ public static String newsMessageToXml(NewsMessage newsMessage) { xstream.alias("xml", newsMessage.getClass()); xstream.alias("item", new Article().getClass()); return xstream.toXML(newsMessage); } /** * 图片对象转换成xml * */ public static String imageMessageToXml(ImageMessage imageMessage) { xstream.alias("xml",imageMessage.getClass()); return xstream.toXML(imageMessage); } /** * 链接对象转换成xml * */ public static String linkMessageToXml(LinkMessage linkMessage) { xstream.alias("xml",linkMessage.getClass()); return xstream.toXML(linkMessage); } /** * 地理位置对象转换成xml * */ public static String locationMessageToXml(LocationMessage locationMessage) { xstream.alias("xml",locationMessage.getClass()); return xstream.toXML(locationMessage); } /** * 拓展xstream,使得支持CDATA块 * */ 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); } } }; } }); }
5), BaseMessage.java message base class (including: developer WeChat ID, user account, creation time, message type, message IDVariables ), text, video, and picture messages will inherit this base class, and extend your own variables on this basis, which can be defined according to various message attributes in the developer documentation
package cn.jon.wechat.message.req; /** * 消息基类 (普通用户-公众号) * @author jon */ public class BaseMessage { //开发者微信号 private String ToUserName; //发送方账号(一个openId) private String FromUserName; //消息创建时间(整型) private long CreateTime; //消息类型(text/image/location/link...) private String MsgType; //消息id 64位整型 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, extended content attribute
package cn.jon.wechat.message.req; /** * 文本消息 * @author jon */ public class TextMessage extends BaseMessage{ //消息内容 private String content; public String getContent() { return content; } public void setContent(String content) { this.content = content; } }
7 ), ImageMessage.java picture message
package cn.jon.wechat.message.req; /** * 图片消息 * @author jon */ public class ImageMessage extends BaseMessage{ //图片链接 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; } }
The above is the detailed content of Using java to develop WeChat public account case code. For more information, please follow other related articles on the PHP Chinese website!