如何使用 AFNetworking 为请求设置 HTTP 正文?

Posted

技术标签:

【中文标题】如何使用 AFNetworking 为请求设置 HTTP 正文?【英文标题】:How to set the HTTP body for a request using AFNetworking? 【发布时间】:2014-02-12 00:12:27 【问题描述】:

在 AFNetworking 的早期版本中,如果我必须制作自己的自定义客户端,那么我将简单地从 AFHTTPClient 继承并创建我的方法。在 AFNetworking 2.0 中,我相信我需要从 AFHTTPSessionManager 继承。

@interface MyCustomClient : AFHTTPSessionManager
    

    

在我的情况下,我需要以肥皂的形式发送请求。这意味着HTTP Body 将是soap 而HTTP HEADERS 将是text/xml。

假设我有一个变量,其中包含我需要发送到服务器的整个肥皂体。

NSString *soapBody = @"Soap body";

使用上面定义的继承自 AFHTTPSessionManager 的自定义类,我将如何将soap body 设置为Request HTTPBody。

如果无论如何可以从 AFHTTPSessionManager 内部访问 NSURLRequest 那么我可以简单地执行 setHTTPBody 但似乎没有?

我希望我现在说得通了!

【问题讨论】:

【参考方案1】:

你应该创建一个 AFHTTPRequestSerializer 的子类,然后实现协议 AFURLRequestSerialization,这个类将关心向请求添加正文和标头

 - (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request
                                withParameters:(id)parameters
                                         error:(NSError * __autoreleasing *)error

     NSParameterAssert(request);

     if ([self.HTTPMethodsEncodingParametersInURI containsObject:[[request HTTPMethod] uppercaseString]]) 
         return [super requestBySerializingRequest:request withParameters:parameters error:error];
     

     NSMutableURLRequest *mutableRequest = [request mutableCopy];

     [self.HTTPRequestHeaders enumerateKeysAndObjectsUsingBlock:^(id field, id value, BOOL * __unused stop) 
         if (![request valueForHTTPHeaderField:field]) 
             [mutableRequest setValue:value forHTTPHeaderField:field];
         
     ];


     [mutableRequest setValue:@"application/soap+xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
     [mutableRequest setHTTPBody:@"This is the soap Body!!"];

     return mutableRequest;

您可以阅读实现或其他 AFHTTPRequestSerializer 子类https://github.com/AFNetworking/AFNetworking/blob/master/AFNetworking/AFURLRequestSerialization.m#L1094

【讨论】:

但是皂体可以因不同的呼叫而不同。如果没有子类化,也没有办法做到这一点。我猜 AFNetworking 2.0 设计得不好。 问题是Objective-C没有本地方法来构建soap body,您可以通过阅读WSDL或制作body模板来使该类构建适当的body。 这是正确的做法。 @johndoe你错了。 AFNetworking 旨在完美适应这一点。附加方法参数可用于对构造 SOAP 主体所需的任何附加信息进行编码。【参考方案2】:

初始化一个 NSMutableURLRequest *request;并将 httpBody 设置为通过以下方式请求: [request setHTTPBody:[soapMessage dataUsingEncoding:NSUTF8StringEncoding]];

你可以试试这个代码。

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:requestURL]];
    request.HTTPMethod = @"POST";
    [request setValue:@"application/soap+xml;charset = utf-8" forHTTPHeaderField:@"Content-Type"];
    request.HTTPBody = [soapMessage dataUsingEncoding:NSUTF8StringEncoding];
    NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate:self delegateQueue:nil];
    NSURLSessionDataTask *sessionTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) 
              if (!error) 
                  // parse response here
               else 
                  // error
              
          ];
    [sessionTask resume];

希望对你有帮助。

【讨论】:

我尝试了以下方法:但没有奏效。我在这里错过了什么吗,请看一下: NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"tempuri.org/"]]; [request setValue:@"text/xml" forHTTPHeaderField:@"Content-type"]; [请求 setHTTPMethod:@"POST"]; [请求 setHTTPBody:[soapMessage dataUsingEncoding:NSUTF8StringEncoding]]; AFHTTPSessionManager *sManager = [[AFHTTPSessionManager alloc] init]; ` [sManager dataTaskWithRequest:(NSURLRequest *)request completionHandler:^( NSURLResponse *response, NSData *data, NSError *error) NSLog(@"%@", data); ];` 你可以在this question看到正确的代码 @AnoopVaidya 你的问题,XML 格式似乎有些问题。 "n" 和 "n" 最后的字符 'n' 是什么?

以上是关于如何使用 AFNetworking 为请求设置 HTTP 正文?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 AFNetworking 2 设置 HTTP 请求?

如何知道请求是不是来自缓存或不使用 AFNetworking

iOS开发之AFNetworking 3.0.4使用

ios开发之--使用AFNetWorking 3.1.0 ,简单的请求封装类

AFNetworking 3.0 迁移

如何在上传带参数的图像时使用 AFNetworking 2.0 设置 cookie?