我正在使用带有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);
}
答案 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的值中的&
,<
和>
和&
分别。