美文网首页
iOS 通过 soap 请求调用地址为 asmx 或 wsdl

iOS 通过 soap 请求调用地址为 asmx 或 wsdl

作者: AlaricMurray | 来源:发表于2017-08-30 15:59 被阅读0次

    平时调接口都是直接用 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);
        }];
    }
    

    相关文章

      网友评论

          本文标题:iOS 通过 soap 请求调用地址为 asmx 或 wsdl

          本文链接:https://www.haomeiwen.com/subject/iritjxtx.html