AFNetworking XML请求问题

时间:2014-12-05 14:02:04

标签: ios afnetworking afnetworking-2

我正在使用带有JSON响应的AFNetworking-2并且它工作正常,现在我必须将其转换为XML而不是使用JSON,因为服务器响应是XML格式的。在我搜索之后,我使用此代码到达但它无法正常工作。

Charles发现请求错误"Fail to parse data (org.xml.sax.SAXParseException: Content not allowed is prolog)"

请问我的问题在哪里?

我的代码:

    NSString *urlString = BaseURLString;
    NSURL *url = [[NSURL alloc] initWithString:urlString];

    NSString *value = @"<r_PM act=\"login\" loginname=\"1234\" password=\"12345678\" />";

    NSString *message = [value stringByReplacingOccurrencesOfString:@"[\\\"" withString:@""];

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlString]];

    [request setHTTPMethod: @"POST"];
    [request setValue:@"text/xml" forHTTPHeaderField:@"content-type"];
    [request setHTTPBody:[[NSString stringWithFormat:@"%@",message] dataUsingEncoding:NSUTF8StringEncoding]];

    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];

    // Make sure to set the responseSerializer correctly
    operation.responseSerializer = [AFXMLParserResponseSerializer serializer];

    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {

        NSXMLParser *XMLParser = (NSXMLParser *)responseObject;
        [XMLParser setShouldProcessNamespaces:YES];

        // Leave these commented for now (you first need to add the delegate methods)
         XMLParser.delegate = self;
         [XMLParser parse];

    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

        UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error Retrieving Weather"
                                                            message:[error localizedDescription]
                                                           delegate:nil
                                                  cancelButtonTitle:@"Ok"
                                                  otherButtonTitles:nil];
        [alertView show];

    }];

    [operation start];
}

以下是一个正常运行的示例:

- (void)viewDidLoad {

[super viewDidLoad];

NSString *value = @"<r_PM act=\"login\" loginname=\"1234\" password=\"12345678\"/>";

NSString *authenticationURL = @"http://demo.example.com/ex/mob/";
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:authenticationURL]];

NSString *message = [value stringByReplacingOccurrencesOfString:@"[\\\"" withString:@""];

[request setHTTPMethod: @"POST"];
[request setValue:@"text/xml" forHTTPHeaderField:@"content-type"];
[request setHTTPBody:[[NSString stringWithFormat:@"%@",message] dataUsingEncoding:NSUTF8StringEncoding]];

NSURLConnection *urlConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

[urlConnection start];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {

NSString *responseText = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

NSLog(@"%@", responseText);
}

2 个答案:

答案 0 :(得分:3)

当您使用AFHTTPRequestSerializer时,您的身体是使用网址表单参数编码创建的。您的非AFNetworking示例使用XML,因此正文看起来不同。

你想要做这样的事情:

使用序列化程序,然后手动设置和排队操作,而不是使用POST:…便捷方法:

NSMutableURLRequest *request = [requestSerializer requestWithMethod:@"POST" URLString:[[NSURL URLWithString:urlString] absoluteString] parameters:parameters error:nil];
request.HTTPBody = [[NSString stringWithFormat:@"%@",message] dataUsingEncoding:NSUTF8StringEncoding];
AFHTTPRequestOperation *operation = [manager HTTPRequestOperationWithRequest:request success:<# success block #> failure:<# failure block #>];
[manager.operationQueue addOperation:operation];

如果你必须这么做,你可能想要为AFHTTPRequestSerializer创建子类并为你的服务器创建一个自定义序列化器。

但实际上你应该告诉你的服务器团队继续接受JSON - 对于大多数应用来说,它更容易使用。

答案 1 :(得分:3)

要扩展Aaron的答案(您应该接受),如果您的服务器需要XML请求,并且正在发送XML响应,您可以执行以下操作:

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFXMLParserResponseSerializer serializer];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPBody:[xmlRequestString dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPMethod:@"POST"];
[request setValue:@"application/xml" forHTTPHeaderField:@"Content-Type"];
[request setValue:@"application/xml" forHTTPHeaderField:@"Accept"];

NSOperation *operation = [manager HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSXMLParser *parser = responseObject;
    parser.delegate = self;
    if (![parser parse]) {
        // handle parsing error here
    } else {
        // use parsed data here
    }
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    // handle network related errors here
}];

[manager.operationQueue addOperation:operation];

在上面,我设置了两个标头Content-Type(通知服务器您正在发送XML请求)和Accept(通知服务器您已经过了期待并将接受XML响应)。这些不一定是必需的,但可能是很好的做法。还有一些有时在这里使用的变体(例如text/xml是可能的,或者也有一些其他相关的Content-Type值),但它只取决于您的服务器期望的内容。但目标是成为一名优秀的HTTP公民并指定这些标题。

显然,这假设您也实现了NSXMLParserDelegate方法,以便实际解析XML响应,但这超出了本问题的范围。如果您不熟悉NSXMLParser,我建议您查看Apple的Event-Driven XML Programming Guide或google&#34; NSXMLParser示例&#34;或者&#34; NSXMLParser教程&#34;了解更多信息。


顺便说一句,我注意到您正在手动构建XML字符串。某些字段(尤其是密码)可能包含一些在XML字段中保留的字符。因此,如果您手动构建XML,请确保使用<>替换嵌入XML的值中的&&lt;&gt;&amp;分别。

相关问题