一、需求说明
用Java程序对接企业微信的审批流程,获取审批数据数据,例如:报销费用金额
二、操作步骤
2.1、分析需求
根据需求分析其实也不知道该怎么去做对接,通过不断试错,发现不需要对接第三方应用,也就是不需要进入服务商后台页面,只需要在自建应用是做好配置即可。
具体参考:https://developer.work.weixin.qq.com/document/path/90665
2.2、搭建 自建应用
前言
这里先介绍一下关键参数从哪里取,具体详见官方文档:https://developer.work.weixin.qq.com/document/path/90665#corpid
corpid,每个企业都拥有唯一的corpid,获取此信息可在管理后台“我的企业”-“企业信息”下查看“企业ID”(需要有管理员权限)
Token、EncodingAESKey:是在自建应用-API接受消息中随机获取的到时候进行保存即可,具体见下图
secret
secret是企业应用里面用于保障数据安全的“钥匙”,每一个应用都有一个独立的访问密钥,为了保证数据的安全,secret务必不能泄漏。secret查看方法:
在管理后台->“应用管理”->“应用”->“自建”,点进某个应用,即可看到。
2.2.1、创建 自建应用
注: 选择可见范围根据业务需求进行选择,如果是针对全公司的业务,则需要选全公司,不然会获取不到数据进行报错
2.2.3、配置接收消息即回调地址
其中回调URL的配置需要写对应的回调方法,具体可以参考:Demo(https://developer.work.weixin.qq.com/devtool/introduce?id=10128),这里建议使用XML格式,因为获取审批流程中的参数都是XML格式。具体见下图:
// 这个方法是进行回调验证的。下面还有一个同样的方法差别仅是将GET换为POST方法,用于接收信息的。
@RequestMapping(value = "/callback/data",method = RequestMethod.GET) public void connect(HttpServletRequest request, HttpServletResponse response){ //当你提交以上信息时,企业号将发送GET请求到填写的URL上,GET请求携带四个参数,企业在获取时需要做urldecode处理,否则会验证不成功 // 微信加密签名 String msg_signature = request.getParameter("msg_signature"); // 时间戳 String timestamp = request.getParameter("timestamp"); // 随机数 String nonce = request.getParameter("nonce"); // 随机字符串 String echoStr = request.getParameter("echostr"); //回调key值 String sEchoStr = null; String contacts_token = PropertiesUtil.getProperty("contacts_token"); String contacts_encodingaeskey = PropertiesUtil.getProperty("contacts_encodingaeskey"); String corpId = PropertiesUtil.getProperty("corpid"); try { PrintWriter out = response.getWriter(); WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(contacts_token,contacts_encodingaeskey,corpId); sEchoStr = wxcpt.VerifyURL(msg_signature,timestamp,nonce,echoStr); if(StringUtils.isBlank(sEchoStr)){ logger.error("URL验证失败"); } out.write(sEchoStr); out.flush(); }catch (Exception e){ logger.error("企业微信回调url验证错误",e); } }
2.2.4、配置IP白名单
多个IP用英文分号进行区分
2.2.5、在审批应用中配置回调通知
2.2.6、写程序获取审批流程数据
走完前面流程后,再部署上下面的代码后,就可以了。当有要监控回调的审批数据后,就会调用下面的方法,拿到审批数据。
具体里面会用到三个知识点。
1、会用到官方接口文档中:开发指南-回调配置-3.2 支持Http Post请求接收业务数据,详见:https://developer.work.weixin.qq.com/document/path/90930#32-%E6%94%AF%E6%8C%81http-post%E8%AF%B7%E6%B1%82%E6%8E%A5%E6%94%B6%E4%B8%9A%E5%8A%A1%E6%95%B0%E6%8D%AE
2、会用到官方接口文档中:开发指南-获取access_token,详见:https://developer.work.weixin.qq.com/document/path/91039
3、会用到官方接口文档中:审批-获取审批申请详情,详见:https://developer.work.weixin.qq.com/document/path/91983
@RequestMapping(value = "/callback/data",method = RequestMethod.POST) public void acceptMessage(HttpServletRequest request, RedirectAttributes attributes, HttpSession session){ System.out.println("————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————"); logger.debug("企业微信信息交互"); // 微信加密签名 String sMsgSignature = request.getParameter("msg_signature"); // 时间戳 String sTimestamp = request.getParameter("timestamp"); // 随机数 String sNonce = request.getParameter("nonce"); System.out.println("acceptMessage方法sMsgSignature: " + sMsgSignature); System.out.println("acceptMessage方法sTimestamp: " + sTimestamp); System.out.println("acceptMessage方法sNonce: " + sNonce); try{ // 获取请求的输入流 ServletInputStream inputStream = request.getInputStream(); // 创建一个 StringBuilder 对象来存储请求内容 StringBuilder xmlContent = new StringBuilder(); // 使用 BufferedReader 读取输入流内容 BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); String line; while ((line = reader.readLine()) != null) { xmlContent.append(line); } // 关闭输入流和读取器 inputStream.close(); reader.close(); // 输出请求内容 System.out.println("请求 XML 内容:" + xmlContent.toString()); String sReqData = xmlContent.toString(); // String sReqData = "<xml><ToUserName><![CDATA[wx5823bf96d3bd56c7]]></ToUserName><Encrypt><![CDATA[RypEvHKD8QQKFhvQ6QleEB4J58tiPdvo+rtK1I9qca6aM/wvqnLSV5zEPeusUiX5L5X/0lWfrf0QADHHhGd3QczcdCUpj911L3vg3W/sYYvuJTs3TUUkSUXxaccAS0qhxchrRYt66wiSpGLYL42aM6A8dTT+6k4aSknmPj48kzJs8qLjvd4Xgpue06DOdnLxAUHzM6+kDZ+HMZfJYuR+LtwGc2hgf5gsijff0ekUNXZiqATP7PF5mZxZ3Izoun1s4zG4LUMnvw2r+KqCKIw+3IQH03v+BCA9nMELNqbSf6tiWSrXJB3LAVGUcallcrw8V2t9EL4EhzJWrQUax5wLVMNS0+rUPA3k22Ncx4XXZS9o0MBH27Bo6BpNelZpS+/uh9KsNlY6bHCmJU9p8g7m3fVKn28H3KDYA5Pl/T8Z1ptDAVe0lXdQ2YoyyH2uyPIGHBZZIs2pDBS8R07+qN+E7Q==]]></Encrypt><AgentID><![CDATA[218]]></AgentID></xml>"; if(!sReqData.contains("wwc892952bc0c83b95")){ //不是该应用 System.out.println("错误提交应用数据"); System.out.println("————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————"); }else{ String contacts_token = "xxx"; String corpId = "xxxx"; String contacts_encodingaeskey = "xxxx"; WXBizMsgCrypt wxcpt = new WXBizMsgCrypt(contacts_token,contacts_encodingaeskey,corpId); String sMsg = wxcpt.DecryptMsg(sMsgSignature, sTimestamp, sNonce, sReqData); System.out.println("after decrypt msg: " + sMsg); // TODO: 解析出明文xml标签的内容进行处理 // For example: DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); DocumentBuilder db = dbf.newDocumentBuilder(); StringReader sr = new StringReader(sMsg); InputSource is = new InputSource(sr); Document document = db.parse(is); Element root = document.getDocumentElement(); NodeList nodelist1 = root.getElementsByTagName("SpNo"); // 获取审批编号 String SpNo = nodelist1.item(0).getTextContent(); System.out.println("审批编号为:" + SpNo); NodeList SpStatus_Node = root.getElementsByTagName("SpStatus"); // 申请单状态:1-审批中;2-已通过;3-已驳回;4-已撤销;6-通过后撤销;7-已删除;10-已支付 String SpStatus = SpStatus_Node.item(0).getTextContent(); if("2".equals(SpStatus)){ // 当状态为2-已通过时进行存储 //先判断该审批编号是否已存 //获取accesstoken String accessUrl = "https://qyapi.weixin.qq.com/cgi-bin/gettoken"; String corpid = "xxxxx"; String corpsecret = "xxxx"; accessUrl=accessUrl+"?corpid="+corpid+"&corpsecret="+corpsecret; System.out.println("请求access_token请求参数:"+accessUrl); String result = HttpUtil.get(accessUrl); JSONObject resultJson = JSON.parseObject(result); System.out.println("请求access_token返回结果:"+resultJson); String access_token = resultJson.getString("access_token"); String getapprovalUrl = "https://qyapi.weixin.qq.com/cgi-bin/oa/getapprovaldetail?access_token="+access_token; JSONObject params = new JSONObject(); params.put("sp_no", SpNo); System.out.println("请求获取审批详情接口请求参数:"+params); String post_result = HttpUtil.post(getapprovalUrl, params.toJSONString()); JSONObject postJson = JSON.parseObject(post_result); System.out.println("请求获取审批详情接口返回结果:"+postJson); System.out.println("————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————————"); } } }catch (Exception e){ logger.error("企业微信消息交互错误",e); } }
三、总结
个人感觉企微的开发文档写的特别垃圾,绕来绕去的很不清晰。希望自己整理后后面再看的时候有些帮助。
标签:Java,String,request,微信,对接,System,token,println,out From: https://www.cnblogs.com/Lonnn/p/18429282