转自 ?http://www.cocoachina.com/bbs/read.php?tid=98388
工作中,使用iPhone作为已有产品的移动终端,目前做能想到最理想的方式就是恳求产品提供WebService了,还是老习惯,坚决不要零散的代码,继续整理为通用的类,便于拉壮丁快速开发,虽然目前的壮丁就俺一个,hoho
再次利用现有的资源,使用了ASIHttpRequest v1.8.1,因为项目中使用了Windows集成验证,而这个东西正好提供了响应的验证方式,爽歪歪了。 还是那句话:只是单纯的希望,大家都能有共享学习的精神! 再一个,项目都是.Net相关的,在浏览器中访问.Net WebService的asmx文件时,会返回一系列帮助文件,让我们了解这个WebService有几个调用方法,每个方法的入口参数是什么,返回值是什么,这次使用了SOAP1.1的规范。 再再一个,这个类并不完善,WebService某个方法的参数,必须是简单的数据类型,如数值、字符等等,不支持数据集等对象,等以后需要了再完善吧,呵呵。 再再再一个,调用后的响应解析,是另一个课题,不在这里讲啦,预报下,如果响应中包含了.Net的数据集,也是自己写了通用类可以解析滴,嘎嘎。 再再再再一个,保证是最后一个再了,代码里面看到这个 [Constant sharedConstant].P_SYSTEM_URL ,就去看看前一篇文章吧,单例模式实现常量存储,哈哈。 1、先看看调用说明: 自定义WebService访问类,需要使用下面这个字符串作为SOAP请求,通过POST的方式,提交给WebService
- POST?/iwscooperationws/todocenter.asmx?HTTP/1.1??
- Host:?192.168.1.11??
- Content-Type:?text/xml;?charset=utf-8??
- Content-Length:?length??
- SOAPAction:?"http://iws.CP.ws/GetWorkflowToDoCount"??
- ???
- <?xml?version="1.0"?encoding="utf-8"?>??
- <soap:Envelope?xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"?xmlns:xsd="http://www.w3.org/2001/XMLSchema"?xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">??
- ??<soap:Body>??
- ????<GetWorkflowToDoCount?xmlns="http://iws.CP.ws/">??
- ??????<UserName>string</UserName>??
- ????</GetWorkflowToDoCount>??
- ??</soap:Body>??
- </soap:Envelope>??
在上述的XML中,可以看到这个asmx提供了一个GetWorkflowToDoCount的方法,其参数是UserName,其中的
http://iws.CP.ws/
是WebService中自己定义的命名空间。经过对几个WebService的实验发现,除了这几个字符串之外,都是不变的东西,那么这个长长的串串,就复制粘贴留下来,等下一步利用之。
2、.h文件中的声明,注释都放到了.m文件中,这是个人习惯:
+?(ASIHTTPRequest?*)getASISOAP11Request:(NSString?*)?WebURL??
- ?????????????????????????webServiceFile:(NSString?*)?wsFile??
- ???????????????????????????xmlNameSpace:(NSString?*)?xmlNS??
- ?webServiceName:(NSString?*)?wsName??
- ?wsParameters:(NSMutableArray?*)?wsParas;??
- +?(NSString?*)getSOAP11WebServiceResponse:( ?????????????????????????? ????????????????????????????NSString?*)getSOAP11WebServiceResponseWithNTLM:( ?????????????????????????????????? ????????????????????????????????????NSMutableArray?*)?wsParas??
- ????????????????????????????????????????userName:(NSString?*)?userName??
- ?????????????????????????????????????????passWord:(NSString?*)?passWord;??
- NSString?*)checkResponseError:(NSString?*)?theResponse;??
3、.m文件的实现之一,生成ASIHttpRequest请求:

