|
@@ -19,12 +19,26 @@ import org.apache.commons.lang3.StringUtils;
|
|
|
import org.slf4j.Logger;
|
|
|
import org.slf4j.LoggerFactory;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.util.StreamUtils;
|
|
|
import org.springframework.web.bind.annotation.GetMapping;
|
|
|
import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
import org.springframework.web.bind.annotation.RestController;
|
|
|
+import org.w3c.dom.Node;
|
|
|
+import org.w3c.dom.NodeList;
|
|
|
|
|
|
import javax.servlet.http.HttpServletRequest;
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
+import javax.xml.parsers.DocumentBuilder;
|
|
|
+import javax.xml.parsers.DocumentBuilderFactory;
|
|
|
+import javax.xml.transform.OutputKeys;
|
|
|
+import javax.xml.transform.Transformer;
|
|
|
+import javax.xml.transform.TransformerFactory;
|
|
|
+import javax.xml.transform.dom.DOMSource;
|
|
|
+import javax.xml.transform.stream.StreamResult;
|
|
|
+import java.io.*;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.HashMap;
|
|
|
+import java.util.Map;
|
|
|
|
|
|
/**
|
|
|
* @author wwl
|
|
@@ -97,12 +111,12 @@ public class TestController {
|
|
|
String nonce = request.getParameter("nonce");
|
|
|
String echostr = request.getParameter("echostr");
|
|
|
log.info("本身" + signature);
|
|
|
- if (SignUtil.checkSignature(signature, timestamp, nonce)) {
|
|
|
-
|
|
|
- //消息处理
|
|
|
- WexHandeler(request);
|
|
|
-
|
|
|
- return echostr;
|
|
|
+ if(request.getMethod().equals("GET")){
|
|
|
+ log.info("-----------微信验签---------");
|
|
|
+ return SignUtil.checkSignature(signature, timestamp, nonce) == true ? echostr : null;
|
|
|
+ }else{
|
|
|
+ //推送消息处理
|
|
|
+ handlePublicMsg(request);
|
|
|
}
|
|
|
} catch (Exception e) {
|
|
|
log.error("验证公众号token失败", e);
|
|
@@ -163,6 +177,157 @@ public class TestController {
|
|
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
+ * 处理微信公众号请求信息
|
|
|
+ */
|
|
|
+ public String handlePublicMsg(HttpServletRequest request) throws Exception {
|
|
|
+ // 获得微信端返回的xml数据
|
|
|
+ /*InputStream is = null;
|
|
|
+ InputStreamReader isr = null;
|
|
|
+ BufferedReader br = null;*/
|
|
|
+ try {
|
|
|
+ /*is = request.getInputStream();
|
|
|
+ isr = new InputStreamReader(is, "utf-8");
|
|
|
+ br = new BufferedReader(isr);
|
|
|
+ String str = null;
|
|
|
+ StringBuffer returnXml= new StringBuffer();
|
|
|
+ while ((str = br.readLine()) != null) {
|
|
|
+ //返回的是xml数据
|
|
|
+ returnXml.append(str);
|
|
|
+ }*/
|
|
|
+// Map<String, String> decryptMap = xmlToMap(returnXml.toString());
|
|
|
+ Map<String, String> decryptMap = xmlToMap(IOUtils.toString(request.getInputStream()));
|
|
|
+// // 得到公众号传来的加密信息并解密,得到的是明文xml数据
|
|
|
+// String decryptXml = WXPublicUtils.decrypt(encryptMap.get("Encrypt"));
|
|
|
+ // 将xml数据转换为map
|
|
|
+ //Map<String, String> decryptMap = xmlToMap(encryptMap);
|
|
|
+
|
|
|
+ // 区分消息类型
|
|
|
+ String msgType = decryptMap.get("MsgType");
|
|
|
+ // 普通消息
|
|
|
+ if ("text".equals(msgType)) { // 文本消息
|
|
|
+ // todo 处理文本消息
|
|
|
+ } else if ("image".equals(msgType)) { // 图片消息
|
|
|
+ // todo 处理图片消息
|
|
|
+ }
|
|
|
+
|
|
|
+ // 事件推送
|
|
|
+ else if ("event".equals(msgType)) { // 事件消息
|
|
|
+ // 区分事件推送
|
|
|
+ String event = decryptMap.get("Event");
|
|
|
+ if ("subscribe".equals(event)) { // 订阅事件 或 未关注扫描二维码事件
|
|
|
+ // 返回消息时ToUserName的值与FromUserName的互换
|
|
|
+ Map<String, String> returnMap = new HashMap<>();
|
|
|
+ returnMap.put("ToUserName", decryptMap.get("FromUserName"));
|
|
|
+ returnMap.put("FromUserName", decryptMap.get("ToUserName"));
|
|
|
+ returnMap.put("CreateTime", new Date().getTime()+"");
|
|
|
+ returnMap.put("MsgType", "text");
|
|
|
+ returnMap.put("Content", "测试哈哈哈哈");
|
|
|
+ String encryptMsg = mapToXml(returnMap);
|
|
|
+ return encryptMsg;
|
|
|
+ } else if ("unsubscribe".equals(event)) { // 取消订阅事件
|
|
|
+ // todo 处理取消订阅事件
|
|
|
+ } else if ("SCAN".equals(event)) { // 已关注扫描二维码事件
|
|
|
+ // 返回消息时ToUserName的值与FromUserName的互换
|
|
|
+ Map<String, String> returnMap = new HashMap<>();
|
|
|
+ returnMap.put("ToUserName", decryptMap.get("FromUserName"));
|
|
|
+ returnMap.put("FromUserName", decryptMap.get("ToUserName"));
|
|
|
+ returnMap.put("CreateTime", new Date().getTime()+"");
|
|
|
+ returnMap.put("MsgType", "text");
|
|
|
+ returnMap.put("Content", "测试哈哈哈哈");
|
|
|
+ String encryptMsg = mapToXml(returnMap);
|
|
|
+ return encryptMsg;
|
|
|
+ } else if ("LOCATION".equals(event)) { // 上报地理位置事件
|
|
|
+ // todo 处理上报地理位置事件
|
|
|
+ } else if ("CLICK".equals(event)) { // 点击菜单拉取消息时的事件推送事件
|
|
|
+ // todo 处理点击菜单拉取消息时的事件推送事件
|
|
|
+ } else if ("VIEW".equals(event)) { // 点击菜单跳转链接时的事件推送
|
|
|
+ // todo 处理点击菜单跳转链接时的事件推送
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("处理微信公众号请求信息,失败", e);
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ /**
|
|
|
+ * XML格式字符串转换为Map
|
|
|
+ *
|
|
|
+ * @param strXML XML字符串
|
|
|
+ * @return XML数据转换后的Map
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public static Map<String, String> xmlToMap(String strXML) throws Exception {
|
|
|
+ try {
|
|
|
+ Map<String, String> data = new HashMap<>();
|
|
|
+ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
|
|
+ DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
|
|
|
+ InputStream stream = new ByteArrayInputStream(strXML.getBytes("UTF-8"));
|
|
|
+ org.w3c.dom.Document doc = documentBuilder.parse(stream);
|
|
|
+ doc.getDocumentElement().normalize();
|
|
|
+ NodeList nodeList = doc.getDocumentElement().getChildNodes();
|
|
|
+ for (int idx = 0; idx < nodeList.getLength(); ++idx) {
|
|
|
+ Node node = nodeList.item(idx);
|
|
|
+ if (node.getNodeType() == Node.ELEMENT_NODE) {
|
|
|
+ org.w3c.dom.Element element = (org.w3c.dom.Element) node;
|
|
|
+ data.put(element.getNodeName(), element.getTextContent());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ stream.close();
|
|
|
+ } catch (Exception ex) {
|
|
|
+ // do nothing
|
|
|
+ }
|
|
|
+ return data;
|
|
|
+ } catch (Exception ex) {
|
|
|
+ throw ex;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 将Map转换为XML格式的字符串
|
|
|
+ *
|
|
|
+ * @param data Map类型数据
|
|
|
+ * @return XML格式的字符串
|
|
|
+ * @throws Exception
|
|
|
+ */
|
|
|
+ public static String mapToXml(Map<String, String> data) throws Exception {
|
|
|
+ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
|
|
+ DocumentBuilder documentBuilder= documentBuilderFactory.newDocumentBuilder();
|
|
|
+ org.w3c.dom.Document document = documentBuilder.newDocument();
|
|
|
+ org.w3c.dom.Element root = document.createElement("xml");
|
|
|
+ document.appendChild(root);
|
|
|
+ for (String key: data.keySet()) {
|
|
|
+ String value = data.get(key);
|
|
|
+ if (value == null) {
|
|
|
+ value = "";
|
|
|
+ }
|
|
|
+ value = value.trim();
|
|
|
+ org.w3c.dom.Element filed = document.createElement(key);
|
|
|
+ filed.appendChild(document.createTextNode(value));
|
|
|
+ root.appendChild(filed);
|
|
|
+ }
|
|
|
+ TransformerFactory tf = TransformerFactory.newInstance();
|
|
|
+ Transformer transformer = tf.newTransformer();
|
|
|
+ DOMSource source = new DOMSource(document);
|
|
|
+ transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
|
|
|
+ transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
|
|
+ StringWriter writer = new StringWriter();
|
|
|
+ StreamResult result = new StreamResult(writer);
|
|
|
+ transformer.transform(source, result);
|
|
|
+ String output = writer.getBuffer().toString(); //.replaceAll("\n|\r", "");
|
|
|
+ try {
|
|
|
+ writer.close();
|
|
|
+ } catch (Exception ex) {
|
|
|
+
|
|
|
+ }
|
|
|
+ return output;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
|
|
|
|
|
|
}
|