本次介绍一下ios使用soap协议和webservice进行通讯。
本人也是近期做了一个小项目,使用到了这中方式。当然现在ios使用的webservice多以restful的居多。想这种复杂的协议soap的,比较少了。
废话少说,开始讲解:
一,先说说原理
soap是一个协议,规范。只要客户端发送特定的xml格式的文本,用post的方式,发送到server端,server端就相应,返回相应的xml格式的回应。
所以知道soap的原理之后,咱们就好做了。
二,ios方面怎么做
来一个可以发送post的方式即可,然后是找到soap的发送协议报文xml格式的,最后是接收,异步接收,收完了再解析返回报文就行啦。很简单。
三,具体程序
在viewcontrol.m中
#import "ViewController.h"
@interface ViewController ()
@property (strong,nonatomic) IBOutletUITextField *search;
@end
@implementation ViewController
@synthesize webData;
@synthesize soapResults;
@synthesize xmlParser;
@synthesize elementFound;
@synthesize matchingElement;
@synthesize conn;
- (IBAction)search:(id)sender
{
// NSString *path=[[NSString alloc] initWithFormat:@"/webservice/query/getresultbyname2"];
// NSMutableDictionary *param = [[NSMutableDictionary alloc] init];
// [param setValue:@"name" forKey:self.search.text];
// [param setValue:@"pageNumber" forKey:@"1"];
// MKNetworkEngine *engine = [[MKNetworkEngine alloc] initWithHostName:@"search.chinajob.com" customHeaderFields:nil];
// MKNetworkOperation *op = [engine operationWithPath:path params:param httpMethod:@"POST"];
// [op addCompletionHandler:^(MKNetworkOperation *completedOperation) {
// NSLog(@"responseData : %@", [completedOperation responseString]);
// NSData *data = [completedOperation responseData];
// NSDictionary *resDict = [NSJSONSerialization JSONObjectWithData:data options:(NSJSONReadingAllowFragments) error:nil];
// [self reloadInputViews];
// } errorHandler:^(MKNetworkOperation *errorOp, NSError *err)
// {
// NSLog(@"error wy : %@", [err localizedDescription]);
// }];
// [engine enqueueOperation:op];
NSString *name = self.search.text;
// 设置我们之后解析XML时用的关键字,与响应报文中Body标签之间的getMobileCodeInfoResult标签对应
matchingElement =@"name";
//创建SOAP消息,内容格式就是网站上提示的请求报文的实体主体部分
NSString *soapMsg = [NSStringstringWithFormat:
@"<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:web=\"http://webservice.kbhn/\">"
"<soapenv:Header/>"
"<soapenv:Body>"
"<web:getresultbyname2>"
"<!--Optional:-->"
"<name>%@</name>"
"<!--Optional:-->"
"<pageNumber>1</pageNumber>"
"</web:getresultbyname2>"
"</soapenv:Body>"
"</soapenv:Envelope>", name, @""];
// 将这个XML字符串打印出来
NSLog(@"%@", soapMsg);
//创建URL,内容是前面的请求报文报文中第二行主机地址加上第一行URL字段
NSURL *url = [NSURLURLWithString:@"http://search.chinajob.com/webservice/query"];
//根据上面的URL创建一个请求
NSMutableURLRequest *req = [NSMutableURLRequestrequestWithURL:url];
NSString *msgLength = [NSStringstringWithFormat:@"%d", [soapMsglength]];
//添加请求的详细信息,与请求报文前半部分的各字段对应
[req addValue:@"text/xml;charset=UTF-8"forHTTPHeaderField:@"Content-Type"];
[req addValue:msgLengthforHTTPHeaderField:@"Content-Length"];
//设置请求行方法为POST,与请求报文第一行对应
[req setHTTPMethod:@"POST"];
// 将SOAP消息加到请求中
[req setHTTPBody: [soapMsgdataUsingEncoding:NSUTF8StringEncoding]];
// 创建连接
conn = [[NSURLConnectionalloc] initWithRequest:reqdelegate:self];
if (conn) {
webData = [NSMutableDatadata];
}
}
// 刚开始接受响应时调用
-(void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *) response{
[webDatasetLength: 0];
}
// 每接收到一部分数据就追加到webData中
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *) data {
[webDataappendData:data];
}
// 出现错误时
-(void) connection:(NSURLConnection *)connection didFailWithError:(NSError *) error {
conn = nil;
webData = nil;
}
// 完成接收数据时调用
-(void) connectionDidFinishLoading:(NSURLConnection *) connection {
NSString *theXML = [[NSStringalloc] initWithBytes:[webDatamutableBytes]
length:[webDatalength]
encoding:NSUTF8StringEncoding];
// 打印出得到的XML
NSLog(@"%@", theXML);
// 使用NSXMLParser解析出我们想要的结果
xmlParser = [[NSXMLParseralloc] initWithData:webData];
[xmlParsersetDelegate: self];
[xmlParsersetShouldResolveExternalEntities: YES];
[xmlParser parse];
}
// 开始解析一个元素名
-(void) parser:(NSXMLParser *) parser didStartElement:(NSString *) elementName namespaceURI:(NSString *) namespaceURI qualifiedName:(NSString *) qName attributes:(NSDictionary *) attributeDict {
if ([elementName isEqualToString:matchingElement]) {
if (!soapResults) {
soapResults = [[NSMutableStringalloc] init];
}
elementFound = YES;
}
}
// 追加找到的元素值,一个元素值可能要分几次追加
-(void)parser:(NSXMLParser *) parser foundCharacters:(NSString *)string {
if (elementFound) {
[soapResultsappendString: string];
}
}
// 结束解析这个元素名
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:matchingElement]) {
UIAlertView *alert = [[UIAlertViewalloc] initWithTitle:@"手机号码信息"
message:[NSStringstringWithFormat:@"%@",soapResults]
delegate:self
cancelButtonTitle:@"确定"
otherButtonTitles:nil];
[alertshow];
elementFound = FALSE;
// 强制放弃解析
[xmlParserabortParsing];
}
}
// 解析整个文件结束后
- (void)parserDidEndDocument:(NSXMLParser *)parser {
if (soapResults) {
soapResults = nil;
}
}
// 出错时,例如强制结束解析
- (void) parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
if (soapResults) {
soapResults = nil;
}
}
- (void)viewDidLoad
{
[superviewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[superdidReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark -
#pragma mark URL Connection Data Delegate Methods
@end
代码中都有注释,最上面都search 我做都相应action,不需要都童鞋可以去掉。
四,获取soap的工具
soapui 去官网安装。把wsdl的url 让soapui去解析出来,下面是我自己的wsdl
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:web="http://webservice.kbhn/">
<soapenv:Header/>
<soapenv:Body>
<web:getresultbyname2>
<!--Optional:-->
<name>mike</name>
<!--Optional:-->
<pageNumber>1</pageNumber>
</web:getresultbyname2>
</soapenv:Body>
</soapenv:Envelope>
soap的头
POST http://search.chinajob.com/webservice/query HTTP/1.1
Accept-Encoding: gzip,deflate
Content-Type: text/xml;charset=UTF-8
SOAPAction: ""
Content-Length: 374
Host: search.chinajob.com
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.1.1 (java 1.5)
别的就没了。工具+代码都在这里了。
实在看不明白的,给我回复。我要是会的话,有时间,尽量回复。