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中的值替换<
, >
和&
<
, >
和&
, 分别。