在前4讲中我们已经使iw开发的应用成功和微信进行了对接,再接下来的章节中我们开始逐一尝试和实现微信的各个API,开始前先来点准备工作
  1. 首先需要明确的是,微信的API都是通过https调用实现的,分为post方法调用和get方法调用。不需要上传数据的采用get方法(例如获取AccessToken),而需要向微信服务器提交数据的采用post方法(例如创建菜单)。
  2. 微信方法调用均需传递AccessToken(URL参数方式),这个AccessToken不是我们微信接入时使用的Token,这个AccessToken专门用于微信API调用,AccessToken有过期时间,而且每天有请求次数限制,据说是为了防止不良的程序调用导致微信服务器出现异常。因此在这种情况下则必须在获取AccessToken后进行保存,在即将过期前再重新获取。
好吧,让我们开始:首先定义post和get方法。这里我们采用Indy实现,不需要再安装什么第三方组件了,也没有大量并发的要求(咱们这是客户端程序),简单易用最重要。

/// <summary>
/// 向指定URL发起Get请求

/// </summary>

/// <param name="http">TIdHTTP</param>

/// <param name="URL">指定URL</param>

/// <param name="Max">Get请求失败最大重试次数</param>

/// <returns>返回腾讯服务器响应(string类型的json格式数据)</returns>

function GetMethod(http: TIdHTTP; URL: String; Max: Integer): String;

var
  RespData: TStringStream;
begin
  RespData := TStringStream.Create('', TEncoding.UTF8);
  try
    try
      http.Get(URL, RespData);
      http.Request.Referer := URL;
      Result := RespData.DataString;
    except
      Dec(Max);
      if Max = 0 then
      begin
        Result := '';
        exit;
      end;
      Result := GetMethod(http, URL, Max);
    end;
  finally
    FreeAndNil(RespData);
  end;
end;

/// <summary>

/// 向指定URL提交数据(Post)

/// </summary>

/// <param name="http">TIdHTTP</param>

/// <param name="URL">指定URL</param>

/// <param name="Data">要提交的数据(UTF8String)</param>

/// <param name="Max">Post请求失败最大重试次数</param>

/// <returns>返回腾讯服务器响应(string类型的json格式数据)</returns>

function PostMethod(http: TIdHTTP; URL: String; Data: UTF8String;

    Max: Integer): String;

var
  PostData, RespData: TStringStream;
begin
  RespData := TStringStream.Create('');
  PostData := TStringStream.Create(Data);
  try
    try
      if http = nil then
        exit;
      http.Post(URL, PostData, RespData);
      Result := RespData.DataString;
      http.Request.Referer := URL;
    except
      Dec(Max);
      if Max = 0 then
      begin
        Result := '';
        exit;
      end;
      Result := PostMethod(http, URL, Data, Max);
    end;
  finally
    http.Disconnect;
    FreeAndNil(RespData);
    FreeAndNil(PostData);
  end;
end;

有了上面两个方法我们就可以开始测试微信API了。

♥ 不过你有没有注意到,微信请求是https,不是http啊,所以似乎还需要让Indy支持ssl传输才行啊,这当然没有问题,上Indy官网下载SSL支持DLL即可,分为64位和32位版本不要搞错,下载后和编译好的IW程序放置在同一目录下即可(说实在的下载网站我给忘了,大家可以百度一下,如果找不到给我留言,我把我下载的发出来)。

接下来研究下如何获取这个AccessToken

由于AccessToken在API调用中都需要使用,因此先来获取AccessToken吧,关于AccessToken的解释请看微信文档:http://mp.weixin.qq.com/wiki/14/9f9c82c1af308e3b14ba9b973f99a8ba.html

使用的微信命令URL是:https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET

采用Get方法。

如你所见:

1、URL调用需传递【APPID】和【APPSECRET】两个参数,返回结果为Json格式字符串。

2、调用成功的情况下,微信会返回下述JSON数据包给公众号:

{"access_token":"ACCESS_TOKEN","expires_in":7200}
参数 说明
access_token 获取到的凭证
expires_in 凭证有效时间,单位:秒

3、错误时微信会返回错误码等信息,JSON数据包示例如下(该示例为AppID无效错误):

{"errcode":40013,"errmsg":"invalid appid"}

♥ 好吧,好像还得找个Json解析的组件,嗯嗯,够麻烦的,推荐使用第三方组件“SuperObject”进行Json格式解析,不过你要非得自行进行Json字符串编解码也行,嗯,可能会累点,相信我,最好找个封装完善的Json组件,工欲善其事必先利其器,否则创建菜单什么的时候有你受的。

嗯,Json结果解析判断什么的我就不说了,再说说AccessToken的缓存问题。