?
- ?
- ?参数?webURL:????????????????远程WebService的地址,不含*.asmx?
- ?参数?webServiceFile:????????远程WebService的访问文件名,如service.asmx?
- ?参数?xmlNS:????????????????????远程WebService的命名空间?
- ?参数?webServiceName:????????远程WebService的名称?
- ?参数?wsParameters:????????????调用参数数组,形式为[参数1名称,参数1值,参数2名称,参数2值??],如果没有调用参数,此参数为nil?
- ?*/??
- {??
- ??????
- ????NSString?*?soapMsgBody1?=?[[NSString?alloc]?initWithFormat:??
- ???????????????????????????????@"<?xml?version="1.0"?encoding="utf-8"?>n"??
- ???????????????????????????????"<soap:Envelope?xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"?n"??
- ???????????????????????????????"xmlns:xsd="http://www.w3.org/2001/XMLSchema"?n"??
- ???????????????????????????????"xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">n"??
- ???????????????????????????????"<soap:Body>n"??
- ???????????????????????????????"<%@?xmlns="%@">n",?wsName,?xmlNS];??
- ????NSString?*?soapMsgBody2?=?[[NSString?initWithFormat:??
- ???????????????????????????????@"</%@>n"??
- ???????????????????????????????"</soap:Body>n"??
- ???????????????????????????????"</soap:Envelope>",0); background-color:inherit">?wsName];??
- ???????
- ??????
- NSString?*?soapParas?=?[[NSString?init];??
- ????soapParas?=?@"";??
- if?(![wsParas?isEqual:nil])?{??
- ????????int?i?=?0;??
- ????????for?(i?=?0;?i?<?[wsParas?count];?i?=?i?+?2)?{??
- ????????????soapParas?=?[soapParas?stringByAppendingFormat:@"<%@>%@</%@>n",??
- ?????????????????????????[wsParas?objectAtIndex:i],??
- ?????????????????????????[wsParas?objectAtIndex:i+1],0); background-color:inherit">?objectAtIndex:i]];??
- ????????}??
- ????}??
- ???????
- //3、生成SOAP消息??
- NSString?*?soapMsg?=?[soapMsgBody1?stringByAppendingFormat:@"%@%@",?soapParas,0); background-color:inherit">?soapMsgBody2];??
- //请求发送到的路径??
- NSURL?*?url?=?[NSURL?URLWithString:[NSString?stringWithFormat:@"%@%@",?WebURL,0); background-color:inherit">?wsFile]];??
- //NSMutableURLRequest?*theRequest?=?[NSMutableURLRequest?requestWithURL:url];??
- ASIHTTPRequest?*?theRequest?=?[ASIHTTPRequest?requestWithURL:url];??
- NSString?*msgLength?=?[NSString?stringWithFormat:@"%d",?[soapMsg?length]];??
- //以下对请求信息添加属性前四句是必有的,第五句是soap信息。??
- ????[theRequest?addRequestHeader:@"Content-Type"?value:@"text/xml;?charset=utf-8"];??
- ????[theRequest?addRequestHeader:@"SOAPAction"?value:[NSString?wsName]];??
- ?addRequestHeader:@"Content-Length"?value:msgLength];??
- ?setRequestMethod:@"POST"];??
- ?appendPostData:[soapMsg?dataUsingEncoding:NSUTF8StringEncoding]];??
- ?setDefaultResponseEncoding:NSUTF8StringEncoding];??
- return?theRequest;??
- }??
#pragma?mark?-??
- /*?
- ?//Mark:?使用SOAP1.1同步调用WebService请求?
- ?参数?webURL:????????????????远程WebService的地址,不含*.asmx?
- ?参数?webServiceFile:????????远程WebService的访问文件名,如service.asmx?
- ?参数?xmlNS:????????????????????远程WebService的命名空间?
- ?参数?webServiceName:????????远程WebService的名称?
- ?参数?wsParameters:????????????调用参数数组,形式为[参数1名称,参数1值,参数2名称,参数2值??],如果没有调用参数,此参数为nil?
- ?*/??
- +?(NSString?*)?WebURL??
- NSString?*)?wsFile??
- ????????????????????????????NSString?*)?xmlNS??
- NSString?*)?wsName??
- NSMutableArray?*)?wsParas??
- {??
- //创建请求??
- ASIHTTPRequest?*?theRequest?=?[self?getASISOAP11Request:WebURL??
- ?????????????????????????????????????????????webServiceFile:wsFile??
- ???????????????????????????????????????????????xmlNameSpace:xmlNS??
- ?webServiceName:wsName??
- ?wsParameters:wsParas];??
- //显示网络请求信息在status?bar上??
- ????[ASIHTTPRequest?setShouldUpdateNetworkActivityIndicator:YES];??
- //同步调用??
- ?startSynchronous];??
- NSError?*error?=?[theRequest?error];??
- if?(!error)?{??
- return?[theRequest?responseString];??
- else?{??
- ??????????
- return?[NSString?sharedConstant].G_WEBSERVICE_ERROR,?[error?localizedDescription]];??
-
?//Mark:?使用SOAP1.1同步调用WebService请求,需提供Windows集成验证的用户名、密码和域?
- ?参数?userName????????????????用户名--目前来看,不需要输入域信息?
- ?参数?passWord????????????????密码?
- ?????????????????????????????????? ????????????????????????????????????NSString?*)?userName??
- ????????????????????????????????????????NSString?*)?passWord??
- //集成验证NTLM用户名,密码和域设置??
- ?setUsername:userName];??
- ?setPassword:passWord];??
- //[theRequest?setDomain:doMain];??
- //显示网络请求信息在status?bar上??
- ????[ASIHTTPRequestYES];??
- //同步调用??
- ?startSynchronous];??
- ?error];??
- if?(!error)?{??
- ?responseString];??
- ????}??
- else?{??
- ??????????
- ?localizedDescription]];??
- }??
?//Mark:?检查WebService的Response是否包含错误信息?
- ????如果未包含错误,则返回零长度字符串?
- ????否则返回错误描述?
- ????错误信息格式:错误前缀n错误描述?
- NSString?*)?theResponse??
- //检查消息是否包含错误前缀??
- if?(![theResponse?hasPrefix:[Constant?sharedConstant].G_WEBSERVICE_ERROR])?{??
- return?@"";??
- NSMutableString?*sTemp?=?[[NSMutableString?initWithString:theResponse];??
- //获取错误前缀的范围??
- ????????NSRange?range=[sTemp?rangeOfString:[Constant?sharedConstant].G_WEBSERVICE_ERROR];??
- //剔除错误前缀??
- ????????[sTemp?replaceCharactersInRange:range?withString:@""];??
- ???????????
- NSString?*?errMsg?=?sTemp;??
- //Authentication?needed??
- if?([sTemp?isEqualToString:@"Authentication?needed"])?{??
- ????????????errMsg?=?@"用户登录失败!";??
- ????????}??
- //The?request?timed?out??
- ?isEqualToString:@"The?request?timed?out"])?{??
- ????????????errMsg?=?@"访问超时,请检查远程地址等基本设置!";??
- //The?request?was?cancelled??
- ?isEqualToString:@"The?request?was?cancelled"])?{??
- ????????????errMsg?=?@"请求被撤销!";??
- //Unable?to?create?request?(bad?url?)??
- ?isEqualToString:@"Unable?to?create?request?(bad?url?)"])?{??
- ????????????errMsg?=?@"无法创建请求,错误的URL地址!";??
- //The?request?failed?because?it?redirected?too?many?times??
- ?isEqualToString:@"The?request?failed?because?it?redirected?too?many?times"])?{??
- ????????????errMsg?=?@"请求失败,可能是因为被重定向次数过多!";??
- //A?connection?failure?occurred??
- ?isEqualToString:@"A?connection?failure?occurred"])?{??
- ????????????errMsg?=?@"网络连接错误,请检查无线或3G网络设置!";??
- return?errMsg;??
-
//创建WebService的调用参数??
- NSMutableArray?*?wsParas?=?[[NSMutableArray?initWithObjects:??
- ????????????????????????????@"UserName",0); background-color:inherit">?sharedConstant].P_USER_NAME,248); line-height:18px; margin:0px!important; padding:0px 3px 0px 10px!important"> ????????????????????????????nil?nil];??
- ???
- //调用WebService,获取响应??
- NSString?*?theResponse?=?[WebService?getSOAP11WebServiceResponseWithNTLM:[Constant?sharedConstant].P_SYSTEM_URL??????????
- ??????????????????????????????????????????????????????????webServiceFile:[Constant?sharedConstant].G_WS_TODOCENTER??
- ????????????????????????????????????????????????????????????xmlNameSpace:[Constant?sharedConstant].G_WEBSERVICE_NAMESPACE??
- ?webServiceName:[Constant?sharedConstant].G_WS_TODOCENTER_GETWORKFLOWTODOCOUNT??
- ?wsParameters:wsParas??
- ????????????????????????????????????????????????????????????????userName:[Constant?sharedConstant].P_USER_NAME??
- ????????????????????????????????????????????????????????????????passWord:[Constant?sharedConstant].P_PASSWORD];??
- //检查响应中是否包含错误??
- NSString?*?errMsg?=?[WebService?checkResponseError:theResponse];??
- //接下来的代码就是检查errMsg有没有内容??
- //再接下来就是theResponse响应字符串的解析了??
注意这个调用例子里面的WebService的参数UserName和调用windows集成验证时提供的userName,是两回事啊??
(编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|