很久没来。5个多月了。换了工作比较忙。还是立志写一份老太太、老爷爷都能看懂的文章。
1、基本的东西,请先看个官网。
必要条件:1、你开通了微信公众号功能。我们作为二次开发,你只需要关注你要的东西就行。
简单总结一句话,你要做的:就是给微信开放接口,让他能把请求转发给你,你再做处理。相关maven依赖在最底下
基本常识:往最底下滑,有个开发-基本配置。
上面除了二维码,其他的马赛克就是你需要重点关注的东西。
先说几个注意事项:
1、这里可以下载demo,里面有很多版本,java、php等。而不是只是php的。
2、上面服务器地址(URL)配置好了记得点击后面的启用。这里要说明,不是一开始你就改这里的。你需要有公网ip后且是80端口。这里你先不管。后面倒过来在看就好。
好了。demo你看了吧?那么接下来就是如何本地开发的问题?
1、微信如何能访问到你本地呢,这个你也先不管。就先写一个微信的认证接口。是一个get请求。
/**
* vx接入接口
*
* @author zhouyi
* @since 2021/2/25
*/
@RestController
@RequestMapping(value = "wxPublic")
@Slf4j
public class WeChatController {
@Autowired
private CoreMessage coreMessage;
// 加密验证
@RequestMapping(method = RequestMethod.GET)
public String checkToken(HttpServletRequest request, HttpServletResponse response) {
// 微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。
String signature = request.getParameter("signature");
// 时间戳
String timestamp = request.getParameter("timestamp");
// 随机数
String nonce = request.getParameter("nonce");
// 随机字符串
String echostr = request.getParameter("echostr");
log.info("微信加密签名:" + signature + ";时间戳:" + timestamp + ";随机数:" + nonce);
PrintWriter out = null;
try {
out = response.getWriter();
// 通过检验signature对请求进行校验,若校验成功则原样返回echostr,否则接入失败
if (WeixinCheckoutUtils.checkSignature(signature, timestamp, nonce)) {
log.info("微信加密签名:" + signature + ";时间戳:" + timestamp + ";随机数:" + nonce);
out.print(echostr);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
out.close();
out = null;
}
return null;
}
}
相关工具类:
/**
* 验证
*
* @author zhouyi
* @since 2021/2/26
*/
public class WeixinCheckoutUtils {
/**
* token可以自己进行定义,必须为英文或者是数字,长度为3-32字符,这个token要跟服务器配置中的token一致
*/
private static String token = "你的token";
/**
* 校验签名
* @param signature 签名
* @param timestamp 时间戳
* @param nonce 随机数
* @return 布尔值
*/
public static boolean checkSignature(String signature,String timestamp,String nonce){
String checktext = null;
if (null != signature) {
//对ToKen,timestamp,nonce 按字典排序
String[] paramArr = new String[]{
token,timestamp,nonce};
Arrays.sort(paramArr);
//将排序后的结果拼成一个字符串
String content = paramArr[0].concat(paramArr[1]).concat(paramArr[2]);
try {
MessageDigest md = MessageDigest.getInstance("SHA-1");
//对接后的字符串进行sha1加密
byte[] digest = md.digest(content.toString().getBytes());
checktext = byteToStr(digest);
} catch (NoSuchAlgorithmException e){
e.printStackTrace();
}
}
//将加密后的字符串与signature进行对比
return checktext !=null ? checktext.equals(signature.toUpperCase()) : false;
}
/**
* 将字节数组转化我16进制字符串
* @param byteArrays 字符数组
* @return 字符串
*/
private static String byteToStr(byte[] byteArrays){
String str = "";
for (int i = 0; i < byteArrays.length; i++) {
str += byteToHexStr(byteArrays[i]);
}
return str;
}
/**
* 将字节转化为十六进制字符串
* @param myByte 字节
* @return 字符串
*/
private static String byteToHexStr(byte myByte) {
char[] Digit = {
'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
char[] tampArr = new char[2];
tampArr[0] = Digit[(myByte >>> 4) & 0X0F];
tampArr[1] = Digit[myByte & 0X0F];
String str = new String(tampArr);
return str;
}
}
接口就是这三板斧。如何访问?你需要配置穿透工具或者自己配置转发到你的本地:http://127.0.0.1/wePublic
这里选择工具转发:natapp.exe,点击链接下载。
上面的文档是必看的教程。照着教程做,在这里你需要获得authtoken用来替换下面脚本的内容。
在对应的目录下:新建start.bat。建立好了后双击就好了。
start natapp -authtoken=authtoken
启动后你就会看到:映射成功。
你如果你不成功。
1、检查你的DNS是不是阿里的,114.114.144.114。不是就改DNS
2、如下参考:
C:\Users\zhouyi>nslookup auth.natapp.cn
服务器: bad.yulong.com
Address: 172.16.2.2
非权威应答:
名称: vm.aicdn.com
Address: 121.12.52.28
Aliases: auth.natapp.cn
authnatapp.b0.aicdn.com
C:\Users\zhouyi>nslookup auth.natapp.cn
服务器: public1.114dns.com
Address: 114.114.114.114
非权威应答:
名称: auth.natapp.cn.ccdomain.com
Address: 35.186.238.101
C:\Users\zhouyi>curl https://auth.natapp.cn
Hello,Your Test Request To Auth Server Is Successf
如上你就可以继续下一步了。
申请测试账号:重点token代码中的一致,url如图说明。
配置成功,你就能看到如下日志被打印了:
log.info("微信加密签名:" + signature + ";时间戳:" + timestamp + ";随机数:" + nonce);
那就认证成功,你可以开心了。可以继续开发了。
自动回复以及菜单等等事件的返回都是同上面的接口,不过不是GET请求,而是POST请求。
他们的核心是什么?根据什么类型、判断什么事件、返回什么内容就可以了。
/**
* 消息处理入口
* @param request 请求
* @param response 返回
*/
@RequestMapping(method = RequestMethod.POST)
public void post(HttpServletRequest request, HttpServletResponse response) {
log.info("消息入口开始执行");
try {
request.setCharacterEncoding("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
log.error(e.getMessage(),e);
}
response.setContentType("text/xml;charset=UTF-8");
// 核心业务:接受消息、处理消息
String respMessage = coreMessage.getMessageRequest(request);
// 响应消息
PrintWriter out = null;
try {
out = response.getWriter();
out.print(respMessage)