Symbian学习笔记8 之 初探WebServices API的使用(中)

 继续刚才的,现在来看具体代码,先是ConnectL的实现:

view plaincopy to clipboardprint?

void CWebEngine::ConnectL()   

   {   

CSenXmlServiceDescription* pattern = CSenXmlServiceDescription::NewLC();      

pattern->SetFrameworkIdL(KDefaultBasicWebServicesFrameworkID);   

pattern->SetEndPointL(KWSEndPoint);   

delete iConnection;   

iConnection = NULL;   

iConnection = CSenServiceConnection::NewL(*this, *pattern);   

CleanupStack::PopAndDestroy(pattern);   
   }  

void CWebEngine::ConnectL()

        {

                CSenXmlServiceDescription* pattern = CSenXmlServiceDescription::NewLC();       

                pattern->SetFrameworkIdL(KDefaultBasicWebServicesFrameworkID);

                pattern->SetEndPointL(KWSEndPoint);

                delete iConnection;

                iConnection = NULL;

                iConnection = CSenServiceConnection::NewL(*this, *pattern);

                CleanupStack::PopAndDestroy(pattern);

        }

这里注意一点与那个AddressBook例子不同的是我们声明了不同框架类型是 KDefaultBasicWebServicesFrameworkID,并且这样只需要提供EndPoint而不需要Contract了。 KWSEndPoint的值是在CPP前声明了:_LIT8(KWSEndPoint,"http://192.168.0.201/uim /PService.asmx");

CSenServiceConnection::NewL的两个参数,一是自己(即MSenServiceConsumer)负责处理回调,二是一个CSenXmlServiceDescription负责参数配置。

在回调SetStatus中我只是简单地打印出状态值。

再看那个SayHello的实现吧,在这个函数中要负责封装SOAP消息包,这时我才遇到了使用Symbian的WebServiceAPI烦人的问题:原来这个SOAP包要自己封装啊!同样SOAP的结果也要自己去解析!!
view plaincopy to clipboardprint?

void CWebEngine::SayHello()     
  {   

   if(iConnectionState==1){   

   //send   

CSenSoapEnvelope  *env = CSenSoapEnvelope::NewL();   

CleanupStack::PushL(env);   

  env->SetSoapActionL(KWSContract);      

  env->BodyL().AddElementL(KWSNamespace,KWSHelloworld);   

iConnection->SendL(*env);   

CleanupStack::PopAndDestroy(env);   
   }   

}  

void CWebEngine::SayHello()

        {

                if(iConnectionState==1){

                        //send

                        CSenSoapEnvelope  *env = CSenSoapEnvelope::NewL();

                        CleanupStack::PushL(env);

                       

                        env->SetSoapActionL(KWSContract);       

                        env->BodyL().AddElementL(KWSNamespace,KWSHelloworld);

                        iConnection->SendL(*env);

                       

                        CleanupStack::PopAndDestroy(env);

                }

        }

好在HelloWorld不需要参数,所以这个SOAP请求还算简单,注意这个SetSoapActionL函数它的KWSContract就是那个"urn:pservice:helloworld" (见上篇中的SOAP请求描述)。因为CSenSoapEnvelope同样派生于CSenBaseFragment ,所以它的Body也可以增加下级节点,上面的代码很好理解。

一旦调用了iConnection->SendL以后,手机会弹出选择接入点,说明这里开始连接网络了,得到结果后,我们回调HandleMessageL中处理结果。
view plaincopy to clipboardprint?

void CWebEngine::HandleMessageL(const TDesC8& aMessage)   

{   

RDebug::Printf("===================HandleMessageL");   

LOG_ALL(aMessage);   

SetReader(*iXmlReader);   

  ParseL(aMessage);   

  }  

void CWebEngine::HandleMessageL(const TDesC8& aMessage)

        {

                RDebug::Printf("===================HandleMessageL");

                LOG_ALL(aMessage);

                SetReader(*iXmlReader);

                ParseL(aMessage);

        }

这里我们将得到的结果(完整的SOAP响应的XML内容)交给iXmlReader去解析,于是此时又会涉及到另两个回调StartElement和EndElement。注意这里补充一下iXmlReader的初始化在WebEngine的ConstructL中完成:
view plaincopy to clipboardprint?

void CWebEngine::ConstructL()   

{   

  LOG_OPEN();   

   CSenBaseFragment::BaseConstructL(KQueryResponseLocalName);   

    iXmlReader = CSenXmlReader::NewL();   

    }  

void CWebEngine::ConstructL()

        {

                LOG_OPEN();

                CSenBaseFragment::BaseConstructL(KQueryResponseLocalName);

                iXmlReader = CSenXmlReader::NewL();

        }

两句话:一是因为自己是派生于CSenBaseFragment,所以先调用BaseConstructL构造一下自己是一个HelloWorldResponse标签的XML节点。二是构造出iXmlReader实例。

下面继续说解析XML的回调处理:
view plaincopy to clipboardprint?

void CWebEngine::StartElementL(const TDesC8& aNsUri,    const TDesC8& aLocalName,   const TDesC8& aQName, const Xml::RAttributeArray& aAttrs)     

{     

RDebug::Printf("================StartElement");      

_LIT(KFmt,"StartElement (%s)");     

LOG_FORMAT((KFmt,aLocalName));   

if(aLocalName==KQueryResponseLocalName){   

delegate = CHelloWorldResult::NewL(aNsUri,aLocalName,aQName);     

CleanupStack::PushL(delegate);     

DelegateParsingL(*delegate);   

CleanupStack::Pop(delegate);     

}     

}     

void CWebEngine::EndElementL(const TDesC8& aNsUri,  const TDesC8& aLocalName, const TDesC8& aQName)     

{     

RDebug::Printf("==================EndElement");   

_LIT(KFmt,"EndElement (%s)");     

LOG_FORMAT((KFmt,aLocalName));   

CSenBaseFragment::EndElementL(aNsUri, aLocalName, aQName);     

}  

void CWebEngine::StartElementL(const TDesC8& aNsUri,    const TDesC8& aLocalName,   const TDesC8& aQName, const Xml::RAttributeArray& aAttrs)

{

RDebug::Printf("================StartElement");         

_LIT(KFmt,"StartElement (%s)");

LOG_FORMAT((KFmt,aLocalName));                        

if(aLocalName==KQueryResponseLocalName){                                

delegate = CHelloWorldResult::NewL(aNsUri,aLocalName,aQName);

CleanupStack::PushL(delegate);

DelegateParsingL(*delegate);

CleanupStack::Pop(delegate);

}

}

void CWebEngine::EndElementL(const TDesC8& aNsUri,  const TDesC8& aLocalName, const TDesC8& aQName)

{

RDebug::Printf("==================EndElement");

_LIT(KFmt,"EndElement (%s)");

LOG_FORMAT((KFmt,aLocalName));

CSenBaseFragment::EndElementL(aNsUri, aLocalName, aQName);

}

这个EndElement没啥好说的,就是调一下老子的EndElement罢了。倒是那个StartElement函数它在遇到 HelloWorldResponse标签时会交给delegate去处理下级节点,就是说<HelloWorldResponse>以下的 XML内容由CHelloWorldResult类的负责处理了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值