package com.smtaiserver.smtaiserver.util.SMTWXSStatic;
|
|
import cn.hutool.http.HttpUtil;
|
import com.smtaiserver.smtaiserver.control.SMTAIServerControl;
|
import com.smtaiserver.smtaiserver.core.SMTAIServerApp;
|
import com.smtservlet.core.SMTRequest;
|
import com.smtservlet.util.Json;
|
import org.apache.logging.log4j.LogManager;
|
import org.apache.logging.log4j.Logger;
|
import org.dom4j.Document;
|
import org.dom4j.DocumentException;
|
import org.dom4j.Element;
|
import org.dom4j.io.SAXReader;
|
import org.springframework.boot.configurationprocessor.json.JSONObject;
|
import org.springframework.web.servlet.ModelAndView;
|
|
import javax.servlet.ServletInputStream;
|
import javax.servlet.http.HttpServletRequest;
|
import java.io.IOException;
|
import java.io.OutputStream;
|
import java.net.HttpURLConnection;
|
import java.net.URL;
|
import java.nio.charset.StandardCharsets;
|
import java.security.MessageDigest;
|
import java.security.NoSuchAlgorithmException;
|
import java.util.HashMap;
|
import java.util.List;
|
import java.util.Map;
|
|
import static java.util.Arrays.sort;
|
|
public class WeixinuUtil {
|
private static Logger _logger = LogManager.getLogger(SMTAIServerControl.class);
|
|
/** 微信验证 */
|
public static ModelAndView getModelAndView(SMTRequest tranReq) throws Exception {
|
String signature = tranReq.convParamToString("signature", true);
|
String timestamp = tranReq.convParamToString("timestamp", true);
|
String nonce = tranReq.convParamToString("nonce", true);
|
String echostr = tranReq.convParamToString("echostr", true);
|
// 获取微信请求参数
|
_logger.info(
|
"开始校验此次消息是否来自微信服务器,param->signature:{},\ntimestamp:{},\nnonce:{},\nechostr:{}",
|
signature,
|
timestamp,
|
nonce,
|
echostr);
|
// 需要验证的时候就启用
|
if (checkSignature(signature, timestamp, nonce)) {
|
return tranReq.returnText(echostr);
|
}
|
return tranReq.returnText("");
|
}
|
|
/** 验证签名util */
|
public static boolean checkSignature(String signature, String timestamp, String nonce)
|
throws Exception {
|
HashMap<String, String> weixinParam = getWeixinParam();
|
String[] arr = new String[] {weixinParam.get("token"), timestamp, nonce};
|
// 将token、timestamp、nonce三个参数进行字典序排序
|
// Arrays.sort(arr);
|
sort(arr);
|
StringBuilder content = new StringBuilder();
|
for (String s : arr) {
|
content.append(s);
|
}
|
MessageDigest md = null;
|
String tmpStr = null;
|
|
try {
|
md = MessageDigest.getInstance("SHA-1");
|
// 将三个参数字符串拼接成一个字符串进行sha1加密
|
byte[] digest = md.digest(content.toString().getBytes());
|
tmpStr = byteToHex(digest);
|
} catch (NoSuchAlgorithmException e) {
|
_logger.error("签名异常", e);
|
}
|
content = null;
|
// 将sha1加密后的字符串可与signature对比,标识该请求来源于微信
|
|
return tmpStr != null && tmpStr.equals(signature.toUpperCase());
|
}
|
|
public static HashMap<String, String> getWeixinParam() throws Exception {
|
Object weixinParam = SMTAIServerApp.getApp().getGlobalConfig("weixin_core_param", "false");
|
_logger.info("微信参数:{}", weixinParam);
|
JSONObject weixinJson = new JSONObject(weixinParam.toString());
|
String appId = (String) weixinJson.get("appId");
|
String secret = (String) weixinJson.get("secret");
|
String token = (String) weixinJson.get("token");
|
HashMap<String, String> paramMap = new HashMap<>();
|
paramMap.put("appId", appId);
|
paramMap.put("secret", secret);
|
paramMap.put("token", token);
|
return paramMap;
|
}
|
|
public static Map<String, String> getWechatReqMap(HttpServletRequest request) {
|
Map<String, String> requestMap = new HashMap<>();
|
SAXReader reader = new SAXReader();
|
try (ServletInputStream inputStream = request.getInputStream()) {
|
Document document = reader.read(inputStream);
|
Element root = document.getRootElement();
|
List<Element> elementList = root.elements();
|
for (Element e : elementList) {
|
requestMap.put(e.getName(), e.getText());
|
}
|
} catch (IOException | DocumentException e) {
|
throw new RuntimeException(e);
|
}
|
return requestMap;
|
}
|
|
/**
|
* 将字节数组转换为十六进制字符串
|
*
|
* @param byteArray
|
* @return
|
*/
|
private static String byteToStr(byte[] byteArray) {
|
StringBuilder strDigest = new StringBuilder();
|
for (byte b : byteArray) {
|
strDigest.append(byteToHexStr(b));
|
}
|
return strDigest.toString();
|
}
|
|
/**
|
* 将字节转换为十六进制字符串
|
*
|
* @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;
|
}
|
|
public static String byteToHex(byte[] data)
|
{
|
String hex = "0123456789ABCDEF";
|
StringBuilder sb = new StringBuilder();
|
for(byte v : data)
|
{
|
sb.append(hex.charAt((v >> 4) & 0x0F));
|
sb.append(hex.charAt(v & 0x0F));
|
//sb.append(String.format("%02X", v));
|
}
|
return sb.toString();
|
}
|
|
public static String sendPost(String urlString, Json jsonParam) throws Exception {
|
// 将参数转换为 JSON 格式字符串
|
// JSONObject jsonParams = new JSONObject(params);
|
String payload = jsonParam.toString();
|
// 创建连接
|
URL url = new URL(urlString);
|
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
connection.setRequestMethod("POST");
|
// 设置请求头
|
connection.setRequestProperty("Content-Type", "application/json;charset=UTF-8");
|
connection.setDoOutput(true);
|
// 写入请求体
|
try (OutputStream os = connection.getOutputStream()) {
|
byte[] input = payload.getBytes(StandardCharsets.UTF_8);
|
os.write(input, 0, input.length);
|
}
|
// 读取响应
|
try (java.io.InputStream in = connection.getInputStream()) {
|
java.util.Scanner scanner = new java.util.Scanner(in).useDelimiter("\\A");
|
return scanner.hasNext() ? scanner.next() : "";
|
}
|
}
|
}
|