一:微信公众号对接的基本介绍
填写服务器配置信息的介绍
在微信公众平台认证之前,我们可以先申请一个测试的公众号来进行测试,这对开发人员来说还是有很大好处的!
为什么要申请测试账号?
主要是因为测试账号比我们没有认证的微信账号权限大一点。足够测试我们的接口了,点击http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
二:微信服务器对接的实现代码部分
创建java项目
新建一个名SpringBoot项目,名为wyj-wechat-demo。
新建一个servlet类,来接收微信服务器传来信息。
package com.wyj.wechart.servlet;
import java.io.IOException;
import java.io.PrintWriter;
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.wyj.wechart.service.CoreService;
import com.wyj.wechart.utils.SignUtil;
/**
* 来接收微信服务器传来信息
*
*
* @author:WangYuanJun
* @date:2018年1月23日 下午2:17:39
*/
@WebServlet(urlPatterns = "/wechart", description = "wechart")
public class CoreServlet extends HttpServlet {
private static final long serialVersionUID = -8685285401859800066L;
/**
* 确认请求来自微信服务器
*/
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println(">>>>>>>>>>doGet()<<<<<<<<<<<");
// 微信加密签名
String signature = req.getParameter("signature");
// 时间戳
String timestamp = req.getParameter("timestamp");
// 随机数
String nonce = req.getParameter("nonce");
// 随机字符串
String echostr = req.getParameter("echostr");
PrintWriter out = resp.getWriter();
// 通过检验signature对请求进行校验,若校验成功则原样返回echostr,表示接入成功,否则接入失败
if (SignUtil.checkSignature(signature, timestamp, nonce)) {
out.print(echostr);
}
out.close();
out = null;
}
/**
* 处理微信服务器发来的消息
*/
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println(">>>>>>>>>>doPost()<<<<<<<<<<<");
// TODO 消息的接收、处理、响应
}
}
- 加密校验程序的工具类。
这个校验的方法,可以通过分析官方文档的demo,然后通过java语言来写出。官方php校验代码一览
package com.wyj.wechart.utils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
/**
* 请求校验工具类
*
*
* @author:WangYuanJun
* @date:2018年1月22日 下午3:45:15
*/
public class SignUtil {
// 与接口配置信息中的Token要一致
private static String token = "wechart";
/**
* 验证签名
*
* @param signature
* @param timestamp
* @param nonce
* @return
*/
public static boolean checkSignature(String signature, String timestamp, String nonce) {
String[] arr = new String[] { token, timestamp, nonce };
// 将token、timestamp、nonce三个参数进行字典序排序
Arrays.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;
}
/**
* 将字节数组转换为十六进制字符串
*
* @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;
}
}
- 修改服务器端口为80端口
SpringBoot application.properties
server.port=80
spring.freemarker.cache=false
spring.freemarker.charset=UTF-8
spring.freemarker.check-template-location=true
spring.freemarker.content-type=text/html
spring.freemarker.expose-request-attributes=true
spring.freemarker.expose-session-attributes=true
spring.freemarker.request-context-attribute=request
spring.freemarker.template-loader-path=classpath:/templates
spring.freemarker.suffix=.html
spring.mvc.static-path-pattern=/static/**
三:填写服务器配置
微信公众号测试环境接入示例:
服务器配置:
URL:是开发者用来接收微信消息和事件 的接口URL。(必须以http://开头,目前支持80端口)
Token:可由开发者可以任意填写,用作生成签名(该Token会和接口URL中包含的Token进行比对,从而验证安全性)。注意必须为英文或数字,长度为3-32字符。
说明:如果提示“token验证失败”,可以先重次几次,微信服务器有时候不稳定,也有可能映射不稳定。URL改成自己的URL,Token要对应自己在SignUtil里面填写的Token值。
验证服务器地址的有效性
开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上,GET请求携带四个参数:
参数 | 描述 |
---|---|
signature | 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数 |
timestamp | 时间戳 |
nonce | 随机数 |
echostr | 随机字符串 |
开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。
加密/校验流程如下:
1. 将token、timestamp、nonce三个参数进行字典序排序
将三个参数字符串拼接成一个字符串进行sha1加密
开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
Token校验是否成功
成功启用后如图:
恭喜,你成功启用开发模式。
启用并设置服务器配置后,用户发给公众号的消息以及开发者需要的事件推送,将被微信转发到该URL中。
成为开发者后,用户每次向公众号发送消息、或者产生自定义菜单、或产生微信支付订单等情况时,开发者填写的服务器配置URL将得到微信服务器推送过来的消息和事件,开发者可以依据自身业务逻辑进行响应,如回复消息。
这些配置可以参照我的其他博客文章进行配置,这里就不多说了。
以上介绍也可以参考 微信开发文档。
注:github项目地址:微信公共号开发用例