没有公众号的可以使用微信测试号进行开发
申请测试号地址:https://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
微信开发文档:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421135319
ngrok下载地址:https://ngrok.com/
一、首先创建一个SpringBoot工程、这里使用idea进行开发:
1.1.file>New>Project 选择Spring Initializr :
1.2.点击next 填写相关信息,直接下一步就行
1.3.创建完成的项目结构为:
二、开发前准备:
2.1.申请测试号、准备ngrok,用来映射本地端口,访问到自己的项目,因为微信服务器不支持IP
三、通过开发文档可以看出,第一步需要填写服务器地址,也就是指的是项目地址,然后微信会发送请求到后台,我们验证消息是否来自微信
3.1.验证微信消息:
1.通过文档可以看到,通过第一步触发微信给后台发送请求,然后可以接收到的参数为:
signature微信加密签名,signature结合了开发者填写的token参数和请求中的timestamp参数、nonce参数。timestamp时间戳nonce随机数echostr随机字符串
2.接收到参数以后,我们需要验证signature
3.验证方式:
1)将token、timestamp、nonce三个参数进行字典序排序
2)将三个参数字符串拼接成一个字符串进行sha1加密
3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
3.2.代码实现:
微信常亮类:
package com.wechat.constant;
/**
* @CreatUser : lsy
* @CreatTime : 2019/1/8 16:30
*/
public class WxConstants {
//这里写测试号的appid
public static final String APP_ID="APP_ID";
//这里写测试号的appsecret
public static final String APP_SECRET="APP_SECRET";
//这里写你自己定义的token
public static final String TOKEN="TEST";
}
sha1加密工具类:
package com.wechat.utils;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
/**
* 加密工具类
* @CreatUser : lsy
* @CreatTime : 2019/1/8 16:41
*/
public class EncryptionUtil {
private static final char[] HEX_DIGITS = { '0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
/**
* 加密
* @param algorithm 算法名称
* @param body 加密的字符串
* @return 加密过后的字符串
*/
public static String encrypt(String algorithm,String body){
if(algorithm==null||body==null){
return null;
}
try {
//这是java自带的加密工具
MessageDigest digest = MessageDigest.getInstance(algorithm);
digest.update(body.getBytes());
return getFormattedText(digest.digest());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
return null;
}
}
private static String getFormattedText(byte[] bytes) {
int len = bytes.length;
StringBuilder buf = new StringBuilder(len * 2);
// 把密文转换成十六进制的字符串形式
for (int j = 0; j < len; j++) {
buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
}
return buf.toString();
}
}
微信消息控制器(获取微信发的参数,然后加密验证):
package com.wechat.controller;
import com.wechat.constant.WxConstants;
import com.wechat.utils.EncryptionUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Array;
import java.util.Arrays;
/**
* @CreatUser : lsy
* @CreatTime : 2019/1/8 16:10
*/
@RestController
@RequestMapping(value = "wx")
public class WechatMsgController {
private Logger logger=LoggerFactory.getLogger(WechatMsgController.class);
/**
* 验证微信消息
*
* @param request
* @return
*/
@GetMapping(value = "/check")
public String checkWxMsg(HttpServletRequest request) {
/**
* 微信加密签名
*/
String signature = request.getParameter("signature");
/**
* 随机字符串
*/
String echostr = request.getParameter("echostr");
/**
* 时间戳
*/
String timestamp = request.getParameter("timestamp");
/**
* 随机数
*/
String nonce = request.getParameter("nonce");
String[] str={timestamp,nonce,WxConstants.TOKEN};
//将token、timestamp、nonce三个参数进行字典序排序
Arrays.sort(str);
StringBuffer sb = new StringBuffer();
//将三个参数字符串拼接成一个字符串进行sha1加密
for (String param:str) {
sb.append(param);
}
//获取到加密过后的字符串
String encryptStr = EncryptionUtil.encrypt("SHA1", sb.toString());
//判断加密后的字符串是否与微信的签名一致
if(signature.equalsIgnoreCase(encryptStr)){
return echostr;
}
logger.error("这不是微信发来的消息!!");
return null;
}
}