企業微信接收回調



1 應用場景

審批回調,其實任何需要回調的接口邏輯相同,會一種即可

企業微信后台配置接口地址細心的同學已經發現了,這貨的參數跟微信的差不了多少。

1.1 企微后台配置

在這里插入圖片描述

1.2 配置配置項

其一是回調的接口地址,其二是需要驗簽用的token,其三是隨機的key,然后我們看一下回調接口的回調參數

在這里插入圖片描述

2 回調接口

2.1 請求方式get

這個是企微文檔的回調接口

然后看到回調參數有

msg_signature=ASDFQWEXZCVAQFASDFASDFSS
timestamp=13500001234
nonce=123412323
echostr=ENCRYPT_STR
根據企微提供的加密類我們可以直接對該參數進行解密

post請求為企微驗證通過之后發送的數據(接口地址與get請求一樣)

接口實現
首先是get請求

 /** * get 請求 驗簽. * * @param msgSignature 加密 * @param timestamp 時間戳 * @param nonce 隨機 * @param echostr . * @param response . * @throws Exception . */
    @GetMapping(value = "/callback")
    public void reveiceMsg(@RequestParam(name = "msg_signature") final String msgSignature,
                           @RequestParam(name = "timestamp") final String timestamp,
                           @RequestParam(name = "nonce") final String nonce,
                           @RequestParam(name = "echostr") final String echostr,
                           final HttpServletResponse response) throws Exception {
        //企業回調的url-----該url不做任何的業務邏輯,僅僅微信查看是否可以調通.
        WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(token,corpid, encodingAesKey);
        // 隨機字符串
        String sEchoStr = wxcpt.verifyURL(msgSignature, timestamp, nonce, echostr);
        PrintWriter out = response.getWriter();
        try {
            //必須要返回解密之后的明文
            if (StringUtils.isBlank(sEchoStr)) {
                System.out.println("URL驗證失敗");
            } else {
                System.out.println("驗證成功!");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        out.write(sEchoStr);
        out.flush();
    } 

get請求有可能解密失敗

2.2 請求方式post

 /** * 企業微信客戶聯系回調. * * @param request request * @param sMsgSignature 簽名 * @param sTimestamp 時間戳 * @param sNonce 隨機值 * @return success */
    @ResponseBody
    @PostMapping(value = "/callback")
    public String callback(final HttpServletRequest request,
                              @RequestParam(name = "msg_signature") final String sMsgSignature,
                              @RequestParam(name = "timestamp") final String sTimestamp,
                              @RequestParam(name = "nonce") final String sNonce) {

        try {
            InputStream inputStream = request.getInputStream();
            String sPostData = IOUtils.toString(inputStream, "UTF-8");
        WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(token,corpid, encodingAesKey); 
            //解密
            String sMsg = msgCrypt.decryptMsg(msgSignature, timeStamp, String nonce, postData);
            //將post數據轉換為map
            Map<String, String> dataMap = MessageUtil.parseXml(sMsg);
            //然后去操作你的業務邏輯
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "success";
    }

配置完成調試接口即可

3 解析xml代碼

 DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
            DocumentBuilder db = dbf.newDocumentBuilder();
            StringReader sr = new StringReader(msg);
            InputSource is = new InputSource(sr);
            Document document = db.parse(is);
            Element root = document.getDocumentElement();
            // 獲取提交用戶ID
            NodeList ApprovalInfo = root.getElementsByTagName("ApprovalInfo");
            if (ApprovalInfo == null || ApprovalInfo.getLength() == 0) {
                logger.error("ApprovalInfo is null");
                logger.error(msg);
                return;
            }
            // 獲取審批狀態
            String spNo = "";
            String spStatus = "";
            NodeList nodes = ApprovalInfo.item(0).getChildNodes();
            for (int i = 0; i < nodes.getLength(); i++) {
                Node node = nodes.item(i);
                String nodeName = node.getNodeName();
                String text = node.getTextContent();
                if ("SpNo".equals(nodeName)) {
                    spNo = text;
                } else if ("SpStatus".equals(nodeName)) {
                    spStatus = text;
                }
            }

可能有xml轉java對象但是我用起來不是很好用,個人覺得還很差勁,所以我想用xml轉jsonobject好一些

import org.apache.commons.lang.StringUtils;
import org.jdom2.Document;
import org.jdom2.JDOMException;
import com.alibaba.fastjson.JSONObject;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;
 
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.LinkedList;
import java.util.List;
 
/** * Created by alany on 2018/7/10. */
public class XmlUtils {
    public static JSONObject xml2Json(String xmlStr) throws JDOMException, IOException {
        if (StringUtils.isEmpty(xmlStr)) {
            return null;
        }
        xmlStr = xmlStr.replaceAll("\\\n", "");
        byte[] xml = xmlStr.getBytes("UTF-8");
        JSONObject json = new JSONObject();
        InputStream is = new ByteArrayInputStream(xml);
        SAXBuilder sb = new SAXBuilder();
        Document doc = sb.build(is);
        Element root = doc.getRootElement();
        json.put(root.getName(), iterateElement(root));
 
        return json;
    }
 
    private static JSONObject iterateElement(Element element) {
        List<Element> node = element.getChildren();
        JSONObject obj = new JSONObject();
        List list = null;
        for (Element child : node) {
            list = new LinkedList();
            String text = child.getTextTrim();
            if (StringUtils.isBlank(text)) {
                if (child.getChildren().size() == 0) {
                    continue;
                }
                if (obj.containsKey(child.getName())) {
                    list = (List) obj.get(child.getName());
                }
                list.add(iterateElement(child)); //遍歷child的子節點
                obj.put(child.getName(), list);
            } else {
                if (obj.containsKey(child.getName())) {
                    Object value = obj.get(child.getName());
                    try {
                        list = (List) value;
                    } catch (ClassCastException e) {
                        list.add(value);
                    }
                }
                if (child.getChildren().size() == 0) { //child無子節點時直接設置text
                    obj.put(child.getName(), text);
                } else {
                    list.add(text);
                    obj.put(child.getName(), list);
                }
            }
        }
        return obj;
    }

用到的依賴

<dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.32</version>
 </dependency>
 <dependency>
        <groupId>org.jdom</groupId>
        <artifactId>jdom</artifactId>
        <version>2.0.2</version>
 </dependency>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM