由于微信那边须要咱们提供一个外网能访问的地址给它使用,而为了方便开发,我这里使用了ngrok
配置外网地址直接指向我本机的地址html
1.到http://natapp.cn//#download下载ngrok。java
2.打开cmd,切换到解压的目录,运行ngrok -config ngrok.cfg -subdomain fengzp 8080命令,其中'fengzp'是我本身定义的域名,8080是指向的端口。web
3.运行结果。数组
访问微信公众号注册地址,注册一个测试公众号,登录。安全
在微信公众平台开发者文档上,关于公众号接入这一节内容在接入指南上写的比较详细的,文档中说接入公众号须要3个步骤,分别是:服务器
一、填写服务器配置
二、验证服务器地址的有效性
三、依据接口文档实现业务逻辑微信
其实,第3步已经不能算作公众号接入的步骤,而是接入以后,开发人员能够根据微信公众号提供的接口所能作的一些开发。app
第1步中服务器配置包含服务器地址(URL)、Token和EncodingAESKey。微信公众平台
服务器地址即公众号后台提供业务逻辑的入口地址,目前只支持80端口,以后包括接入验证以及任何其它的操做的请求(例如消息的发送、菜单管理、素材管理等)都要从这个地址进入。接入验证和其它请求的区别就是,接入验证时是get请求,其它时候是post请求;dom
Token可由开发者能够任意填写,用做生成签名(该Token会和接口URL中包含的Token进行比对,从而验证安全性);
EncodingAESKey由开发者手动填写或随机生成,将用做消息体加解密密钥。本例中所有以未加密的明文消息方式,不涉及此配置项。
第2步,验证服务器地址的有效性,当点击“提交”按钮后,微信服务器将发送一个http的get请求到刚刚填写的服务器地址,而且携带四个参数:
接到请求后,咱们须要作以下三步,若确认这次GET请求来自微信服务器,原样返回echostr参数内容,则接入生效,不然接入失败。
1. 将token、timestamp、nonce三个参数进行字典序排序
2. 将三个参数字符串拼接成一个字符串进行sha1加密
3. 开发者得到加密后的字符串可与signature对比,标识该请求来源于微信
实际代码:编写一个servlevt,在其中的doGet方法中定义校验方法,具体代码以下:
package com.feng.web.service.servlet; import java.io.IOException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.Map; 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.feng.web.model.WxMessage; import com.feng.web.service.util.BeanUtil; import com.feng.web.service.util.WxMsgUtil; /** * * @author fengzp * */ @WebServlet(urlPatterns = "/WxServlet") public class WxServlet extends HttpServlet { /** * */ private static final long serialVersionUID = -6008816817887502362L; /** * Token可由开发者能够任意填写,用做生成签名(该Token会和接口URL中包含的Token进行比对,从而验证安全性) */ private final String TOKEN = "fengzp"; @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("开始校验签名"); /** * 接收微信服务器发送请求时传递过来的4个参数 */ String signature = request.getParameter("signature");// 微信加密签名signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。 String timestamp = request.getParameter("timestamp");// 时间戳 String nonce = request.getParameter("nonce");// 随机数 String echostr = request.getParameter("echostr");// 随机字符串 System.out.println(signature); System.out.println(timestamp); System.out.println(nonce); System.out.println(echostr); // response.getWriter().print(echostr); // 加密 String mySignature = sha1(sort(TOKEN, timestamp, nonce)); // 校验签名 if (mySignature != null && mySignature != "" && mySignature.equals(signature)) { System.out.println("签名校验经过。"); response.getWriter().write(echostr); // response.getWriter().print(echostr); } else { System.out.println("签名校验失败."); } } public String sort(String token, String timestamp, String nonce) { String[] strArray = { token, timestamp, nonce }; Arrays.sort(strArray); StringBuilder sb = new StringBuilder(); for (String str : strArray) { sb.append(str); } return sb.toString(); } private String sha1(String str) { try { MessageDigest digest = MessageDigest.getInstance("SHA-1"); digest.update(str.getBytes()); byte messageDigest[] = digest.digest(); // Create Hex String StringBuffer hexString = new StringBuffer(); // 字节数组转换为 十六进制 数 for (int i = 0; i < messageDigest.length; i++) { String shaHex = Integer.toHexString(messageDigest[i] & 0xFF); if (shaHex.length() < 2) { hexString.append(0); } hexString.append(shaHex); } return hexString.toString(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return ""; } @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { } }
而后进入微信测试公众号管理界面,在接口配置信息中的URL填写这个servlet的外网地址和咱们自定义的token,以下图所示:
到此咱们的微信公众号已接入完毕。