微信公众号开发
来源:互联网 发布:淘宝网牛仔女装 编辑:程序博客网 时间:2024/05/17 02:39
微信公众号开发大体步骤如下:
- 申请公众号
- 购买阿里云ESC 实例
- 配置公众号开发者工具
- 搭建本地服务框架SSM
- 编码
- 部署阿里云服务器
- 测试
申请公众号
事物的发展顶峰必然由盛转衰、是公众号已经火了很久了,至于什么时候死,拭目以待吧。
微信申请公众号分为服务号与订阅号、政府机关、企业属于服务号、个人或其他组织属于订阅号,服务号一般需要相关材料证明,并且申请费300RMB /年,订阅号一般不要什么材料(只需要个人身份证正反面照片)、也不用交费,当然订阅号功能比服务号功能少!这里我暂且申请订阅号。
申请完后就可以直接登陆进入后台管理页面
点击右上角公众号名称如图:
可以看到公众号基本详情。
购买阿里云ESC 实例
为什么 购买阿里云?因为微信公众号回调接口连接的是公网、普通用户ip 基本都是私网、故申请域名,服务器!这里说明一下、目前国内服务器供应商相对较好是阿里云、国外亚马逊、二者区别:国内网速相对国内用户比较好、加个也相对贵点、国外的价格便宜、但对于大陆用户网速较慢。我个人买的是阿里云服务器:
最重要的是购买域名、然后备案、备案这个比较麻烦,不出意外的话一个月时间就能备案成功、这里我的域名备案已经成功。
配置公众号开发者工具
点击左立列表菜单 找到“开发者工具”点击去配置公众号开发选项:
这里Appid 、AppSecret 在代码里配置,服务器配置是微信公众号服务器回调你本地服务器接口、其中url 是你服务器提供回调接口、token 令牌随便写、同时在代码里也是保持一样,EncodingAESKey 消息加密密钥、随机生成、代码里也需要配置一样,消息加解密方式,有三种:明文、兼容、私密模式、这里是兼容模式。
公众号这已经设置好后、保存并启动配置。
搭建本地服务框架SSM
- 开发工具:
MyEclipse 2015 state 2.0 + Tomcat 8.0 + MYSQL 5.7 + JDK 1.7
搭建Spring + Spring MVC + MyBatis 项目
- 初始化公众号配置信息 web.xml:
- Servlet class 如下:
package com.cn.hnust.controller;import java.io.IOException;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 com.cn.hnust.biz.TokenThread;import com.cn.hnust.biz.TokenThread.AccessTokenCallBack;import com.cn.hnust.resp.AccessToken;import com.cn.hnust.util.FileUtil;import com.cn.hnust.util.L;@WebServlet(name = "AccessTokenServlet")public class AccessTokenServlet extends HttpServlet implements AccessTokenCallBack{ private static final long serialVersionUID = -7811255688733771828L; public AccessTokenServlet() { } @Override public void init() throws ServletException { //获取servlet初始参数appid和appsecret TokenThread.appId = getInitParameter("appid"); TokenThread.appSecret = getInitParameter("appsecret"); new Thread(new TokenThread(this)).start(); //启动进程// new Thread(new MenuThread()).start(); super.init(); } @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { L.i("doGet", "is running"); super.doGet(req, resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { L.i("doPost", "is running"); super.doPost(req, resp); } @Override public void callBack(AccessToken accessToken) { FileUtil.writerLog(FileUtil.PATH,accessToken.getAccessToken()); }}
- TokenThread class 如下:
package com.cn.hnust.biz;import com.alibaba.fastjson.JSON;import com.alibaba.fastjson.JSONObject;import com.cn.hnust.resp.AccessToken;import com.cn.hnust.util.Config;import com.cn.hnust.util.L;public class TokenThread implements Runnable { public static String appId = ""; public static String appSecret = ""; public static AccessToken accessToken = null; private AccessTokenCallBack callback; public TokenThread(AccessTokenCallBack callback) { this.callback = callback; } @Override public void run() { while (true) { accessToken = this.getAccessToken(); if (null != accessToken) { L.i("token", accessToken.getAccessToken()); L.i("time", accessToken.getExpiresin()+""); callback.callBack(accessToken); try { Thread.sleep(7000 * 1000); } catch (InterruptedException e) { e.printStackTrace(); }// 获取到access_token 休眠7000秒 }else{ try { Thread.sleep(1000*3); } catch (InterruptedException e) { e.printStackTrace(); } //获取的access_token为空 休眠3秒 } } } private AccessToken getAccessToken() { NetWorkHelper workHelper = new NetWorkHelper(); String Url = String.format(Config.access_token_url,this.appId,this.appSecret); String result = workHelper.getHttpsResponse(Url, ""); JSONObject json = JSON.parseObject(result); AccessToken token = new AccessToken(); token.setAccessToken(json.getString("access_token")); token.setExpiresin(json.getInteger("expires_in")); return token; } public interface AccessTokenCallBack { public void callBack(AccessToken accessToken); }}
- NetWorkHelper class 如下:
package com.cn.hnust.biz;import java.io.BufferedReader;import java.io.ByteArrayOutputStream;import java.io.DataOutputStream;import java.io.File;import java.io.FileOutputStream;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;import java.io.OutputStream;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.URL;import java.net.URLEncoder;import java.security.cert.Certificate;import java.security.cert.CertificateException;import java.security.cert.X509Certificate;import java.util.HashMap;import java.util.Map;import javax.net.ssl.HostnameVerifier;import javax.net.ssl.HttpsURLConnection;import javax.net.ssl.SSLContext;import javax.net.ssl.SSLSession;import javax.net.ssl.TrustManager;import javax.net.ssl.X509TrustManager;public class NetWorkHelper { public NetWorkHelper() { // TODO Auto-generated constructor stub } public String getMessage(String ur) { try { URL url = new URL(ur); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5 * 1000); conn.setRequestMethod("GET"); InputStream inStream = conn.getInputStream(); BufferedReader reader = new BufferedReader(new InputStreamReader(conn.getInputStream(), "GBK")); String line = ""; StringBuffer buffer = new StringBuffer(); while ((line = reader.readLine()) != null) { buffer.append(line); } //System.out.println("result=" + buffer.toString()); conn.disconnect(); return buffer.toString(); } catch (Exception e) { e.printStackTrace(); return "error"; } } public void postMessage(String sender, String content, String ur) { // String path = "http://192.168.1.106:8009/messageApi"; try { Map<String, String> requestParams = new HashMap<String, String>(); requestParams.put("sender", "12"); //requestParams.put("content", "中国"); StringBuilder params = new StringBuilder(); for (Map.Entry<String, String> entry : requestParams.entrySet()) { params.append(entry.getKey()); params.append("="); params.append(URLEncoder.encode(entry.getValue(), "UTF-8")); params.append("&"); } if (params.length() > 0) params.deleteCharAt(params.length() - 1); byte[] data = params.toString().getBytes(); URL url = new URL(ur); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); conn.setConnectTimeout(5000); conn.setRequestMethod("POST"); conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded"); conn.setRequestProperty("Content-Length", String.valueOf(data.length)); // POST方式,其实就是浏览器把数据写给服务器 conn.setDoOutput(true); // 设置可输出流 // OutputStream os = conn.getOutputStream(); // 获取输出流 DataOutputStream outStream = new DataOutputStream( conn.getOutputStream()); outStream.write(data); // 将数据写给服务器 int code = conn.getResponseCode(); if (code == 200) { InputStream is = conn.getInputStream(); // return StreamTools.streamToString(is); } else { // return "网络访问失败"; } } catch (Exception e) { e.printStackTrace(); // return 网络访问失败; } } public String getURLResponse(String urlString) { HttpURLConnection conn = null; //连接对象 InputStream is = null; String resultData = ""; try { URL url = new URL(urlString); //URL对象 conn = (HttpURLConnection) url.openConnection(); //使用URL打开一个链接 conn.setDoInput(true); //允许输入流,即允许下载 //在android中必须将此项设置为false conn.setDoOutput(false); //允许输出流,即允许上传 conn.setUseCaches(false); //不使用缓冲 conn.setRequestMethod("GET"); //使用get请求 is = conn.getInputStream(); //获取输入流,此时才真正建立链接 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 (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); System.out.println("MalformedURLException:" + e.getMessage()); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); System.out.println("IOException:" + e.getMessage()); } finally { if (is != null) { try { is.close(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } if (conn != null) { conn.disconnect(); } } return resultData; } /** * 下载文件 * @param hsUrl * @return */ public String DownLoadHttpsFile(String hsUrl,String fileName,String ur) { URL url; InputStream is = null; String filePath = ur+fileName; try { url = new URL(hsUrl); 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); //允许输入流,即允许下载 //在android中必须将此项设置为false con.setDoOutput(false); //允许输出流,即允许上传 con.setUseCaches(false); //不使用缓冲 con.setRequestMethod("GET"); //使用get请求 is = con.getInputStream(); //获取输入流,此时才真正建立链接 ByteArrayOutputStream outStream = new ByteArrayOutputStream(); byte[] buffer = new byte[1024]; int len = 0; while( (len=is.read(buffer)) != -1 ){ outStream.write(buffer, 0, len); } is.close(); byte[] fileBytes = outStream.toByteArray(); File file = new File(filePath); FileOutputStream fops = new FileOutputStream(file); fops.write(fileBytes); fops.flush(); fops.close(); /* Certificate[] certs = con.getServerCertificates(); for (Certificate cert : certs) { X509Certificate xcert = (X509Certificate) cert; }*/ } catch (Exception e) { e.printStackTrace(); } return filePath; } /** * HTTPS协议的POST请求 * @param hsUrl 请求地址 * @param json 请求数据 * @return */ public String postHttpsResponse(String hsUrl,String json) { URL url; InputStream is = null; String resultData = ""; try { url = new URL(hsUrl); 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); //允许输入流,即允许下载 //在android中必须将此项设置为false con.setDoOutput(true); //允许输出流,即允许上传 con.setUseCaches(false); //不使用缓冲 con.setRequestMethod("POST"); //使用post请求 //表单数据 if (null != json) { OutputStream outputStream = con.getOutputStream(); outputStream.write(json.getBytes("UTF-8")); outputStream.close(); } is = con.getInputStream(); //获取输入流,此时才真正建立链接 InputStreamReader isr = new InputStreamReader(is); BufferedReader bufferReader = new BufferedReader(isr); String inputLine = ""; while ((inputLine = bufferReader.readLine()) != null) { resultData += inputLine + "\n"; } System.out.println(resultData); Certificate[] certs = con.getServerCertificates(); for (Certificate cert : certs) { X509Certificate xcert = (X509Certificate) cert; } } catch (Exception e) { e.printStackTrace(); } return resultData; } public String getHttpsResponse(String hsUrl, String requestMethod) { URL url; InputStream is = null; String resultData = ""; try { url = new URL(hsUrl); 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); // 允许输入流,即允许下载 // 在android中必须将此项设置为false con.setDoOutput(false); // 允许输出流,即允许上传 con.setUseCaches(false); // 不使用缓冲 if (null != requestMethod && !requestMethod.equals("")) { con.setRequestMethod(requestMethod); // 使用指定的方式 } else { con.setRequestMethod("GET"); // 使用get请求 } is = con.getInputStream(); // 获取输入流,此时才真正建立链接 InputStreamReader isr = new InputStreamReader(is); BufferedReader bufferReader = new BufferedReader(isr); String inputLine = ""; while ((inputLine = bufferReader.readLine()) != null) { resultData += inputLine + "\n"; } Certificate[] certs = con.getServerCertificates(); int certNum = 1; for (Certificate cert : certs) { X509Certificate xcert = (X509Certificate) cert; } } catch (Exception e) { e.printStackTrace(); } return resultData; } private X509TrustManager xtm = new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { // TODO Auto-generated method stub } @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { // TODO Auto-generated method stub } @Override public X509Certificate[] getAcceptedIssuers() { // TODO Auto-generated method stub return null; } };}
- 微信公众号服务器回调接口类如下:
package com.cn.hnust.controller;import java.io.IOException;import java.io.PrintWriter;import java.util.Map;import javax.annotation.Resource;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import com.cn.hnust.biz.MessageHandler;import com.cn.hnust.biz.ProcessReqest;import com.cn.hnust.pojo.WxMessage;import com.cn.hnust.service.IWechatService;import com.cn.hnust.service.IWxService;import com.cn.hnust.util.L;import com.cn.hnust.util.SignUtil;@Controller@RequestMapping("/wx")public class WechatController extends BaseController{ private static final String TIMESTAMP = "timestamp"; private static final String ECHOSTR = "echostr"; private static final String NONCE = "nonce"; private static final String SIGNATURE = "signature"; @Resource private IWechatService wechatService; @Resource private IWxService<WxMessage> messageService; @RequestMapping("/req") public void registerWxAPI(HttpServletRequest request,HttpServletResponse response) { String reqMethod = request.getMethod(); if (reqMethod.equals("GET")) { // 微信加密签名 String signature = request.getParameter(SIGNATURE); // 时间戳 String timestamp = request.getParameter(TIMESTAMP); // 随机数 String nonce = request.getParameter(NONCE); // 随机字符串 String echostr = request.getParameter(ECHOSTR); logger.info("===============微信公众号对接开始===============!"); boolean valid = wechatService.checkcalidata(signature, timestamp, nonce); if (valid) { PrintWriter out = null; try { out = response.getWriter(); // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败 if (SignUtil.checkSignature(signature, timestamp, nonce)) { out.print(echostr); out.flush(); logger.info("微信公众号对接成功!"); } } catch (IOException e) { e.printStackTrace(); logger.info("微信公众号对接出现异常!"); } finally { out.close(); out = null; } } } else if (reqMethod.equals("POST")) { response.setContentType("text/html;charset=utf-8"); //设置输出编码格式 String result = ""; Map map; try { map = MessageHandler.parseXml(request); System.out.println("开始构造消息"); result = MessageHandler.buildXml(map,messageService); if (result.equals("")) result = "未正确响应"; } catch (Exception e) { e.printStackTrace(); L.i("发生异常:", e.getMessage()); } try { response.getWriter().println(result); } catch (IOException e) { e.printStackTrace(); } } } @RequestMapping("chat") public void chat(HttpServletRequest request, HttpServletResponse response) { // 微信加密签名 String signature = request.getParameter(SIGNATURE); // 时间戳 String timestamp = request.getParameter(TIMESTAMP); // 随机数 String nonce = request.getParameter(NONCE); logger.info("===============微信公众号应答开始===============!"); boolean valid = wechatService.checkcalidata(signature, timestamp,nonce); if (valid) { PrintWriter out = null; try { out = response.getWriter(); // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败 if (SignUtil.checkSignature(signature, timestamp, nonce)) { // 调用核心业务类接收消息、处理消息 String respMessage = null; try { respMessage = ProcessReqest.process(request, response); } catch (Exception e) { e.printStackTrace(); } out.print(respMessage); out.flush(); logger.info("微信公众号对接成功!"); } } catch (IOException e) { e.printStackTrace(); logger.info("微信公众号对接出现异常!"); } finally { out.close(); out = null; } } }}
- SignUtil class 如下:
package com.cn.hnust.util;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;public class SignUtil { // 与接口配置信息中的Token要一致 private static final String token = "xxxxxxxx"; private static final String EncodingAESKey = "xxxxxxxxxxxxxxxxxxxxxxxx"; public static boolean checkSignature(String signature, String timestamp,String nonce) { // 从请求中(也就是微信服务器传过来的)拿到的token, timestamp, nonce String[] arr = new String[] { token, timestamp, nonce }; // 将token、timestamp、nonce三个参数进行字典序排序 sort(arr); StringBuilder content = new StringBuilder(); for (int i = 0; i < arr.length; i++) { content.append(arr[i]); } MessageDigest md = null; String tmpStr = null; try { md = MessageDigest.getInstance("SHA-1"); // 将三个参数字符串拼接成一个字符串进行sha1加密 byte[] digest = md.digest(content.toString().getBytes()); // 将字节数组转成字符串 tmpStr = byteToStr(digest); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } content = null; // 将sha1加密后的字符串可与signature对比,标识该请求来源于微信 return tmpStr != null ? tmpStr.equals(signature.toUpperCase()) : false; } // 用于字典排序 public static void sort(String a[]) { for (int i = 0; i < a.length - 1; i++) { for (int j = i + 1; j < a.length; j++) { if (a[j].compareTo(a[i]) < 0) { String temp = a[i]; a[i] = a[j]; a[j] = temp; } } } } // 将加密后的字节数组变成字符串 private static String byteToStr(byte[] byteArray) { String strDigest = ""; for (int i = 0; i < byteArray.length; i++) { strDigest += byteToHexStr(byteArray[i]); } return strDigest; } private static String byteToHexStr(byte mByte) { char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; char[] tempArr = new char[2]; tempArr[0] = Digit[(mByte >>> 4) & 0X0F]; tempArr[1] = Digit[mByte & 0X0F]; String s = new String(tempArr); return s; }}
- 业务处理类 MessageHandler 如下:
package com.cn.hnust.biz;import java.io.ByteArrayOutputStream;import java.io.IOException;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;import java.util.UUID;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.dom4j.Document;import org.dom4j.Element;import org.dom4j.io.SAXReader;import com.cn.hnust.pojo.EventType;import com.cn.hnust.pojo.GeneralMessage;import com.cn.hnust.pojo.MessageType;import com.cn.hnust.pojo.MusicMessage;import com.cn.hnust.pojo.NewsItem;import com.cn.hnust.pojo.PictureMessage;import com.cn.hnust.pojo.WxMessage;import com.cn.hnust.service.IWxService;import com.cn.hnust.util.L;public class MessageHandler { public static Map parseXml(HttpServletRequest request) throws Exception { // 将解析结果存储在HashMap中 Map map = new HashMap(); // 从request中取得输入流 InputStream inputStream = request.getInputStream(); /* * 读取request的body内容 此方法会导致流读取问题 Premature end of file. Nested exception: * Premature end of file String requestBody = * inputStream2String(inputStream); System.out.println(requestBody); */ // 读取输入流 SAXReader reader = new SAXReader(); Document document = reader.read(inputStream); // 得到xml根元素 Element root = document.getRootElement(); // 得到根元素的所有子节点 List<Element> elementList = root.elements(); // 遍历所有子节点 for (Element e : elementList) { L.i(e.getName(), e.getText()); map.put(e.getName(), e.getText()); } // 释放资源 inputStream.close(); inputStream = null; return map; } private static String inputStream2String(InputStream is) throws IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); int i = -1; while ((i = is.read()) != -1) { baos.write(i); } return baos.toString(); } // 根据消息类型 构造返回消息 public static String buildXml(Map map,IWxService<WxMessage> messageService) { String result = ""; String msgType = map.get("MsgType").toString(); MessageType messageEnumType = MessageType.valueOf(MessageType.class, msgType.toUpperCase()); switch (messageEnumType) { case TEXT: result = handleTextMessage(map,messageService); break; case IMAGE: result = handleImageMessage(map,messageService); break; case VOICE: result = handleVoiceMessage(map,messageService); break; case VIDEO: result = handleVideoMessage(map,messageService); break; case SHORTVIDEO: result = handleSmallVideoMessage(map,messageService); break; case LOCATION: result = handleLocationMessage(map,messageService); break; case LINK: result = handleLinkMessage(map,messageService); break; case EVENT: String eventType = map.get("Event").toString(); System.out.println("eventType:" + eventType); EventType eventEnumType = EventType.valueOf(EventType.class, eventType.toUpperCase()); switch(eventEnumType){ case CLICK: result = handleGetMessageEvent(map,messageService); break; case VIEW: result = handleLinkEvent(); break; case SCANCODE_PUSH: result = handleScanPushEvent(); break; case SCANCODE_WAITMSG: result = handleScanWaitMsgEvent(); break; case PIC_SYSPHOTO: result = handlePicSystemEvent(); break; case PIC_PHOTO_OR_ALBUM: result = handlePicPhotoAlbumEvent(); break; case PIC_WEIXIN: result = handlePicWeiXinEvent(); break; case LOCATION_SELECT: result = handleLocationSelectionEvent(); break; default: break; } break; default: break; } return result; } private static String handleLocationSelectionEvent() { // TODO Auto-generated method stub return null; } private static String handlePicWeiXinEvent() { // TODO Auto-generated method stub return null; } private static String handlePicPhotoAlbumEvent() { // TODO Auto-generated method stub return null; } private static String handlePicSystemEvent() { // TODO Auto-generated method stub return null; } private static String handleScanWaitMsgEvent() { // TODO Auto-generated method stub return null; } private static String handleScanPushEvent() { // TODO Auto-generated method stub return null; } private static String handleLinkEvent() { // TODO Auto-generated method stub return null; } private static String handleGetMessageEvent(Map map, IWxService<WxMessage> messageService) { String xml = ""; xml = buildTextMessage(map,messageService, "你点击了天气预报"); return xml; } private static String handleTextMessage(Map map, IWxService<WxMessage> messageService) { String xml = ""; String fromUserName = map.get("FromUserName").toString(); // 开发者微信号 String toUserName = map.get("ToUserName").toString(); // 消息内容 String content = map.get("Content").toString(); GeneralMessage msg = new GeneralMessage(); msg.Sender = toUserName; msg.Receiver = fromUserName; msg.CreateTime = getUtcTime(); switch (content) { case "文本": xml = buildTextMessage(map,messageService, "这是一条文本消息"); break; case "图片": xml = buildPicture(map,messageService); break; case "音乐": xml = buildMusic(map,messageService); break; case "图文": xml = buildNewsMessage(map,messageService); break; default: xml = String .format("<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[%s]]></Content></xml>", msg.Receiver, msg.Sender, msg.CreateTime, "请回复如下关键词:\n文本\n图片\n语音\n视频\n音乐\n图文"); break; } return xml; } private static String getUtcTime() { Date dt = new Date();// 如果不需要格式,可直接用dt,dt就是当前系统时间 DateFormat df = new SimpleDateFormat("yyyyMMddhhmm");// 设置显示格式 String nowTime = ""; nowTime = df.format(dt); long dd = (long) 0; try { dd = df.parse(nowTime).getTime(); } catch (Exception e) { } return String.valueOf(dd); } /** * 构造文本消息 * * @param map * @param messageService * @param content * @return */ private static String buildTextMessage(Map map, IWxService<WxMessage> messageService, String content) { String fromUserName = map.get("FromUserName").toString(); // 开发者微信号 String toUserName = map.get("ToUserName").toString(); WxMessage wm = new WxMessage(); wm.setMsgid(new Date().getTime()); wm.setContent(content); wm.setCreatetime(getUtcTime()); wm.setTousername(toUserName); wm.setFromusername(fromUserName); wm.setMsgtype("text"); messageService.save(wm); return String.format("<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[%s]]></Content></xml>", fromUserName, toUserName, getUtcTime(), content); } /** * 构造图片消息 * * @param map * @param messageService * @return */ private static String buildPicture(Map map, IWxService<WxMessage> messageService) { String fromUserName = map.get("FromUserName").toString(); String toUserName = map.get("ToUserName").toString(); String tempMediaId = "58fFYMRjJv0V94qZJ1EeGSKRQB4CbboVBC7FAILlxxZ2AzMnVVUeiOOenxgkzv9g"; WxMessage wm = new WxMessage(); wm.setMsgid(new Date().getTime()); wm.setFromusername(fromUserName); wm.setTousername(toUserName); wm.setMediaid(tempMediaId); wm.setMsgtype("image"); wm.setCreatetime(getUtcTime()); messageService.save(wm); return String.format("<xml>\n" + "<ToUserName><![CDATA[%s]]></ToUserName>\n" + "<FromUserName><![CDATA[%s]]></FromUserName>\n" + "<CreateTime>%s</CreateTime>\n" + "<MsgType><![CDATA[image]]></MsgType>\n" + "<Image>\n" + "<MediaId><![CDATA[%s]]></MediaId>\n" + "</Image>\n" + "</xml>", fromUserName, toUserName, getUtcTime(), tempMediaId); } /** * 构造音乐消息 * * @param map * @param messageService * @return */ private static String buildMusic(Map map, IWxService<WxMessage> messageService) { MusicMessage msg = new MusicMessage(); String fromUserName = map.get("FromUserName").toString(); String toUserName = map.get("ToUserName").toString(); msg.Sender = toUserName; msg.Receiver = fromUserName; msg.CreateTime = getUtcTime(); msg.Title = "蓝莲花"; msg.Description = "蓝莲花-许巍"; msg.MusicURL = "http://7te94m.com1.z0.glb.clouddn.com/lanlianhua.mp3"; msg.HQMusicUrl = "http://7te94m.com1.z0.glb.clouddn.com/lanlianhua.mp3"; msg.ThumbMediaId = "kpNqTAk7tZ6NHhlHlEBhgUhfxjPBADbK79EfwF1RlOKAFcuKYC0eenD-ja-nTHg9"; WxMessage wm = new WxMessage(); wm.setMsgid(new Date().getTime()); wm.setFromusername(fromUserName); wm.setTousername(toUserName); wm.setCreatetime(getUtcTime()); wm.setDescription(msg.Description); wm.setTitle(msg.Title); wm.setThumbmediaid(msg.ThumbMediaId); wm.setUrl(msg.HQMusicUrl); wm.setMsgtype("music"); messageService.save(wm); return String .format("<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[music]]></MsgType><Music><Title><![CDATA[%s]]></Title><Description><![CDATA[%s]]></Description><MusicUrl><![CDATA[%s]]></MusicUrl><HQMusicUrl><![CDATA[%s]]></HQMusicUrl><ThumbMediaId><![CDATA[%s]]></ThumbMediaId></Music></xml>", msg.Receiver, msg.Sender, getUtcTime(), msg.Title, msg.Description, msg.MusicURL, msg.HQMusicUrl, msg.ThumbMediaId); } /** * 构造图文消息 * * @param map * @param messageService * @return */ private static String buildNewsMessage(Map map, IWxService<WxMessage> messageService) { String fromUserName = map.get("FromUserName").toString(); String toUserName = map.get("ToUserName").toString(); NewsItem item = new NewsItem(); item.Title = "iOS 9.1现2大故障 iPhone基本功能遭殃"; item.Description = "凤凰科技讯 11月9日消息,据中关村在线报道,iOS 9.1 是个颇为稳定的版本,至少初初推出时的印象是这样,现在推出接近两星期,一些颇为严重的问题开始浮现。其中两大问题,正在困扰为数不少的用户。"; item.PicUrl = "https://ss0.bdstatic.com/5aV1bjqh_Q23odCf/static/superman/img/logo/bd_logo1_31bdc765.png"; item.Url = "http://tech.ifeng.com/a/20151109/41503466_0.shtml"; String itemContent1 = buildSingleItem(item); NewsItem item2 = new NewsItem(); item2.Title = "刚毕业就月薪过万的程序员 创业大街上的得意与迷茫"; item2.Description = "DoNews11月9日消息(编辑 陈艳曲)第一次见到刚毕业的程序员小李时,正逢他在创业大街上谋到了一份工作,五位数的薪资让他更加坚信,毕业前在技术学校报一个ios开发培训班是一个多么正确的决定"; item2.PicUrl = "http://photocdn.sohu.com/20151108/mp40396008_1446997429715_4_th_fv23.jpeg"; item2.Url = "http://tech.hexun.com/2015-11-09/180434346.html"; String itemContent2 = buildSingleItem(item2); WxMessage wm = new WxMessage(); wm.setMsgid(new Date().getTime()); wm.setFromusername(fromUserName); wm.setTousername(toUserName); wm.setTitle(item.Title); wm.setCreatetime(getUtcTime()); wm.setDescription(item.Description); wm.setPicurl(item.PicUrl); wm.setUrl(item.Url); wm.setMsgtype("news"); messageService.save(wm); String content = String.format("<xml>\n" + "<ToUserName><![CDATA[%s]]></ToUserName>\n" + "<FromUserName><![CDATA[%s]]></FromUserName>\n" + "<CreateTime>%s</CreateTime>\n" + "<MsgType><![CDATA[news]]></MsgType>\n" + "<ArticleCount>%s</ArticleCount>\n" + "<Articles>\n" + "%s" + "</Articles>\n" + "</xml> ", fromUserName, toUserName, getUtcTime(), 2, itemContent1 + itemContent2); return content; } /** * 生成图文消息的一条记录 * * @param item * @return */ private static String buildSingleItem(NewsItem item) { String itemContent = String.format("<item>\n" + "<Title><![CDATA[%s]]></Title> \n" + "<Description><![CDATA[%s]]></Description>\n" + "<PicUrl><![CDATA[%s]]></PicUrl>\n" + "<Url><![CDATA[%s]]></Url>\n" + "</item>", item.Title, item.Description, item.PicUrl, item.Url); return itemContent; } /** * 接收到图片消息后处理 * * @param map * @param messageService * @return */ private static String handleImageMessage(Map map, IWxService<WxMessage> messageService) { String picUrl = map.get("PicUrl").toString(); String mediaId = map.get("MediaId").toString(); System.out.print("picUrl:"+picUrl); System.out.print("mediaId:" + mediaId); String result = String.format("已收到您发来的图片,图片Url为:%s\n图片素材Id为:%s",picUrl,mediaId); return buildTextMessage(map,messageService,result); } private static String handleVoiceMessage(Map map, IWxService<WxMessage> messageService){ String format = map.get("Format").toString(); String mediaId = map.get("MediaId").toString(); System.out.print("format:"+format); System.out.print("mediaId:" + mediaId); String result = String.format("已收到您发来的语音,语音格式为:%s\n语音素材Id为:%s",format,mediaId); return buildTextMessage(map,messageService,result); } private static String handleVideoMessage(Map map, IWxService<WxMessage> messageService){ String thumbMediaId = map.get("ThumbMediaId").toString(); String mediaId = map.get("MediaId").toString(); System.out.print("thumbMediaId:"+thumbMediaId); System.out.print("mediaId:" + mediaId); String result = String.format("已收到您发来的视频,视频中的素材ID为:%s\n视频Id为:%s",thumbMediaId,mediaId); return buildTextMessage(map,messageService,result); } private static String handleSmallVideoMessage(Map map, IWxService<WxMessage> messageService){ String thumbMediaId = map.get("ThumbMediaId").toString(); String mediaId = map.get("MediaId").toString(); System.out.print("thumbMediaId:"+thumbMediaId); System.out.print("mediaId:" + mediaId); String result = String.format("已收到您发来的小视频,小视频中素材ID为:%s,\n小视频Id为:%s",thumbMediaId,mediaId); return buildTextMessage(map,messageService,result); } private static String handleLocationMessage(Map map, IWxService<WxMessage> messageService){ String latitude = map.get("Location_X").toString(); //纬度 String longitude = map.get("Location_Y").toString(); //经度 String label = map.get("Label").toString(); //地理位置精度 String result = String.format("纬度:%s\n经度:%s\n地理位置:%s",latitude,longitude,label); return buildTextMessage(map,messageService,result); } private static String handleLinkMessage(Map map, IWxService<WxMessage> messageService){ String title = map.get("Title").toString(); String description = map.get("Description").toString(); String url = map.get("Url").toString(); String result = String.format("已收到您发来的链接,链接标题为:%s,\n描述为:%s\n,链接地址为:%s",title,description,url); return buildTextMessage(map,messageService,result); }}
至此,基本代码完成。
部署阿里云服务器
主要是把tomcat web app 目录下storm 部署阿里云服务器上,重启tomcat 即可!
测试
关注公众号,随便输入如图:
进入微信后台:
进入我自己写的页面:
至此 ,公众号讲解到此为止。
- 微信公众号开发
- 微信公众号开发
- 微信公众号开发
- 微信公众号开发
- 微信公众号开发
- 微信公众号开发
- 微信公众号开发
- 微信公众号开发
- 微信公众号开发
- 微信公众号开发
- 微信公众号开发
- 微信公众号开发
- 微信公众号开发
- 微信公众号开发
- 微信公众号开发
- 微信公众号开发
- 微信公众号开发
- 微信公众号开发
- JSON和JS对象的区别和JSON的基本应用?常说的JSON是什么?
- 复制工程部署路径出问题
- Backbone入门指南(四):Model(数据模型)
- mac 配置Python集成开发环境(Eclipse +Python+Pydev)
- Android Fragmnet-Fragment数据交换以及ListFragment的使用
- 微信公众号开发
- java实现抽奖效果
- android 百度地图定位不准问题
- 关于分布式系统的数据一致性问题(二)
- oj第十一周训练——趣味取小数
- 第10周练习(补)小学生加法题
- GIT上传、下载、还原
- bzoj 3450: Tyvj1952 Easy (概率与期望dp)
- form表单嵌套,用标签的form属性来解决表单嵌套的问题