简单说:“为了保密appsecrect,第三方需要一个access_token获取和刷新的中控服务器。而其他业务逻辑服务器所使用的access_token均来自于该中控服务器,不应该各自去刷新,否则会造成access_token覆盖而影响业务;”这个是微信文档原话,所以让我们看看怎么缓存这个东东。

先声明一个TAccessToken记录,然后利用一个全局公开的变量,再加上一个泛型容器,如此的简单:

/// <summary>
/// AccessToken记录,包含AccessToken值和过期时间

/// </summary>

TAccessToken = record

  AccessToken: string;

  AccessTokenExpiresDt: TDateTime;

end;

var 
  gAccessTokenLst: TDictionary<string, TAccessToken>; 
  gCS: TCriticalSection;

♥  声明成记录类型的好处是,可以当做简单变量来使用,要是声明成指针或者类,哦哦,创建再释放,太麻烦了。微信返回的json结果中是这个AccessToken还有多少秒过期,我们换算成时间类型会比较好用一些。

♥ 泛型我喜欢,让Hash表成为强类型的。

♥  如上gAccessTokenLst用来存储获取的AccessToken,key就是微信号的APPID,估计这个不会重复吧!上面还声明了一个临界区对象gCS,大约我不说你也能猜到,既然是全局的那就得上锁,防止写入混乱。

♥  上面那两个变量gAccessTokenLst和gCS我是在单元的initialization部分实例化的,并在finalization进行了释放,在这两个地方处理全局变量的好处是:运行时只执行一次。是初始化全局变量的绝佳地点。

万事具备了,最终获取AccessToken的函数代码如下:

procedure TWxSdkImp.GetAccessToken(const appid, appsecret: string;
  var AccessToken: string; const GetNew: Boolean = false);

var

  URL: string;

  JSONObject: ISuperObject;

  temp, sKey: string;

  recAccessToken: TAccessToken;

begin

  if (appid = '') or (appsecret = '') then

    raise Exception.Create('TWxSdkImp.GetAccessToken执行出错,参数应用ID或者应用秘钥不能为空!');

recAccessToken.AccessToken := '';

  sKey := appid;

  if gAccessTokenLst.ContainsKey(sKey) then

    recAccessToken := gAccessTokenLst.Items[sKey];

// 如果要求重新获取AccessToken 或者 尚未获取AccessToken 或者 已经获取了但是离过期不足30秒

  gCS.Enter;

  try

    if GetNew or (recAccessToken.AccessToken = '') or (SecondSpan(recAccessToken.AccessTokenExpiresDt, Now) < 30) then

    begin

      URL := Format(WxCmdUrl_GetAccessToken, [appid, appsecret]);

      temp := GetMethod(http, URL, 3);

      JSONObject := ParseJson(temp, ['"access_token"', '"errcode"']);

      if Pos('"access_token"', temp) > 0 then

      begin

        recAccessToken.AccessToken := JSONObject['access_token'].AsString;

        recAccessToken.AccessTokenExpiresDt := IncSecond(Now, JSONObject['expires_in'].AsInteger);

if gAccessTokenLst.ContainsKey(sKey) then

          gAccessTokenLst.Remove(sKey);

        gAccessTokenLst.Add(sKey, recAccessToken);

      end else

        raise Exception.Create('TWxSdkImp.GetAccessToken执行出错,服务器返回错误代码:' + JSONObject['errcode'].AsString + ',错误信息:' + JSONObject['errmsg'].AsString + '!');

    end;

  finally

    gCS.Leave;

  end;

  AccessToken := recAccessToken.AccessToken;

end;

需要获取AccessToken时,

var accessToken: string;

GetAccessToken('YourAppID', 'YourAppSecret', accessToken);

输出的accessToken字符串就是我们想要的结果。

♥  呵呵,如果想要用Delphi+iw进行微信开发的,看到这里应该算是有方向了吧,加油!希望早日看到各位的大作。

