Chinaunix首页 | 论坛 | 博客
  • 博客访问: 22197
  • 博文数量: 28
  • 博客积分: 670
  • 博客等级: 上士
  • 技术积分: 285
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-09 11:27
文章分类

全部博文(28)

文章存档

2011年(28)

我的朋友
最近访客

分类: 嵌入式

2011-01-29 12:25:07

继续刚才的,现在来看具体代码,先是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," /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去处理下级节点,就是说以下的 XML内容由CHelloWorldResult类的负责处理了。

阅读(291) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~