接入概述
和微信官方文档给出的开发接入指南稍微有点儿不同,我把微信平台和服务器对接的代码编写放到了平台接入这一块,因为作为半个新人来讲,我觉得微信给出的开发文档是我见过最难入门的开发文档,没有之一。在接入指南里面,上来就是填写服务器配置,当你填写好服务器配置地址时候,发现一直提示配置失败,具体失败原因也不清楚。然后就只能懵逼的到处找资料,还好网络是个好东西,大神们也乐于分享,参考了很多资料后,发现如果想要对接成功,不仅是搭好自己的服务器就行,还需要一个跟微信平台交互的程序来确定自己服务器程序与微信成功对接,具体接入步接下来我会一步步写清楚。(本人能力有限,有错误的地方看到的大神们请留言或私信指出,我及时改正过来,以免误导新人)
1.编写服务器对接代码
在第一章准备工作中,我们已经申请到自己的测试开发账号登录开发者测试账号 点击接口配置信息的修改按钮出现下图:
我们填写好URL 和Token后,点击提交会一直提示配置失败,导致配置失败的原因是微信调用你填写的url接口没调通,或者是调通了返回的结果与微信验证的结果不一致。依据微信官方提供的接入文档可知,微信调用我们服务器程序的接口会提供如下参数:
参数 | 描述 |
---|---|
signature | 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。 |
timestamp | 时间戳 |
nonce | 随机数 |
echostr | 随机字符串 |
如果在服务器不存在异常,微信平台能正常调用我们服务器接口的情况下,我们服务器只需原样返回echostr字符串,微信平台接收到这个字符串就能正常与我们服务器对接成功,在不考虑signature签名正确与否的情况下即可认为微信平台与我们自己服务器接入成功。 接入代码代码如下:
import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.carwash.modules.wechat.service.WxConnectService;
/**
* 描述:微信接入控制器
* @author pwu
* 创建时间:2016-6-15
* @version v1.0
*/
@Controller
@RequestMapping(value="wx")
public class WxConnectController {
@Autowired
private WxConnectService connectService;
//微信链接
@RequestMapping(value="", method = RequestMethod.GET)
public void connectWeChat(HttpServletRequest request,HttpServletResponse response) throws Exception{
String signature = request.getParameter("signature");//签名验证
String timestamp = request.getParameter("timestamp");//调用时间戳
String nonce = request.getParameter("nonce");//随机数
String echostr = request.getParameter("echostr");//随机字符串
PrintWriter p = response.getWriter();
//验证微信链接
//checkSignature签名验证方法,初次测试连接时候可以把判断条件直接改为true
//等微信跟平台连接成功,再去写接入验证代码。
if(connectService.checkSignature(signature, timestamp, nonce)){
p.print(echostr);//注意此处必须返回原样echostr以完成验证
}
}
}
服务器其中代码编写完成后,启动服务。再回去填写微信测试开发者账号中的接口配置信息,点击提交,如果服务器能正常调访问的话,此时应该配置成功,即我们服务器与平台对接成功。
2.微信接入签名认证
从微信官方给出的接入签名校验流程:
1)将token、timestamp、nonce三个参数进行字典序排序
2)将三个参数字符串拼接成一个字符串进行sha1加密
3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
不难理解,要验证微信签名是否正确只需要根据上面的流程一步步操作即可,具体校验代码如下:
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import org.springframework.stereotype.Service;
/**
* 描述:处理微信接入服务(验证)
* @author pwu
* 创建时间:2017-6-15
* @version v1.0
*/
@Service
public class WxConnectService {
private static String token = "token";//接口配置信息中填写的Token
public boolean checkSignature(String signature, String timestamp, String nonce) {
// 1.将token、timestamp、nonce三个参数进行字典序排序
String[] arr = new String[] { token, timestamp, nonce };
Arrays.sort(arr);
// 2. 将三个参数字符串拼接成一个字符串进行sha1加密
StringBuilder content = new StringBuilder();
for (int i = 0; i < arr.length; i++) {
content.append(arr[i]);
}
String sha1 = getSha1(content.toString());
//3.验证signature是否正确。
return sha1 !=null ? sha1.equals(signature): false;
}
/**
* 描述:获取sha1加密后十六进制字符串
* @param str token,timestamp,nonce拼接字符串
* @return sha1加密后十六进制字符串
*/
private static String getSha1(String str) {
if (null == str || 0 == str.length()){
return null;
}
String strDigest = "";
try {
MessageDigest md = MessageDigest.getInstance("SHA1");
byte[] digest = md.digest(str.getBytes());
for (int i = 0; i < digest.length; i++) {
strDigest += byteToHexStr(digest[i]);
}
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
return strDigest;
}
/**
* 描述:将字节转换成十六进制字符串
* @param dByte
* @return 十六进制字符串
*/
private static String byteToHexStr(byte dByte) {
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[(dByte >>> 4) & 0X0F];
tempArr[1] = Digit[dByte & 0X0F];
String s = new String(tempArr);
return s;
}
}
完成上面工作后,提交接口信息配置成功,则微信公众号平台接入成功,若失败请耐心排查原因,根据本人经验总结一般有如下原因:
1.用开发机作为服务器(花生壳,或者其他工具穿透映射)
1)可能外网无法访问本地服务器,导致微信无法调用接入接口,检测外网是否能正常访问开发机。
2)微信接入接口不通,在浏览器地址直接输入接口配置信息中的地址,通过DEBUG看看程序是否进入到对接接口。若不没有进入则证明接口不通,进一步查找其他原因。比如接口地址是否正确,服务器是否正常工作等。
2.用新浪云服务器,或者其他无法实时监测程序运行的情况
1)微信接入接口不通,先在本地通过在浏览器localhost:端口/**/wx看看是否能正常进入接口,若进去了证明接口正常,若进不去证明接口不通,进一步查找接口不通的原因。
2)在第一步检查通过的情况下,同步到云服务器又配置失败,检查下云服务器是否运行正常。项目是否正常运行,最简单的方法是在云服务中放一个能够访问的图片或者静态网页等,看能否正常访问。
自己也是萌新,以上都是自己开发中一点点的总结,遇到的问题和解决问题的能力有限,如有和我一样的萌新,遇到问题欢迎留言或私信,我们一起探讨互相学习。