- 微信公众平台企业号开发揭秘
- 蒋书平
- 2680字
- 2021-03-24 12:04:28
3.1 主动调用
何谓主动调用?主动调用是微信企业号基本的连接模式,为什么说它是基本的呢?因为当我们的应用需要调用企业号API的时候,建立HTTPS协议连接,数据包不需要解密,每次调用企业号API的时候,只需要调用AccessToken参数。稍后会细讲什么是AccessToken、AccessToken怎么获取及其使用期限。
3.1.1 主动调用概述
主动调用即企业号应用直接访问企业号API,根据用户的需要获取后台数据资源或发送消息给成员。主动调用不需要执行解密操作,直接连接微信企业号提供的API请求地址即可,剩下的就是获取数据并进行相应的操作处理。
3.1.2 获取AccessToken
AccessToken是请求微信API的访问票据,可以把AccessToken比喻成一张身份证,把需要做的一件事(如获取某个成员的身份信息)比喻成一个人,把微信API比喻成一个旅馆。当这个人去住旅馆时,就必须要出示身份证,以便旅馆工作人员登记这个人的入住信息,这样可以避免不法分子入住,有身份证的人才可以入住旅馆,才可以享受旅馆的服务,如此理解印象更深刻。
AccessToken需要用CorpID和Secret来获取,AccessToken使用期限为7200秒,在这个AccessToken还处于有效期内时,重复获取AccessToken将返回同一个AccessToken,直到这个AccessToken过期,再去获取AccessToken时,AccessToken才会是一个新的值。
怎么获取CorpID和Secret呢?接下来为大家详细介绍。
申请和注册企业号之后,找到需要的第一个参数CorpID,登录企业号,进入管理后台,单击“我的企业”,如图3-1所示。
进入“我的企业”页面,找到“企业信息”栏并将内容拖动到底部,如图3-2所示,界面框内的属性就是CorpID,这个属性很重要。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P53_1755.jpg?sign=1739358767-H84tM4o4Ju57KATv65WZ36VEWsIF2nY6-0-dfea72f71907f1410ed51d46cb82d8a6)
图3-1 单击“我的企业”
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P53_1756.jpg?sign=1739358767-utazFT3Ab59JDj2RPOZdMoz39xtJvxRr-0-9b5ad4393c86c9bd774b3f3400aaefc3)
图3-2 获取CorpID
获取CorpID后,接下来获取Secret。
登录企业号,进入管理后台,单击“企业应用”选项,进入“企业应用”页面,单击其中的一个应用,如果没有应用,可以新建一个,如图3-3所示。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P53_1789.jpg?sign=1739358767-W44ZourUV8U3UV8Nh3U7uuNAIMiT7WL1-0-2c1e3eb06d2718ca842569826755eb50)
图3-3 创建新的应用
单击“创建应用”选项后,弹出如图3-4所示的界面。
填写新应用信息,单击“创建应用”按钮,如图3-5所示。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P53_1773.jpg?sign=1739358767-viwPsks5D6ixjCaVPwcSWUQUaK0yJqt1-0-fc64fc3fbc354d70fead3f97d86defef)
图3-4 填写新应用信息
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P53_1774.jpg?sign=1739358767-ICKyNUYfosEoo89WApB1YEQATfonKfXc-0-c4979ef0ddac72ce1ea6b8f9d81d6df6)
图3-5 创建新的应用
稍后单击“企业应用”选项,进入“企业应用”页面,生成新应用“Android趣味堂”,如图3-6所示。
单击该应用,可以查看该应用的详情,方框内的就是Secret参数,如图3-7所示。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P54_1801.jpg?sign=1739358767-HeJ4EOwgWaZeAvXPpZf0mptus42F5V3L-0-edbce96ea5564998d8854b3da818827a)
图3-6 新应用创建完成
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P54_1802.jpg?sign=1739358767-UzGHqlnA7cI8TgBS9pMzbjTWqiJOqEs2-0-c02bd88ba4fd87f0af3ca5d35ad70f97)
图3-7 获取Secret参数
在应用详情页还可以查看该应用的可见范围,就是对某些成员可见对某些成员不可见,由开发者设置。“Android趣味堂”应用的可见范围如图3-8所示。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P54_1847.jpg?sign=1739358767-mQx8jaZEKy77BiGUaB9wTwE2mX4j64U8-0-8003e038d59d5cb7a30aad22e5f2c87c)
图3-8 应用可见范围
在应用详情页还可以设置该应用的一些功能,如发送消息、网页授权及JS-SDK、设置应用主页、接收消息、自动回复、自定义菜单、企业微信授权登录,如图3-9所示。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P54_1818.jpg?sign=1739358767-5F77kijEI6XIE5Apjyc8OZHGDye2cHvg-0-3a1c489480ba6eb219333aa2bb4440df)
图3-9 应用功能设置
在应用详情页底部有“删除应用”选项。单击后可删除该应用,如图3-10所示。
在应用详情页右侧有一个停用、启用的Switch按钮,如图3-11所示,单击该按钮可以选择是否启用应用。若停用,则会弹出一个确认停用的窗口,提示“应用停用后,该应用在客户端中的消息将被删除”,单击窗口中的“停用”按钮可停用该应用。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P54_1830.jpg?sign=1739358767-6HqAGmE9q7U43sDccswHQckhJq7lIYfH-0-31bf674032296a12f7a536e27244016c)
图3-10 删除应用
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P54_1831.jpg?sign=1739358767-p0AHE7aYHmy22doc0ooCSnqMBVQTobOM-0-165b14f171efe2836f5a9045bfdeec00)
图3-11 启用应用
至此,应用详情页的介绍就结束了,也获取了CorpID、Secret参数,接下来利用这两个参数来获取AccessToken。
在编程之前需要仔细阅读API,避免出现地址错误或参数错误,一定要看明白之后再开始写代码,否则很可能出现一些不必要的问题。
请求说明如下。
HTTPS请求方式:Get
请求地址:https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=id&corpsecret=secrect
参数说明见表3-1。
表3-1 参数说明
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-T55_65017.jpg?sign=1739358767-ALpxSWDlfRqWvl0VvTu5yTq7f0JvWFZ1-0-b442b5cff9a35fc95cf7b942f6ffa603)
正确返回结果:
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P55_65020.jpg?sign=1739358767-pEW2Sg54ZqGVTS0YROMpme8Bm2CctTmt-0-b3a62c801686204d8b83fd9bfcb78537)
参数说明见表3-2。
表3-2 参数说明
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-T55_65021.jpg?sign=1739358767-r7wpnz3n0DNrmSobh8Ewwmdx3nvMmXyQ-0-e973c0656aa2f7b3c6330bc3531f4337)
错误返回结果:
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P55_65023.jpg?sign=1739358767-OtnpObeopmwkDZppP1bbz18C6vSrLHlK-0-cbe4f523b0185259cc50d6253c598619)
编写一个获取AccessToken的程序来调用接口,为了方便读者看懂,笔者会把函数代码以及调用方法逐个贴出来,一定要仔细跟着输入代码并理解其意思,还可以根据注释来加深某个语句、某个函数的意义。注意,一定要先看完本章再开始写代码,因为部分章节是有联系的。
getAccessToken()代码如下。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P55_65024.jpg?sign=1739358767-ydJeTTETSljE0ypZ6y7qJ1vbyavmyx2D-0-d3c6683adaaf5722ec9259dd621569de)
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P56_65025.jpg?sign=1739358767-tkHUCPDpMg8ZTTK99XWYD6neXcRXz1tG-0-7c062185d7e858f3220678c014b442a2)
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P57_65026.jpg?sign=1739358767-MBMMsdTrKRb2OOTnUTRforqRk1RlMFKh-0-00de903ca9d9c7aeb3a089b04b684752)
代码有很详细的注释,大家要仔细阅读函数开始部分的带@parma、@author字样的文字,这是注释文档,可写可不写,但是笔者建议大家都写,并养成习惯。因为很多大项目被分成很多模块,每个模块在管理的时候必须要有非常详细的注释,方便交接、管理、后期维护。
HttpRequest()代码如下。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P57_65027.jpg?sign=1739358767-NYYjkVm6YfxMO5ABv5Jvnsxzm8XdqOsA-0-8cce6b32e0c8e9afabc15a1be2bb78b6)
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P58_65028.jpg?sign=1739358767-7Q3aaC6vQ4kxTeLsFgnRvlKiEq8oNukV-0-a82a2571565b0def428b7d9bc471b43f)
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P59_65029.jpg?sign=1739358767-bCY6SjJtDRSQEsOSruXGOZ95SdGcLnam-0-8a47d2f44cc487c38749c297b146bf5a)
AccessToken类代码如下。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P59_65030.jpg?sign=1739358767-dyrF3frYeNd75q0WoBACFRDAZSDbthSC-0-6856381ec069a1b6b62ad7636edfb7d9)
下面示范getAccessToken函数的调用。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P59_65031.jpg?sign=1739358767-9ZmEJ6UZpCIGJoGGozzwUk5fClf65EUt-0-4324cbdf05d611beac106efcd8e434fc)
范例获取到的结果值为7200,单位为秒。
获取到的AccessToken:ud5kEI0N52juvNsxJJZL1HCV3gxanUHeD72Z5aCBnYcfJUrR-wpmFMHQgX2jLl9OzGqq2Bx1APlo5UsOol5G6g。
有效时间:7200秒。
读者要注重理解,前期可以跟着敲代码,后面要慢慢建立起自己的代码体系、代码风格。
3.1.3 主动调用的频率限制
当获取到AccessToken时,应用就可以成功地调用企业号后台所提供的各种接口,以管理、访问企业号后台的资源或给企业号成员发消息。
为了防止因企业应用的程序错误而引发企业号服务器负载异常,默认情况下,每个企业号调用接口都有一定的频率限制,当超过此限制时,调用对应接口会收到相应错误码。
以下是当前默认的频率限制,企业号后台可能会根据运营情况调整此阈值。
- 基础频率
每个企业调用单个cgi/api不可超过1 000次/分,30 000次/小时。
每个IP调用单个cgi/api不可超过2 000次/分,60 000次/小时。
第三方应用提供商由于需要同时服务于多个企业,IP频率限制为:每个IP调用单个cgi/api不可超过20 000次/分,600 000次/小时。
- 发消息频率
每个企业不可超过账号上限数×30人次/天。
- 创建账号频率
每个企业创建账号数不可超过账号上限数×3/月。
- 创建应用频率
每个企业最大应用数限制为30个,创建应用次数不可超过30×3/月。
关于访问次数和AccessToken的时效性,可以合理安排访问的次数,AccessToken失效之后,程序没有再次去获取AccessToken会导致接口访问权限失效的错误。下面针对此问题写一个程序来解决。
3.1.4 防止AccessToken过期的处理
首先介绍具体思想,因为AccessToken的时效性是7200s,所以我们只需要给定两个写死的获取凭证的参数,判断这两个参数是否取到,没有值就需要自行配置。再启动一个线程,传参给新起的线程,写一个死循环,执行一次获取,对获取到的对象实例进行一次判断,如果值为null,就调用线程休眠,具体休眠时间看情况并结合API计算。
因为是死循环,所以当第二次取到值的时候,又进行了判断,当然这次不可能为null,除非参数有问题,这时就不需要继续执行下去,需要休眠线程,因为值已经取到了。根据API 7200s的时效性,每天2000次调用频率,其实2000次足够我们调用了,7200/3600=2h, 24/2h=12,每天12次就可以了,更何况是2000次呢?让线程休眠7000+s,之后的时间(7200-7000)剩下200+s,在200+s里可以重新唤醒线程开始对值判断,又可以合理管理调用时间间隔,具体以自己的需求情况为准。这样就可以避免AccessToken的失效了。
接下来介绍参数配置的问题,在web.xml里需要配置如下几个参数,作为线程启动及获取凭证的映射。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P61_65032.jpg?sign=1739358767-wkaLZ6CFcYVgfQ9udbpcA7u9yHUEwP36-0-d65a1a80eddd2d6b9d64f2cd63dfcd8c)
servlet-name、servlet-class分别是类名和包名点类名,在init-param属性下配置好appid、appsecret。load-on-startup为0,就是当这个服务启动时,InitAccessTokenServlet自动启动并同时启动线程服务。
(1)通过配置<init-param>向Servlet中传入参数。
(2)通过配置<load-on-startup>使得Web服务器启动时就加载该Servlet。
(3)没有配置<servlet-mapping>,因为InitServlet并不对外提供访问。
接下来开始编写访问次数的程序,然后编写一个自定义的Servlet,继承自HttpServlet,代码如下。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P61_65033.jpg?sign=1739358767-ShlQbUw0tWaOKUlWDATOVJaFjtOHe3sj-0-6561654bf56673f6f2ef63686b27da83)
编写自定义线程,代码如下。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P62_65035.jpg?sign=1739358767-0BXfsiWSNzrk3AG7EWnitaqFzN3GGP1W-0-caf30a8216ce33aa8e703057a899d31d)
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P63_65036.jpg?sign=1739358767-pDNTa5bltcOSamdf0pRh3PyANZTb3gOL-0-00df646e35ca958c33c7415f7d6f36b0)
线程打印测试如图3-12所示。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P63_4405.jpg?sign=1739358767-D3bzghJzgmH87fK5AlgYQysBG5SZpMx7-0-4db4f86f5932603b9574ff82b43fa580)
图3-12 线程测试
服务开启之后,服务器日志打印,如图3-13所示。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P64_4417.jpg?sign=1739358767-Y5t5hyTqWmbDYWvVlqB6xPir1a8smpkB-0-1c0a86c09e39c0769daa180a9c025e5e)
图3-13 服务器日志