![微信公众平台企业号开发揭秘](https://wfqqreader-1252317822.image.myqcloud.com/cover/489/26793489/b_26793489.jpg)
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=1739595444-TRNfHSuBXQnYqWZcHdw8WAhP53SJL5DR-0-0398d9bb56d685913715b78f9a8619e4)
图3-1 单击“我的企业”
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P53_1756.jpg?sign=1739595444-CJw6TuOPs9GTVwFyl996yqLJ3hAKnXP7-0-eba16e1ee7de1ada1544d03c5fba2d84)
图3-2 获取CorpID
获取CorpID后,接下来获取Secret。
登录企业号,进入管理后台,单击“企业应用”选项,进入“企业应用”页面,单击其中的一个应用,如果没有应用,可以新建一个,如图3-3所示。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P53_1789.jpg?sign=1739595444-N9UKmoslllAW5bXFUHvyorreOUwln1Lg-0-3d33b22371b9a6ad0962a3945a92b3b3)
图3-3 创建新的应用
单击“创建应用”选项后,弹出如图3-4所示的界面。
填写新应用信息,单击“创建应用”按钮,如图3-5所示。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P53_1773.jpg?sign=1739595444-3wb8XRkJ0CwT86thrM5KrnedY71wQH0x-0-316993595a03c774dd93070f6cc94a31)
图3-4 填写新应用信息
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P53_1774.jpg?sign=1739595444-5NClh2vMqQ7QAoeQL5EvBRFuIidiDOdn-0-06a7e769a833787f4272a6fb5f0668a1)
图3-5 创建新的应用
稍后单击“企业应用”选项,进入“企业应用”页面,生成新应用“Android趣味堂”,如图3-6所示。
单击该应用,可以查看该应用的详情,方框内的就是Secret参数,如图3-7所示。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P54_1801.jpg?sign=1739595444-x3E04tooGS6orziFhApTL311p5axHvCU-0-760a532f79bd08942ba28efd1a9867a8)
图3-6 新应用创建完成
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P54_1802.jpg?sign=1739595444-FqFr98b0mPaWDGxLrkFqEiD5jKp5IxeE-0-9cf93bb03179e2c985ceb8a56618eef8)
图3-7 获取Secret参数
在应用详情页还可以查看该应用的可见范围,就是对某些成员可见对某些成员不可见,由开发者设置。“Android趣味堂”应用的可见范围如图3-8所示。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P54_1847.jpg?sign=1739595444-U9i5Cy7APEHcTdlxZ3L4hPphto4aj79l-0-397777a46d5829a3320b0fb5b6a3aa46)
图3-8 应用可见范围
在应用详情页还可以设置该应用的一些功能,如发送消息、网页授权及JS-SDK、设置应用主页、接收消息、自动回复、自定义菜单、企业微信授权登录,如图3-9所示。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P54_1818.jpg?sign=1739595444-28JwTadmq856PVD8sd4Yv9rXx1K1fS2k-0-c12533df5da57ffbce420d29457cd030)
图3-9 应用功能设置
在应用详情页底部有“删除应用”选项。单击后可删除该应用,如图3-10所示。
在应用详情页右侧有一个停用、启用的Switch按钮,如图3-11所示,单击该按钮可以选择是否启用应用。若停用,则会弹出一个确认停用的窗口,提示“应用停用后,该应用在客户端中的消息将被删除”,单击窗口中的“停用”按钮可停用该应用。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P54_1830.jpg?sign=1739595444-rnZJr5c5geYbS35xCPrcTV1kUeG1HQoj-0-ba36fc871dbc74698b0ae20cc7a374a6)
图3-10 删除应用
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P54_1831.jpg?sign=1739595444-6bXUHg1wlf8sVuvGnQZ1OgJ6w63axZ7w-0-4dcee413be35627cfdc4c3ff865a7f1b)
图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=1739595444-J7pLdSVkVKrd7JPnKzDYfYUwuN0psadB-0-c914a1821d70b90cda7ee44d216cb9c6)
正确返回结果:
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P55_65020.jpg?sign=1739595444-VcTPZnWJX5zwBRheT4RkAzfWvgOQcxxd-0-ea2a3c5f4fcd5c64bb217ff539d5d8ef)
参数说明见表3-2。
表3-2 参数说明
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-T55_65021.jpg?sign=1739595444-7rJzHUZ6RzQB0if11AIzbXspJXsunblM-0-4c6dbff740b96aead0213b756a8e79d4)
错误返回结果:
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P55_65023.jpg?sign=1739595444-Ch24iCK4mNVnGqbZ9RaqONW4cuLn02Ir-0-0a5805f82862d7d7b7883f163195b124)
编写一个获取AccessToken的程序来调用接口,为了方便读者看懂,笔者会把函数代码以及调用方法逐个贴出来,一定要仔细跟着输入代码并理解其意思,还可以根据注释来加深某个语句、某个函数的意义。注意,一定要先看完本章再开始写代码,因为部分章节是有联系的。
getAccessToken()代码如下。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P55_65024.jpg?sign=1739595444-qwuWhY9edz70lqpNZVPvEA8FgX2SOtTP-0-d5a568217c5daaf9cf70ad32f7ab5d32)
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P56_65025.jpg?sign=1739595444-4CYI3xcIKmuxkA3p0wVAnRWJSgAjyhtE-0-3e41c240de9709dc44b42b2172234634)
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P57_65026.jpg?sign=1739595444-6gRqR0V1qvaPLcbpLJYwCHDGGbocR9lL-0-099faf24050fd138fd65583fe1471ad7)
代码有很详细的注释,大家要仔细阅读函数开始部分的带@parma、@author字样的文字,这是注释文档,可写可不写,但是笔者建议大家都写,并养成习惯。因为很多大项目被分成很多模块,每个模块在管理的时候必须要有非常详细的注释,方便交接、管理、后期维护。
HttpRequest()代码如下。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P57_65027.jpg?sign=1739595444-1A4jLWLuxpjWb7tPPohPjdZXANtGeyTp-0-39f9c511cd0ba507abe1f7f808e83ba0)
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P58_65028.jpg?sign=1739595444-6kDttWsrQSZitrlyRy2VeCUoQWx1DUhU-0-6b86b1632fc18e5bb95ddc8e58aa0372)
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P59_65029.jpg?sign=1739595444-DiIhwkgz3lzKreMAqATni2HRGcEvi9XW-0-3967d60616c92de4aa77eed12d759eab)
AccessToken类代码如下。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P59_65030.jpg?sign=1739595444-nIOxIdJ8OcG8Bd7r5Zj7Cc4Ma8sCTL5T-0-9628eed0420c0e1b9a71788c16c09332)
下面示范getAccessToken函数的调用。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P59_65031.jpg?sign=1739595444-H2XEHtkrSl1IAQunbFq5jjdlpa3NIahQ-0-2cd582974ad016706d0189e4d832cf01)
范例获取到的结果值为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=1739595444-3fMJggZgccCtyVe1Pnwmz3KzABqqnXEJ-0-9eb14fad75164f401615e58f3c2be493)
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=1739595444-mMLHHZqJ6BBO03qDbKGjlsu4NDSFtdeF-0-b80e2dea4b1e99797fe1439d52e0c2db)
编写自定义线程,代码如下。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P62_65035.jpg?sign=1739595444-FBssYid5cAGhcDZVRnfjWutVhqK8kyYn-0-ea08b2faac0aad7d15848f56c64307b8)
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P63_65036.jpg?sign=1739595444-6CyU3RYe1fbpz0zoX6AjzvB1vpEOFNEB-0-2e7f15c2e697891b1c93a46505b4e759)
线程打印测试如图3-12所示。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P63_4405.jpg?sign=1739595444-7EtNdw2rYJLIspKEIsJW14a1A3n1QRZZ-0-454a3bf4b50d10e4ce1d015f56a54f07)
图3-12 线程测试
服务开启之后,服务器日志打印,如图3-13所示。
![](https://epubservercos.yuewen.com/0DAA23/15253384304103006/epubprivate/OEBPS/Images/Figure-P64_4417.jpg?sign=1739595444-MaZ9ZN3utUSmD4d5aPpJVnDwrX5r0MQ2-0-c0cb96fccbd6c817e3c3576a30b469cd)
图3-13 服务器日志