이 기사는 Java를 사용하여 WeChat 공개 계정 사례 코드를 개발하고, 공개 계정에 액세스하는 방법, 구독 계정은 어떻습니까메시지 수신, 특정 참조 값이 있으므로 관심 있는 친구가 참조할 수 있습니다
WeChat 공용 계정 개발은 일반적으로 기업 및 조직을 대상으로 합니다. 일반적으로 개인은 구독 계정만 신청할 수 있으며 호출되는 인터페이스가 제한되어 있습니다. 액세스 단계를 간략하게 설명하겠습니다. 공개 계정 :
1. 먼저 WeChat 공개 계정 플랫폼에 등록하려면 이메일 주소가 필요합니다.
등록 방법에는 구독 계정, 공개 계정, 미니 프로그램 및 기업이 있습니다. 계정, 개인적으로 여기에서 구독 계정만 선택할 수 있습니다
2. 등록 후 공식 계정 플랫폼에 로그인합니다 --->개발--->기본 구성, 여기에서 작성해야 합니다. URL 및 토큰에서 URL은 서버에서 사용하는 인터페이스입니다.
3. Java 웹 서버 프로그램이 컴파일되어 서버에 배포되어 실행될 수 있으면 온라인 인터페이스를 디버깅할 수 있습니다. WeChat 공식 계정 :
1) 적절한 인터페이스를 선택합니다
2) 시스템에서 인터페이스의 매개변수 테이블을 직접 입력할 수 있습니다. 텍스트 상자의 해당 매개변수 값(빨간색 별표는 이 필드가 필수임을 나타냄)
3) 문제 확인 버튼을 클릭하여 해당 디버깅 정보를 가져옵니다
예: 단계 access_token을 얻으려면:
1) 인터페이스 유형: 기본 지원
2) 인터페이스 목록: access_token 인터페이스/토큰 가져오기
3) 해당 매개변수를 입력합니다. , 비밀
4) 질문을 확인하려면 클릭하세요
5) 확인이 성공하면 결과와 프롬프트가 반환됩니다: 요청 성공은 확인이 성공했음을 의미합니다. >
사진메시지, 음성 메시지, 동영상메시지 등
구독 계정으로 메시지를 받는 방법의 경우를 주로 설명합니다. 🎜>
1. 개인 위챗 구독 계정을 신청해야 합니다
1), Ac
Servlet.java 클래스, 확인은 WeChat에서 이루어짐 서버의 메시지 처리 및 WeChat 서버
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 클래스, 요청 확인 도구 클래스, 토큰은 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 서비스 클래스는 주로 메시지 요청 및 응답 처리를 위한 것이며 사용자가 공식 계정을 팔로우할 때 기본 푸시 메시지를 설정할 수 있습니다
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),
상수
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); } } }; } }); }
정의를 포함한 MessageUtil.java 도움말 클래스5), BaseMessage .java 메시지 기본 클래스(개발자 WeChat 계정, 사용자 계정, 생성 시간, 메시지 유형, 메시지 ID
변수
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 텍스트 메시지의 다양한 메시지 속성에 따라 정의할 수 있는 자신만의 변수를 확장합니다. , 5의 기본 클래스에서 상속, 확장 콘텐츠 속성
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 그림 메시지
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 영상 메시지
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; } }
위 내용은 Java를 사용하여 WeChat 공개 계정 사례 코드 개발의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!