使用delphi+intraweb进行微信开发5—准备实现微信API,先从获取AccessToken开始的更多相关文章

  1. 微信开发(2):微信js sdk分享朋友圈,朋友,获取config接口注入权限验证(转)

    进行微信开发已经一阵子了,从最初的什么也不懂,到微信授权登录,分享,更改底部菜单,素材管理,等. 今天记录一下微信jssdk 的分享给朋友的功能,获取config接口注入. 官方文档走一下简单说:四步 ...

  2. 夺命雷公狗---微信开发53----网页授权(oauth2.0)获取用户基本信息接口(3)实现世界留言版

    前面两节课我们讲的是base型的授权了,那么现在我们开始Userinfo型授权, 先来看下我们的原理图 我们这节课来做一个 世界留言版 系统 1..首先我还是在微信测试平台那里设置好回调页面的域名 2 ...

  3. 夺命雷公狗---微信开发51----网页授权(oauth2.0)获取用户基本信息接口(1)

    如果用户在微信客户端访问第三方网页,公众号可以通过微信网页授权机制,来获取用户基本信息,从而实现业务逻辑. 一般我们用来“数据采集”,“市场调查”,“投票”,只要授权了第三方网页,微信用户无需注册就可 ...

  4. 【微信开发】PC端 微信扫码支付成功之后自动跳转

    场景: PC端   微信扫码支付 结果: 支付成功 自动跳转 实现思路: 支付二维码页面,写ajax请求支付状态,请求到结果,无论成功还是失败,都跳转到相应的结果页面 具体实现方法: html部分: ...

  5. 夺命雷公狗---微信开发52----网页授权(oauth2.0)获取用户基本信息接口(2)

    我们在上一节课已经发送code给第三方了,那么这就要获取code去换取到用户的openid. 第一步:编写create_baseurl.php(上一节课程已经写完了) 第二步:编写vote1.php( ...

  6. Java企业微信开发_15_查询企业微信域名对应的所有ip

    一.前言 二.方法 1.在线网站 百度搜索"域名查IP",可查到如下网站,输入域名即可查到所有IP: 站长工具 site.ip138.com tools.ipip.net 2.li ...

  7. 使用delphi+intraweb进行微信开发3—微信消息处理

    示例代码已经放出!请移步使用delphi+intraweb进行微信开发1~4代码示例进行下载,虽为示例代码但是是从我项目中移出来的,封装很完备适于自行扩展和修改. 在第二讲使用delphi+intra ...

  8. 【微信开发】公众号后台设置错误导致的微信redirect_uri参数错误【图】

    在微信开发中,如微信网页授权登录,分享到朋友圈自定义内容,微信h5支付时 可能会遇到微信redirect_uri参数错误的情况. 此时除了检查自己代码正确性外,还要检查一下是否正确地设置了公众号后台的 ...

  9. c#微信开发,使用JS-SDK自定义分享功能,分享朋友圈,分享给朋友等

    如果一个后端开发掌握了微信开发,甚至有微信开发上线项目,这在换工作的时候 还是有竞争力的. 微信开发的资料很多,但是用asp.net c#进行微信开发好像比较少,或者资料不够完整. 使用JS-SDK自 ...

随机推荐

  1. A session of Log Collect, Retrieval and Analysis using ELK Stack

    Motivation 运维过程中对问题的定位往往需要跟踪和定位日志.分布式和弹性计算的引入,使得日志的定位和分析变得越发复杂. 本次实践主要的目的是考察现有成熟的日志收集.检索和分析方案:Kafka+ ...

  2. jenkins 使用oclint 扫描 oc 代码

    jenkins 环境的搭建,在这里不在赘述,下面我们写一写,如何接入oclint. OCLint是一个强大的静态代码分析工具,可以用来提高代码质量,查找潜在的bug,主要针对c,c++和Objecti ...

  3. mysql 用法记录和常见错误,持续更新。

    2016-10-20 08:31:46 在navicat创建表的时候,遇到"#1166 - Incorrect column name'Id'"问题,原因是创建的字段中有空格(是直 ...

  4. Java笔记9-正则表达式

    提纲: 1.正则表达式 2.常见的异常 3.内部类------------------------------------------------------------------JDK 1.4以后 ...

  5. pthread_create 内存释放

    run() { pthread_attr_destroy(&m_attr);    pthread_detach(pthread_self()); }

  6. cloudera manager安装spark后使用spark shell编写基于scala的world count

    val file = sc.textFile("hdfs://zhcloudil-lcnode04:8020/user/cloudil/wc_spark.txt") val cou ...

  7. install google chrome

    32bit: wget https://dl.google.com/linux/direct/google-chrome-stable_current_i386.deb sudo dpkg -i go ...

  8. Java单例模式(转载)

    原文地址:1:http://www.cnblogs.com/hupp/p/4487521; 2:http://cantellow.javaeye.com/blog/838473 先罗列五种单例模式的实 ...

  9. TimeQuest 静态时序分析 基本概论

    静态时序分析 基本概念  [转载] 1.   背景 静态时序分析的前提就是设计者先提出要求,然后时序分析工具才会根据特定的时序模型进行分析,给出正确是时序报告. 进行静态时序分析,主要目的就是为了提高 ...

  10. 自动化测试工具QTP的使用实例 分类: 软件测试 2015-06-17 00:23 185人阅读 评论(0) 收藏

    1. QTP简介 1.1QTP功能与特点 QTP是QuickTest Professional的简称,是一种自动化软件测试工具.在软件的测试过程中,QTP主要来用来通过已有的测试脚本执行重复的手动测试 ...