Symbian中的Http开发详解

1 打开一个会话

Http客户端会话由声明一个RHttpSession对象并调用它的OpenL()方法开始。

RHTTPSession iSession;

iSession.OpenL();

2 创建一个事务

要创建一个新的事务,客户端必须指定URI、HTTP请求方法和一个用于接收事务处理期间的事件的callback对象,该回调对象必须继承自MHTTPTransactionCallBack接口。RHTTPTransaction句柄由唯一地定义新事物的会话返回。

void CHttpClient::InvokeHttpMethodL(const TDesC8& aUri, RStringF aMethod)

{

...

TUriParser8 uri;

uri.Parse(aUri);

RHTTPTransaction trans = iSession.OpenTransactionL(uri, *iTransObs, aMethod);

...

};

OpenTransactionL()的第二个参数表示回调对象。

3 设置请求头

在打开了事务之后,如果有需要,客户端就要设置请求头。但是,对于简单事务来说,请求头的使用是可选的,因为HTTP/1.1的请求头会被自动生成。

可以使用RHTTPHeaders类访问与事务请求或事务响应相关的头部。该句柄是从事务相关的RHTTPRequest或RHTTPResponse对象中取得的。

RHTTPHeaders hdr = trans.Request().GetHeaderCollection();

// Add headers appropriate to all methods

SetHeaderL(hdr, HTTP::EUserAgent, KUserAgent);

SetHeaderL(hdr, HTTP::EAccept, KAccept);

...

void CHttpClient::SetHeaderL(RHTTPHeaders aHeaders, TInt aHdrField, const TDesC8& aHdrValue)

{

RStringF valStr = iSession.StringPool().OpenFStringL(aHdrValue);

THTTPHdrVal val(valStr);

aHeaders.SetFieldL(iSession.StringPool().StringF(aHdrField), val);

valStr.Close();

}

头部域类型是使用HTTP名字空间的枚举来指定,如:HTTP::EUserAgent。该类用于拥有头部域的值:THTTPHdrVal,就像一个C++联合类型,在其中它可以拥有不同的数据类型。

4 启动事务

设置了头部域后,一个不带请求体的简单事务就可以立即启动了。但这只是适用于诸如GET、HEAD和TRACE等HTTP方法的情况。而不适用于另外一些请求中包括主体的HTTP方法,如POST。客户端向其发送请求体数据的数据提供者必须在事务启动之前关联到事务上。

当事务准备启动时,客户端调用RHTTPTransaction::SubmitL()表示请求应该被提交了。

...

// submit the transaction

trans.SubmitL();

// Start the scheduler, once the transaction completes or is cancelled //on an error the scheduler will be stopped in the event handler

CActiveScheduler::Start();

5 接收事务事件

当客户端从HTTP服务器收到数据,事件也会被生成并通过会话过滤器传回到客户端。事件到达客户端时,HTTP会唤醒事务回调对象,也即MHFRunL (RHTTPTransaction aTransaction, const THTTPEvent &aEvent)方法。

在该方法中可通过以下方式利用事务响应取得响应状态码和文本描述:

case THTTPEvent::EGotResponseHeaders:

{

RHTTPResponse resp = aTransaction.Response();

TInt status = resp.StatusCode();

RStringF statusStr = resp.StatusText();

下面的代码则是使用THTTPHdrFieldIter类循环取得头部域数据:

    RHTTPResponse resp = aTrans.Response();

    RStringPool strP = aTrans.Session().StringPool();

    RHTTPHeaders hdr = resp.GetHeaderCollection();

    THTTPHdrFieldIter it = hdr.Fields();

    TBuf<KMaxHeaderNameLen> fieldName16;

    TBuf<KMaxHeaderValueLen> fieldVal16;

    while (it.AtEnd() == EFalse)

    {

    // Get the name of the next header field

    RStringTokenF fieldName = it();

    RStringF fieldNameStr = strP.StringF(fieldName);

    // Check it does indeed exist

    THTTPHdrVal fieldVal;

    if (hdr.GetField(fieldNameStr,0,fieldVal) == KErrNone)

      {

       ...

       // Display realm for WWW-Authenticate header

       RStringF wwwAuth = strP.StringF(HTTP::EWWWAuthenticate, RHTTPSession::GetTable());

       if (fieldNameStr == wwwAuth)

         {

         // check the auth scheme is 'basic'

         RStringF basic = strP.StringF(HTTP::EBasic,RHTTPSession::GetTable());

         RStringF realm = strP.StringF(HTTP::ERealm, RHTTPSession::GetTable());

         THTTPHdrVal realmVal;

         if (fieldVal.StrF() == basic)

          // check the header has a 'realm' parameter

          if (hdr.GetParam(wwwAuth, realm, realmVal) == KErrNone)

           {

           RStringF realmValStr = strP.StringF(realmVal.StrF());

           fieldVal16.Copy(realmValStr);

           Printf(_L("Realm is: %S/n"), &fieldVal16);

           }

        }

     }

     // Advance the iterator

     ++it;

 }

6 取得响应体

要取得响应体,就必须使用包含在事务响应里的数据提供者。在客户端完成处理所有的响应体数据片后,必须数据释放数据提供者。

case THTTPEvent::EGotResponseBodyData:

 {

 // Some (more) body data has been received. Get the body data supplier

 MHTTPDataSupplier* body = aTransaction.Response().Body();

 TPtrC8 dataChunk;

 TBool isLast = body->GetNextDataPart(dataChunk);

 Dump(dataChunk);

 if (isLast)

   Printf(_L("Got the last data chunk./n"));

// Done with that bit of body data

 body->ReleaseData();

 }

 break;

7 完成事务

事务的完成(不管是成功还是失败),都要停止本地活动调度器。枚举值EResponseComplete仅是事务完成的一个信号,而不用于完成任何具体的工作。具体的工作放在成功或是失败的分支里处理:

case THTTPEvent::EResponseComplete:

    {

    // The transaction's response is complete

    Printf(_L("/nTransaction Complete/n"));

    }

    break;

case THTTPEvent::ESucceeded:

    {

    Printf(_L("Transaction Successful/n"));

    aTransaction.Close();

    CActiveScheduler::Stop();

    }

    break;

case THTTPEvent::EFailed:

    {

    Printf(_L("Transaction Failed/n"));

    aTransaction.Close();

    CActiveScheduler::Stop();

    }

    break;

最后要使用RHTTPTransaction::Close()关闭事务,这个调用将释放所有关联到事务的资源。

8 终止会话

客户端准备终止时,要关闭会话:

CHttpClient::~CHttpClient()

    {

    iSession.Close();

    ...

    }

关闭会话导致所有的资源被返回给系统,所有残存的未完成事务都将被立即取消。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值