完整代码见底部
前置条件:内网穿透。(免费工具:ngrok.cc 花生壳)这两个是我用过的,都差不多,这一次用的是第二个。
原因:我是在本地先写代码调试再放上服务器的,而公众号在测试的时候也是要域名,无法直接使用IP。PS:可能大家有别的方法,这是我了解到的方法了。
进入这个页面。
在微信公众号的:设置与开发-开发-开发者工具-公众平台测试账号
屏幕截图 2021-09-28 221213.jpg
填写URL和Token
内网穿透的那个URL。再加GetMapping中设的路由,比如我设的是connect。就加上/connect。Tip:不能是POST。
image.png
pic3.jpg
[图片上传中...(image.png-fcb7b4-1632838674076-0)]
设计一个类来接收数据 ConnectEntity
根据微信文档,连接时会传这些数据
image.png
那么设置一个类包含这些属性
//这三个为lombok中注解,get-set toString,全参构造器,无参构造器
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ConnectEntity {
private String signature;
private String timestamp;
private String nonce;
private String echostr;
}
开始连接
1、声明变量Token【在测试号中所填写的】
2、根据文档-将token、timestamp、nonce三个参数进行字典序排序
String Token = "填写的Token";
// 字典序排序
String[] getStr = new String[]{Token, connectInfo.getTimestamp(), connectInfo.getNonce()};
Arrays.sort(getStr);
3、将三个参数字符串拼接成一个字符串进行sha1加密
//sha1加密
String strConn = getStr[0] + getStr[1] + getStr[2];
//sha1 需要的时字节数组, 转化成的 也是字符数组
//需要与signature 比较, signature是字符串,所以需要将加密后的字符数组转化为字符串
//引入一个char[] 已知为16进制
char[] changeChar = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e',
'f'};
try {
MessageDigest messageDigest = MessageDigest.getInstance("sha1");
byte[] digest = messageDigest.digest(strConn.getBytes());
StringBuilder sb = new StringBuilder();
for (byte b :
digest) {
sb.append(changeChar[(b >> 4) & 15]);
sb.append(changeChar[(b) & 15]);
}
String s = sb.toString();
4、开发者获得加密后的字符串可与signature对比
使用equals,为true则给一个反馈。
String signature = connectInfo.getSignature();
// 比较两个是否相同
if(s.equals(signature)){
// 给一个反馈
PrintWriter writer = resp.getWriter();
writer.write(connectInfo.getEchostr());
writer.flush();
writer.close();
}
至此连接成功。
完整代码
接收数据的类
//这三个为lombok中注解,get-set toString,全参构造器,无参构造器
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ConnectEntity {
private String signature;
private String timestamp;
private String nonce;
private String echostr;
}
// 微信与后台connect
@GetMapping(value = "/connect")
public void connectWx(ConnectEntity connectInfo, HttpServletResponse resp) {
//
String Token = "修改为你的Token!!!";
// 字典序排序
String[] getStr = new String[]{Token, connectInfo.getTimestamp(), connectInfo.getNonce()};
Arrays.sort(getStr);
//sha1加密
String strConn = getStr[0] + getStr[1] + getStr[2];
//sha1 需要的时字节数组, 转化成的 也是字符数组
//需要与signature 比较, signature是字符串,所以需要将加密后的字符数组转化为字符串
//引入一个char[] 已知为16进制
char[] changeChar = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e',
'f'};
try {
MessageDigest messageDigest = MessageDigest.getInstance("sha1");
byte[] digest = messageDigest.digest(strConn.getBytes());
StringBuilder sb = new StringBuilder();
for (byte b :
digest) {
sb.append(changeChar[(b >> 4) & 15]);
sb.append(changeChar[(b) & 15]);
}
String s = sb.toString();
//System.out.println(s);
String signature = connectInfo.getSignature();
// 比较两个是否相同
if(s.equals(signature)){
// 给一个反馈
PrintWriter writer = resp.getWriter();
writer.write(connectInfo.getEchostr());
writer.flush();
writer.close();
}
} catch (NoSuchAlgorithmException | IOException e) {
e.printStackTrace();
}
}
网友评论