AFNetworking的Post中parameters向服务器传输失败
项目调接口时,使用的框架AFNetworking,get正常,post时Java服务器收不到parameters信息,和服务器调了小半天才解决,所以做下记录,下面贴代码(只做参考,不能直接拿来用):
(底下的评论里有更好的方式解决类似问题)
原本代码:
-(AFHTTPSessionManager *)configHTTPSessionManagerWith:(NSString *)apiSign{
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//请求序列
AFJSONRequestSerializer *requestSerializer = [AFJSONRequestSerializer serializer];
[requestSerializer setValue:@"application/x-www-form-urlencoded;
charset=UTF-8" forHTTPHeaderField:@"Content-Type"];
[requestSerializer setValue:apiSign forHTTPHeaderField:@"Api-Sign"];
[requestSerializer setValue:[self readCacheApiToken] forHTTPHeaderField:@"Api-Token"];
requestSerializer.timeoutInterval = kTimeOut;
manager.requestSerializer = requestSerializer;
//响应序列
AFJSONResponseSerializer *responseSerialiazer = [AFJSONResponseSerializer serializer];
responseSerialiazer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html",@"text/css",@"text/xml",@"text/plain", @"application/javascript", @"image/*", nil];
manager.responseSerializer = responseSerialiazer;
DLog(@"httpHeader %@",manager.requestSerializer.HTTPRequestHeaders);
return manager;
}-(id)POSTHttpRequestAsynUrl:(NSString *)url methodType:(HTTPTYPE)methodType parameters:(NSDictionary *)parameters apiSign:(NSString *)apiSign body:(id)body{
NSString *m = [[RequestMethod sharedMethod] typeMethod:methodType];
if(STRISEMPTY(m)){
return nil;
}
dispatch_group_enter(self.dispathGroup);
AFHTTPSessionManager *manager=[self configHTTPSessionManagerWith:apiSign];
__block NSURLSessionDataTask *postDataTask = nil;
postDataTask = [manager POST:url parameters:parameters
progress:^(NSProgress * _Nonnull uploadProgress) {
// 这里获取到目前数据请求的进度
} success:^(NSURLSessionDataTask * _Nonnull task, id_Nullable responseObject) {[self requestSuccess:task responseObject:responseObject methodType:methodType];
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
[self requestFailure:task error:error methodType:methodType];
}];
[postDataTask resume];
RequestID *rid = [RequestID requestIdWith:methodType object:postDataTask andTag:_nextId++];
[self addRequestId:rid];
return rid;
}
服务器收不到parameters,但是在iOS端断点获取到的字典parameters为:
{不知道什么原因服务器收不到参数,后来在TCP层数据流中得到参数传过去的格式为:
phone = 15011058118;
platform = ios;
timestamp = 1525419739;
}
{"phone":"15011058118","platform":"ios","timestamp":"1525423788"},【AFNetworking的Post中parameters向服务器传输失败】(AFNetworking在请求时会把body里面的字典转换为json格式或者http字符串格式)
那么收不到参数的原因就是服务器接受格式和客户端传送格式不一致,由此修改请求传送格式:
requestSerializer有三种格式:
- AFHTTPRequestSerializer:第一种是普通的http的编码格式也就是mid=10&method=userInfo&dateInt=20160818,这种格式的。
- AFJSONRequestSerializer:第二种也是json编码格式的,也就是编码成{"mid":"11","method":"userInfo","dateInt":"20160818"}
- AFPropertyListRequestSerializer:第三种没用过
AFJSONRequestSerializer *requestSerializer = [AFJSONRequestSerializer serializer];
修改为:
AFHTTPRequestSerializer *requestSerializer = [AFHTTPRequestSerializer serializer];
改了之后还不成,
继续调整到最后将body中字典参数parameters拼接成要传的字符串格式,
另外把AFNetworking内部 AFURLRequestSerialization.m 文件中的requestBySerializingRequest 方法中
//这一句注释掉调整后代码:
// [mutableRequest setHTTPBody:[query dataUsingEncoding:self.stringEncoding]];
//替换为:
NSData *postData = https://www.it610.com/article/[parameters dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
[mutableRequest setHTTPBody:postData];
#define kTimeOut35.f
//post请求
-(id)POSTHttpRequestAsynUrl:(NSString *)url methodType:(HTTPTYPE)methodType parameters:(NSDictionary *)parameters apiSign:(NSString *)apiSign body:(id)body{
NSString *m = [[RequestMethod sharedMethod] typeMethod:methodType];
if(STRISEMPTY(m)){
return nil;
}
dispatch_group_enter(self.dispathGroup);
AFHTTPSessionManager *manager=[self configHTTPSessionManagerWith:apiSign];
__block NSURLSessionDataTask *postDataTask = nil;
//将字典转为字符串
NSString *parameterStr = [self dictToStringWithDict:parameters];
postDataTask = [manager POST:url parameters:parameterStr
progress:^(NSProgress * _Nonnull uploadProgress) {
// 这里获取到目前数据请求的进度
} success:^(NSURLSessionDataTask * _Nonnull task, id_Nullable responseObject) {
//请求成功回调
[self requestSuccess:task responseObject:responseObject methodType:methodType];
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
//请求失败回调
[self requestFailure:task error:error methodType:methodType];
}];
[postDataTask resume];
RequestID *rid = [RequestID requestIdWith:methodType object:postDataTask andTag:_nextId++];
[self addRequestId:rid];
return rid;
}-(NSString *)dictToStringWithDict:(NSDictionary *)parameters{
NSDictionary *dic = parameters;
NSString *parameterStr = @"";
for (NSString *key in dic.allKeys) {
parameterStr = [NSString stringWithFormat:@"%@&%@=%@",parameterStr,key,dic[key]];
}
parameterStr = [parameterStr substringFromIndex:1];
return parameterStr;
}
-(AFHTTPSessionManager *)configHTTPSessionManagerWith:(NSString *)apiSign{
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
//如果服务器不接受json,则服务器收不到body参数,需要改变请求格式(requestSerializer有三种编码格式)
/*
AFHTTPRequestSerializer:第一种是普通的http的编码格式也就是mid=10&method=userInfo&dateInt=20160818,这种格式的。
AFJSONRequestSerializer:第二种也是json编码格式的,也就是编码成{"mid":"11","method":"userInfo","dateInt":"20160818"}
AFPropertyListRequestSerializer:第三种没用过
*/
//AFJSONRequestSerializer *requestSerializer = [AFJSONRequestSerializer serializer];
//if (openHttpsSSL) {
//[manager setSecurityPolicy:[self customSecurityPolicy]];
//}
AFHTTPRequestSerializer *requestSerializer = [AFHTTPRequestSerializer serializer];
[requestSerializer setValue:@"application/x-www-form-urlencoded;
charset=UTF-8" forHTTPHeaderField:@"Content-Type"];
[requestSerializer setValue:apiSign forHTTPHeaderField:@"Api-Sign"];
[requestSerializer setValue:[self readCacheApiToken] forHTTPHeaderField:@"Api-Token"];
requestSerializer.timeoutInterval = kTimeOut;
manager.requestSerializer = requestSerializer;
//响应序列
AFJSONResponseSerializer *responseSerialiazer = [AFJSONResponseSerializer serializer];
responseSerialiazer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html",@"text/css",@"text/xml",@"text/plain", @"application/javascript", @"image/*", nil];
manager.responseSerializer = responseSerialiazer;
DLog(@"httpHeader %@",manager.requestSerializer.HTTPRequestHeaders);
return manager;
}
一般用afn中请求时数据传送requestSerializer用json格式就可以了,但是如果服务器不按常规道路走不接收json,就得调整数据传送格式了,一般调整几个方面:
- parameters信息格式,看是不是需要用字典;
- 查requestSerializer请求头的"Content-Type"的值与服务器协商一致;
- 看requestSerializer的请求序列化数据传送格式服务器能接收哪一种。
推荐阅读
- 热闹中的孤独
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- 放屁有这三个特征的,请注意啦!这说明你的身体毒素太多
- 一个人的旅行,三亚
- 布丽吉特,人生绝对的赢家
- 慢慢的美丽
- 尽力
- 一个小故事,我的思考。
- 家乡的那条小河
- 《真与假的困惑》???|《真与假的困惑》??? ——致良知是一种伟大的力量