AFNetworking XML请求问题

我正在使用AFNetworking-2和JSON响应,它工作正常,现在我必须将其转换为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 = @""; 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 = @""; 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); } 

使用AFHTTPRequestSerializer将使用URL表单参数编码创建正文。 您的非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 – 对于大多数应用程序来说,它更简单。

要扩展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的事件驱动的XML编程指南或google“NSXMLParser示例”或“NSXMLParser教程”以获取更多信息。


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