企业微信接收回调

简介: 企业微信接收回调

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>


目录
相关文章
|
数据安全/隐私保护
企微配置回调服务
企微配置回调服务
1740 0
|
Java fastjson API
Springboot 整合 xxljob 动态API调度任务(进阶篇)
Springboot 整合 xxljob 动态API调度任务(进阶篇)
9078 0
Springboot 整合 xxljob 动态API调度任务(进阶篇)
企业微信接入系列-上传临时素材
简述在API接口创建企业群发时上传临时素材的操作
企业微信接入系列-上传临时素材
|
人工智能 弹性计算 监控
3分钟部署HiClaw
HiClaw 是基于 OpenClaw 的开源 Agent 团队系统,含 Manager(AI 管家)与可扩展 Worker,通过 Matrix 群聊协作。安全设计(仅用消费者令牌)、开箱即用(内置 Matrix)、一键部署(curl | bash)、丰富技能生态(skills.sh),真正让 AI 团队可控、可信、易用。(239字)
3分钟部署HiClaw
|
9月前
|
人工智能 前端开发 API
【cursor】前后端分离项目下的AI跨工程管理方案
针对前后端分离项目中AI编辑器难以跨工程协作的问题,提出通过统一文件夹管理方案,将前端与后端项目置于同一根目录下,利用AI编辑器打开根目录并结合@引用功能,实现对前后端代码的联合理解与开发,提升联调效率与代码生成准确性。
1936 0
|
消息中间件 算法 Java
java如何对接企业微信
java如何对接企业微信
1604 0
|
JavaScript 算法 Java
企业微信开启接收消息+验证URL有效性
企业微信开启接收消息、验证URL有效性、SHA1、提供接收和推送给企业微信消息的加解密接口、计算消息签名接口
1390 1
企业微信开启接收消息+验证URL有效性
|
JavaScript Java 数据库
企业微信接入系列-扫码绑定/登录
讲述在企业后台管理平台账号绑定企业微信以及企业微信扫码登录企业管理平台
企业微信接入系列-扫码绑定/登录
|
存储 Java 数据安全/隐私保护
SpringBoot整合Flowable【03】- 通过Flowable-UI体验一个简单流程
本文介绍了如何使用Flowable 7.0以下版本的flowable-ui进行流程建模、发布和执行。首先,通过解压并启动flowable-ui war包,访问http://localhost:8080/flowable-ui/idm/#/login登录系统。接着,创建并绘制一个简单的绩效流程模型,包含开始节点、任务节点(自评、上级评、隔级评)和结束节点,并为各节点分配处理人。然后,创建应用并发布绩效流程。最后,通过创建a、b、c三个用户分别完成各节点任务,演示了整个流程的执行过程。本文旨在帮助读者理解Flowable的基本操作和流程元素,后续将介绍通过Java代码控制流程的方法。
5172 2
SpringBoot整合Flowable【03】- 通过Flowable-UI体验一个简单流程

热门文章

最新文章