Symbian中对HTTP支持最重要的类是 RHTTPSession。
下面讲一下symbian中关于http接口api的使用,若有理解不正确的地方,欢迎各位朋友指正 ^_^
http执行事务处理的主要思想是:会话,事务,头部,数据提供器和过滤器。下面我就以向网络上的web服务器 发送请求和获取数据的流程过一下这些api。
// 发送请求流程
在symbian中,http协议栈和相关资源由相关的服务器(注意这里所指的服务器是symbian系统管理 手机资源的一种结构,我们暂且称之为SymbianHttpServ)来管理的。
RHTTPSession代表和SymbianHttpServ的客户端会话,所以我们首先需要使用它来连接 SymbianHttpServ,以便使用相关资源,如http协议栈等等。
RHTTPSession iSession;
//iSession.SetSessionEventCallback(MHTTPSessionEventCallback *);
iSession.OpenL();
TUriParser8 iUriParser;
User::LeaveIfError(iUriParser.Parse(
_L8("http://www.symbian.com/index.html")));
// Create the transaction
// for get
iTransaction = iSession.OpenTransactionL(iUriParser, MHTTPTransactionCallback &,
iSession.StringPool().StringF(HTTP::EGET,
iSession.StringPool().StringF(HTTP::EGET,
RHTTPSession::GetTable()));
// for post
iTransaction = iSession.OpenTransactionL(iUriParser, *this,
iSession.StringPool().StringF(HTTP::EPOST, RHTTPSession::GetTable()));
iSession.StringPool().StringF(HTTP::EPOST, RHTTPSession::GetTable()));
// Set transaction headers
RHTTPHeaders headers = iTransaction.Request().GetHeaderCollection() ;
// Add a header to a header set
//void Engine::AddHeaderL(RHTTPHeaders aHeaders, TInt aHeaderField,
// const TDesC8& aHeaderValue)
//{
// RStringPool stringPool = iSession.StringPool();
// RStringF valStr = stringPool.OpenFStringL(aHeaderValue);
//{
// RStringPool stringPool = iSession.StringPool();
// RStringF valStr = stringPool.OpenFStringL(aHeaderValue);
// 用THTTPHdrVal类描述HTTP客户请求包中的每个字段
// THTTPHdrVal headerVal(valStr);
// aHeaders.SetFieldL(stringPool.StringF(aHeaderField,
// THTTPHdrVal headerVal(valStr);
// aHeaders.SetFieldL(stringPool.StringF(aHeaderField,
// RHTTPSession::GetTable()), headerVal);
// valStr.Close();
//}
// valStr.Close();
//}
//
// User-Agent头部提供了一个字符串, 用于标识客户程序
AddHeaderL(headers, HTTP::EUserAgent, _L8("HTTPExample (1.0)"));
// Accept头部定义了在响应消息主体中接受的内容类型。
// "text
AddHeaderL(headers, HTTP::EContentType, _L8("text/plain"));
AddHeaderL(headers, HTTP::EContentType, _L8("text/plain"));
// Build form encoder for post request, Start by removing any previous content.
// The get request can ignore this step.
// post请求与get请求的主要不同之处在于post请求本身不仅包括头,还包括主体(表单)。
delete iFormEncoder; iFormEncoder = NULL;
iFormEncoder = CHTTPFormEncoder::NewL();
TBuf8<32> buf8;
buf8.Copy(_L("cheney"));
iFormEncoder->AddFieldL(_L8("NAME"), buf8);
TBuf8<32> buf8;
buf8.Copy(_L("cheney"));
iFormEncoder->AddFieldL(_L8("NAME"), buf8);
iTransaction.Request().SetBody(*iFormEncoder);
// Submit the request
iTransaction.SubmitL(); // 异步方法
iTransaction.SubmitL(); // 异步方法
// 以上过程中若想取消未完成的事务,调用iTransaction.Cancel() 方 法。
// 调用iTransaction.Close() 会 导致所有与事务关联的资源得到清除,从而决不能再试图使用它。
// 接收数据流程
当请求发出之后,http服务器会发回通知和数据,客户端相应的处理全在MHTTPTransactionCallback::MHFRunL 方法中
void MHTTPTransactionCallback::MHFRunL(RHTTPTransaction aTransaction,
const THTTPEvent& aEvent)
{
switch (aEvent.iStatus)
{
case THTTPEvent::EGotResponseHeaders :
{
// HTTP response headers have been received.
// Pass status information to observer.
RHTTPResponse resp = aTransaction.Response();
{
switch (aEvent.iStatus)
{
case THTTPEvent::EGotResponseHeaders :
{
// HTTP response headers have been received.
// Pass status information to observer.
RHTTPResponse resp = aTransaction.Response();
// Get status code
TInt statusCode = resp.StatusCode();
TInt statusCode = resp.StatusCode();
// Get status text
RStringF statusStr = resp.StatusText();
HBufC* statusBuf = HBufC::NewLC(statusStr.DesC().Length());
statusBuf->Des().Copy(statusStr.DesC());
RStringF statusStr = resp.StatusText();
HBufC* statusBuf = HBufC::NewLC(statusStr.DesC().Length());
statusBuf->Des().Copy(statusStr.DesC());
// Inform observer
iObserver.ResponseStatusL(statusCode, *statusBuf);
iObserver.ResponseStatusL(statusCode, *statusBuf);
CleanupStack::PopAndDestroy(statusBuf);
}
break;
}
break;
// 至少接受了部分主体数据。该事件会发生一次或多次,直至接受了所有主体数据为止
case THTTPEvent::EGotResponseBodyData:
{
// Get text of response body
MHTTPDataSupplier* dataSupplier =
case THTTPEvent::EGotResponseBodyData:
{
// Get text of response body
MHTTPDataSupplier* dataSupplier =
aTransaction.Response().Body();
TPtrC8 ptr;
TPtrC8 ptr;
// 从数据提供器获取主体数据。
dataSupplier->GetNextDataPart(ptr);
dataSupplier->GetNextDataPart(ptr);
// Convert to 16-bit descriptor
HBufC* buf = HBufC::NewLC(ptr.Length());
buf->Des().Copy(ptr);
HBufC* buf = HBufC::NewLC(ptr.Length());
buf->Des().Copy(ptr);
// Append to iResponseBuffer
if (!iResponseBuffer)
{
iResponseBuffer = buf->AllocL();
}
else
{
iResponseBuffer = iResponseBuffer->ReAllocL(
if (!iResponseBuffer)
{
iResponseBuffer = buf->AllocL();
}
else
{
iResponseBuffer = iResponseBuffer->ReAllocL(
iResponseBuffer->Length() + buf->Length() );
iResponseBuffer->Des().Append(*buf);
}
iResponseBuffer->Des().Append(*buf);
}
// Release buf
CleanupStack::PopAndDestroy(buf);
CleanupStack::PopAndDestroy(buf);
// Release the body data
dataSupplier->ReleaseData();
}
break;
dataSupplier->ReleaseData();
}
break;
// 所有的主体数据都已被接受
case THTTPEvent::EResponseComplete:
{
// Pass the response buffer by reference to the observer
iObserver.ResponseReceivedL(*iResponseBuffer);
}
break;
}
}
{
// Pass the response buffer by reference to the observer
iObserver.ResponseReceivedL(*iResponseBuffer);
}
break;
}
}
Called when RunL leaves from a transaction event. This works in the same way as CActve::RunError; return KErrNone if you have handled the error. If you don't completely handle the error, a panic will occur.
TInt MHTTPTransactionCallback::MHFRunError(TInt aError,
RHTTPTransaction aTransaction, const THTTPEvent &aEvent);