在访问web网页时,移动网关会返回这样的
<?xml version="1.0"?>
<!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml">
<wml><card><p><do type="prev" name="Back" label="Back"><prev/></do>
Your request for a service could not be fulfilled. Please try again or contact your operator if the problem persists.
</p></card></wml>
信息.经我测试发现,是由于下列原因引起的
在CMWAP 下发送中文请求,这个问题看似简单的问题,让我麻烦了很长时间.
我们直接进入主题:
对于普通的HTTP用CMWAP代理 设置代码 如下:
//连接Socket服务器
User::LeaveIfError(iSocketServ.Connect());
打开连接服务器
User::LeaveIfError(iConnection.Open(iSocketServ));
打开HTTP Session
TRAPD( err, iSession.OpenL() );
//设置接入点 使当前连接不弹出接入点对话框设置
iPref.SetDialogPreference(ECommDbDialogPrefDoNotPrompt);
CMyHttpEngineAppUi* pAppUi = GetCurAppUi();
#ifdef __WINS__
iPref.SetIapId(pAppUi->iCur_IAP_ID);
#else
iPref.SetIapId(pAppUi->iCur_IAP_ID);
#endif
iPref.SetDirection(ECommDbConnectionDirectionOutgoing);
iConnection.Start(iPref);//此处会产生 7 s左右的时间延时 建议用异步方法 来解决这个问题
//出错处理
if( err != KErrNone ){
// Most common error; no access point configured, and session creation
// leaves with KErrNotFound.
// Load a string from the resource file and add the error code to string
HBufC* textResource = StringLoader::LoadLC( R_IAP_CONF_ERR, err );
CAknErrorNote* errorNote;
errorNote = new (ELeave) CAknErrorNote;
// Show the error Note with textResource loaded with StringLoader.
errorNote->ExecuteLD( *textResource);
// Pop HBuf from CleanUpStack and Destroy it.
CleanupStack::PopAndDestroy( textResource );
User::Leave( err );
}
// 把当前的SOCKET服务器与HTTP Session做绑定
iSession.ConnectionInfo().SetPropertyL(iSession.StringPool().StringF(HTTP::EHttpSocketServ, RHTTPSession::GetTable()), THTTPHdrVal(iSocketServ.Handle()));// Attach to connection
// 把当前的连接与HTTP Session做绑定
TInt connPtr = REINTERPRET_CAST(TInt, &iConnection);
iSession.ConnectionInfo().SetPropertyL(iSession.StringPool().StringF(HTTP::EHttpSocketConnection, RHTTPSession::GetTable()), THTTPHdrVal(connPtr));
#ifndef __WINS__//设置CMWAP WAP代理
_LIT8(KProxy, "10.0.0.172:80");
if(pAppUi && pAppUi->iCur_IAP_ID == pAppUi->iCMWAP_IAP_ID)
{
RStringF proxyAddr = iSession.StringPool().OpenFStringL(KProxy());
CleanupClosePushL(proxyAddr);
THTTPHdrVal proxyUsage(iSession.StringPool().StringF(HTTP::EUseProxy, RHTTPSession::GetTable()));
iSession.ConnectionInfo().SetPropertyL(iSession.StringPool().StringF(HTTP::EProxyUsage, RHTTPSession::GetTable()), proxyUsage);
iSession.ConnectionInfo().SetPropertyL(iSession.StringPool().StringF(HTTP::EProxyAddress, RHTTPSession::GetTable()), proxyAddr);
CleanupStack::PopAndDestroy(); // proxyAddr
}
#endif
这样, 完成了CMWAP 的代理设置.
这里对于关闭这个HTTP Session对象来说就要这样关闭.
iSession.Close();
iConnection.Close();
iSocketServ.Close();
对于Get请求方法,我们加入一些表头信息,就能完成我们的操作了
void CWebClientEngine::SetHeaderL( RHTTPHeaders aHeaders,
TInt aHdrField,
const TDesC8& aHdrValue )
{
RStringF valStr = iSession.StringPool().OpenFStringL( aHdrValue );
CleanupClosePushL( valStr );
THTTPHdrVal val( valStr );
aHeaders.SetFieldL( iSession.StringPool().StringF( aHdrField,
RHTTPSession::GetTable() ), val );
CleanupStack::PopAndDestroy( &valStr );
}
void CWebClientEngine::IssueHTTPGetL( const TDesC8& aUri )
{
// Parse string to URI (as defined in RFC2396)
if(iRunning)
{
iRequestList->AppendL(aUri);
return ;
}
TUriParser8 uri;
uri.Parse( aUri );// Get request method string for HTTP GET
RStringF method = iSession.StringPool().StringF( HTTP::EGET,
RHTTPSession::GetTable());// Open transaction with previous method and parsed uri. This class will
// receive transaction events in MHFRunL and MHFRunError.
iTransaction = iSession.OpenTransactionL( uri, *this, method );// Set headers for request; user agent and accepted content type
RHTTPHeaders hdr = iTransaction.Request().GetHeaderCollection();
_LIT8(KUserAgent, "Nokia");
_LIT8(KAccept, "*/*");
_LIT8(KAcceptCharset, "utf-8");SetHeaderL( hdr, HTTP::EUserAgent, KUserAgent );
SetHeaderL( hdr, HTTP::EAccept, KAccept);
SetHeaderL(hdr, HTTP::EAcceptCharset, KAcceptCharset);// Submit the transaction. After this the framework will give transaction
// events via MHFRunL and MHFRunError.
iTransaction.SubmitL();iRunning = ETrue;
// Load a string from the resource file
HBufC* textResource = StringLoader::LoadLC( R_CONNECTING );
if(iObserver)
iObserver->ClientEvent(EHttpStatusNone, *textResource );
CleanupStack::PopAndDestroy( textResource );
iPtr.Zero();
}
这样就完成了GET方法设置.这些网上资料已经很多了.这里只是保证,此方法是我测试通过的代码.
关键部分来了,在传给CWebClientEngine的对象的方法IssueHTTPGetL( const TDesC8& aUri )的形参时,我们不能用一般方法操作了.
这样要提到UrlEncoded编码问题. 对于一般的CMWAP 网关是不会关心GET 请求是否合非的问题.但在广州移动的WAP网关对这个会对这个进行判定.对于中文会过滤或者产生乱码.
我这个测试结果如下:
对于有这样的一个URL: www.baidu.com/s?wd=广州天气,我们中文用UTF8的编码方式:
代码:
CnvUtfConverter::ConvertFromUnicodeToUtf8(iUri, szBufUrl);
HBufC8* pBuf = iUri.Alloc();
iUri.Format(KNEWWAP, pBuf);
iHttpEngine->SetCurGetHeader(aCommand);delet pBuf;
测试下来的结果如图1
这时发现在请求中会出现????这样的符示 这是由于中文的问题.这样就有可能产生问题
解决方法
CnvUtfConverter::ConvertFromUnicodeToUtf8(iUri, szBufUrl);
HBufC8* pBuf = EScapeUtils::EscapeEncodeL(iUrl , EscapeUtils::EEscapeUrlEncoded);//此这关键 把中文转换成一个合法的字符
iUri.Format(KNEWWAP, pBuf);
iHttpEngine->SetCurGetHeader(aCommand);delet pBuf;
测试结果如图2:
完成我们的要求了.
结果很午简单,但花了我不少时间,假如有人遇到过这样的问题,能看到这篇文章,我心足已.