公司要弄微信公众号,我也看了微信公众号的接口文档和一些例子,现在我从项目拿出这些心得
第一步肯定是要申请公众号的,要么是自己申请测试号(http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login)的,要么公司申请。
第二步填写基本配置,在基本配置中有一项注意的是那URL那就是外网地址,我推荐的是用花生壳,当时用了新浪的云和其它的,感觉都不太好,因为这个URL要校验有效性。
这里面的Token得注意了,是检验对像,在JAVA代码里面对应,不然通不过,没法提交信息。
EcoingAESKey也就是加密的密钥
第三步:也就是最重要代码:
public class CoreFilterInterceptor implements Interceptor { // 验证请求来源拦截器 public void intercept(Invocation ai) { Controller c = ai.getController(); String methodType= c.getRequest().getMethod(); System.out.print("\n----methodType ="+ methodType); if("GET".equals(methodType)){ String signature = c.getPara("signature"); // 时间戳 String timestamp = c.getPara("timestamp"); // 随机数 String nonce = c.getPara("nonce"); // 随机字符串 String echostr = c.getPara("echostr"); System.out.print("signature = " +signature +" ****timestamp = " +timestamp); // 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败 boolean chkFlag=SignUtil.checkSignature(signature, timestamp, nonce); System.out.println("\n-------SignUtil.checkSignature result="+chkFlag); if (chkFlag) { try { //modified by peter 2016-11-24 PrintWriter pw=c.getResponse().getWriter(); pw.print(echostr); pw.close(); }catch (IOException e){ e.printStackTrace(); } }else { System.out.print("failing"); } ai.invoke(); }else if("POST".equals(methodType)){ try { // c.getResponse().getWriter().write(echostr); //modified by peter 2016-11-24 PrintWriter pw=c.getResponse().getWriter(); pw.print("success"); pw.close(); }catch (IOException e){ e.printStackTrace(); } } } }大家看到 Interceptor也不用急,我用的是jfinal框架这相当于Filter
public class SignUtil { // 配置信息中的Token保持一致 private static String token = "wei12345"; /** * 校验签名 * * @param signature 微信加密签名 * @param timestamp 时间戳 * @param nonce 随机数 * @return */ public static boolean checkSignature(String signature, String timestamp, String nonce) { // 对token、timestamp和nonce按字典排序 String[] paramArr = new String[] { token, timestamp, nonce }; Arrays.sort(paramArr); // 将排序后的结果拼接成一个字符串 String content = paramArr[0].concat(paramArr[1]).concat(paramArr[2]); String ciphertext = null; try { MessageDigest md = MessageDigest.getInstance("SHA-1"); // 对接后的字符串进行sha1加密 byte[] digest = md.digest(content.toString().getBytes()); ciphertext = byteToStr(digest); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } // 将sha1加密后的字符串与signature进行对比 return ciphertext != null ? ciphertext.equals(signature.toUpperCase()) : false; } /** * 将字节数组转换为十六进制字符串 * * @param byteArray * @return */ private static String byteToStr(byte[] byteArray) { String strDigest = ""; for (int i = 0; i < byteArray.length; i++) { strDigest += byteToHexStr(byteArray[i]); } return strDigest; } /** * 将字节转换为十六进制字符串 * * @param mByte * @return */ 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; } }
这里面token记得一定要和配置里面的token保持一致不然是通不过的。
如果是测试帐号的话也是一样的。
在校验的过程中要是遇到超时或者配失败的话,多点几下,