iOS 通过 soap 请求调用地址为 asmx 或 wsdl 服务器上的接口

平时调接口都是直接用 AFN 把接口地址放到 post 方法中就可以获取到需要的数据,但如何调用 java或.net 的 webservice 接口,以登录方法为例:

地址是asmx的:

22.png

这时候需要通过 AFN 发送 soap 请求。

  1. 构建 soap 请求体
NSString *soapbody = [[NSString alloc] init];
    for(NSString *str in pratams.allKeys)
    {
        soapbody = [soapbody stringByAppendingString:[NSString stringWithFormat:@"<%@>%@</%@>\\",str,[pratams objectForKey:str],str]];
    }

2.根据后台soap格式,拼接 soap 字符串(命名空间可能需要修改 )

    //使用命名空间: http://tempuri.org/
    NSString *soapStr = [NSString stringWithFormat:
                         @"<?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:Header>\
                         </soap:Header>\
                         <soap:Body>\
                         <%@ xmlns=\"http://tempuri.org/\">\
                         %@\
                         </%@>\
                         </soap:Body>\
                         </soap:Envelope>",soapMethod,soapbody,soapMethod];
  1. 对 AFN 相关参数进行设置
AFHTTPSessionManager *manager = [ AppDelegate shareManager];
    manager.responseSerializer = [AFXMLParserResponseSerializer serializer];
    // 设置请求超时时间
    manager.requestSerializer.timeoutInterval = 10;
    // 返回NSData
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    // 设置请求头,也可以不设置
    [manager.requestSerializer setValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
    [manager.requestSerializer setValue:[NSString stringWithFormat:@"%zd", soapStr.length] forHTTPHeaderField:@"Content-Length"];
    // 设置HTTPBody
    [manager.requestSerializer setQueryStringSerializationWithBlock:^NSString *(NSURLRequest *request, NSDictionary *parameters, NSError *__autoreleasing *error) {
        return soapStr;
    }];
  1. post 方法
 [manager POST:@"地址" parameters:soapStr progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        // 把返回的二进制数据转为字符串
        NSString *result = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
        // 利用正则表达式取出<return></return>之间的字符串
        NSString *regularStr = [NSString stringWithFormat:@"(?<=%@Result\\>).*(?=</%@Result)",soapMethod,soapMethod];
        NSRegularExpression *regular = [[NSRegularExpression alloc] initWithPattern:regularStr options:NSRegularExpressionCaseInsensitive error:nil];
        NSDictionary *dict = [NSDictionary dictionary];
        for (NSTextCheckingResult *checkingResult in [regular matchesInString:result options:0 range:NSMakeRange(0, result.length)]) {
            // 得到字典
            dict = [NSJSONSerialization JSONObjectWithData:[[result substringWithRange:checkingResult.range] dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableLeaves error:nil];
        }
       
        // 请求成功并且结果有值把结果传出去
        if (success && dict) {
            success(dict);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if (failure) {
            failure(error);

            //请求失败
        }
    }];

完整代码如下:

+ (void)SOAPData:(NSDictionary *)pratams soapMethod:(NSString *)soapMethod success:(void (^)(id))success failure:(void (^)(NSError *))failure
{

    NSString *soapbody = [[NSString alloc] init];
    for(NSString *str in pratams.allKeys)
    {
        soapbody = [soapbody stringByAppendingString:[NSString stringWithFormat:@"<%@>%@</%@>\\",str,[pratams objectForKey:str],str]];
    }
    //使用命名空间: http://tempuri.org/
    NSString *soapStr = [NSString stringWithFormat:
                         @"<?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:Header>\
                         </soap:Header>\
                         <soap:Body>\
                         <%@ xmlns=\"http://tempuri.org/\">\
                         %@\
                         </%@>\
                         </soap:Body>\
                         </soap:Envelope>",soapMethod,soapbody,soapMethod];
    
    

    AFHTTPSessionManager *manager = [ AppDelegate shareManager];
    manager.responseSerializer = [AFXMLParserResponseSerializer serializer];
    // 设置请求超时时间
    manager.requestSerializer.timeoutInterval = 10;
    // 返回NSData
    manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    // 设置请求头,也可以不设置
    [manager.requestSerializer setValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
    [manager.requestSerializer setValue:[NSString stringWithFormat:@"%zd", soapStr.length] forHTTPHeaderField:@"Content-Length"];
    // 设置HTTPBody
    [manager.requestSerializer setQueryStringSerializationWithBlock:^NSString *(NSURLRequest *request, NSDictionary *parameters, NSError *__autoreleasing *error) {
        return soapStr;
    }];
    

    [manager POST:@"地址" parameters:soapStr progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        // 把返回的二进制数据转为字符串
        NSString *result = [[NSString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
        // 利用正则表达式取出<return></return>之间的字符串
        NSString *regularStr = [NSString stringWithFormat:@"(?<=%@Result\\>).*(?=</%@Result)",soapMethod,soapMethod];
        NSRegularExpression *regular = [[NSRegularExpression alloc] initWithPattern:regularStr options:NSRegularExpressionCaseInsensitive error:nil];
        NSDictionary *dict = [NSDictionary dictionary];
        for (NSTextCheckingResult *checkingResult in [regular matchesInString:result options:0 range:NSMakeRange(0, result.length)]) {
            // 得到字典
            dict = [NSJSONSerialization JSONObjectWithData:[[result substringWithRange:checkingResult.range] dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableLeaves error:nil];
        }
       
        // 请求成功并且结果有值把结果传出去
        if (success && dict) {
            success(dict);
        }
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        if (failure) {
            failure(error);

            [[FunctionManager sharedHandel] showAlert:@"网络连接失败" duration:1.0];
        }
    }];
}

调用(比如登录):

 NSDictionary * paramDict = @{@"userName":_nameTextField.text,@"passWord":_passwordTextField.text};
        
        [AFNwebManager SOAPData:paramDict soapMethod:@"getUserList" success:^(id responseObject) {
            
            NSLog(@"%@",responseObject);
            //获取到数据,进行操作
        } failure:^(NSError *error) {
            
            //获取失败
        }];

如果地址是wsdl的:

33.png

注意 soap 请求体的标签可能会不一样,可以下载并借助 soapUI (下载后将接口网址放上去,会生成对应的 soap 格式)

完整代码:

- (void)SOAPData:(NSDictionary *)pratams soapMethod:(NSString *)soapMethod success:(void (^)(id))success failure:(void (^)(void))failure
{
    NSString *soapbody = [[NSString alloc] init];
    for(NSString *str in pratams.allKeys)
    {
        soapbody = [soapbody stringByAppendingString:[NSString stringWithFormat:@"<%@>%@</%@>\\",str,[pratams objectForKey:str],str]];
    }
    ////.net http://tempuri.org/
  //java 与。net的标签不一样,需要借助soapUI查看
    NSString *soapStr = [NSString stringWithFormat:
                                                  @"<?xml version=\"1.0\" encoding=\"utf-8\"?>\
                                                      <soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ser=\"http://service.zhwy.com/\">\
                                                  <soapenv:Header>\
                                                  </soapenv:Header>\
                                                  <soapenv:Body>\
                                                  <ser:%@>\
                                                  %@\
                                                  </ser:%@>\
                                                  </soapenv:Body>\
                                                  </soapenv:Envelope>",soapMethod,soapbody,soapMethod];

    self.manager.responseSerializer = [AFXMLParserResponseSerializer serializer];
    // 设置请求超时时间
    self.manager.requestSerializer.timeoutInterval = 10;
    
    // 返回NSData
    self.manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    
    // 设置请求头,也可以不设置
    [self.manager.requestSerializer setValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
    [self.manager.requestSerializer setValue:[NSString stringWithFormat:@"%zd", soapStr.length] forHTTPHeaderField:@"Content-Length"];
//   self.manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"text/xml",@"text/json", @"text/plain", @"text/html", nil];
    // 设置HTTPBody
    [self.manager.requestSerializer setQueryStringSerializationWithBlock:^NSString *(NSURLRequest *request, NSDictionary *parameters, NSError *__autoreleasing *error) {
        return soapStr;
    }];


    self.task = [self.manager POST:HTTP_STR1 parameters:soapStr progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        // 把返回的二进制数据转为字符串
        NSString *result = [[NSString alloc] initWithData:(NSData *)responseObject encoding:NSUTF8StringEncoding];
        // 利用正则表达式取出<return></return>之间的字符串
        NSString *regularStr = [NSString stringWithFormat:@"(?<=return\\>).*(?=</return)"];
        NSRegularExpression *regular = [[NSRegularExpression alloc] initWithPattern:regularStr options:NSRegularExpressionCaseInsensitive error:nil];
        NSDictionary *dict = [NSDictionary dictionary];

//        NSString *str;
        for (NSTextCheckingResult *checkingResult in [regular matchesInString:result options:0 range:NSMakeRange(0, result.length)]) {
            
            // 得到字典
         //   dict = [NSJSONSerialization JSONObjectWithData:[[result substringWithRange:checkingResult.range] dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableLeaves error:nil];
            NSString *jsonStr = [result substringWithRange:checkingResult.range];
            //注意接口传过来的数据带有&quot字样,需要替换成“ " ”(引号)
            jsonStr = [jsonStr stringByReplacingOccurrencesOfString:@""" withString:@"\""];//替换字符
            NSData *jsonData = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
            dict = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableLeaves error:nil];
//            str = [result substringWithRange:checkingResult.range];
        }
        // 请求成功并且结果有值把结果传出去
        if (success && dict) {
            success(dict);
        }

    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        if(failure)
        {
            failure();
        }
        NSString *errorStr ;
        if(error.code == -1001)
        {
            errorStr = @"网络请求超时";
        }
        else if (error.code == -999){
            return ;
        }
        else if (error.code == -1009)
        {
            errorStr = @"网络未连接";
        }
        else
        {
            errorStr = @"服务器连接异常";
        }
        for (UIView *view in [UIApplication sharedApplication].keyWindow.subviews) {
            if ([view isKindOfClass:[MBProgressHUD class]]) {
                [view removeFromSuperview];
            }
        }
        MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:[UIApplication sharedApplication].keyWindow animated:YES];
        hud.mode = MBProgressHUDModeText;
        hud.label.text = errorStr;
        hud.backgroundColor = [UIColor colorWithWhite:0.f alpha:0.5f];
        hud.offset = CGPointMake(0.f, 200);
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [MBProgressHUD hideHUDForView:[UIApplication sharedApplication].keyWindow animated:YES];
        });
        //HLog(@"error-----------%@",error);
    }];
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,384评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,845评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,148评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,640评论 1 290
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,731评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,712评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,703评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,473评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,915评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,227评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,384评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,063评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,706评论 3 324
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,302评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,531评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,321评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,248评论 2 352

推荐阅读更多精彩内容

  • AFHTTPRequestOperationManager 网络传输协议UDP、TCP、Http、Socket、X...
    Carden阅读 4,335评论 0 12
  • 一、Java基础 1.写出下面代码的执行结果 2.写出下面代码的执行结果 3.写出下面代码的执行结果 (此题需写出...
    joshul阅读 512评论 0 1
  • 概览 CXF frontends 是一组编程的API,被用来开发和发布webservice。CXF支持两种类型的f...
    JohnShen阅读 1,301评论 2 2
  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 31,617评论 18 399
  • 因为工作中使用了SOAP进行两个系统的接口调用,所以私下学习一下两种实现,粗略记录于此。本文侧重于实际实现操作,而...
    峡客阅读 4,377评论 0 4