AFNetworking的Post中parameters向服務(wù)器傳輸失敗

項(xiàng)目調(diào)接口時(shí),使用的框架AFNetworking亲茅,get正常娘纷,post時(shí)Java服務(wù)器收不到parameters信息嫁审,和服務(wù)器調(diào)了小半天才解決,所以做下記錄赖晶,下面貼代碼(只做參考律适,不能直接拿來用):

(底下的評論里有更好的方式解決類似問題)

原本代碼:

-(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;

    //響應(yīng)序列
    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) {
                                              // 這里獲取到目前數(shù)據(jù)請求的進(jìn)度
                                          } 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;
}

服務(wù)器收不到parameters辐烂,但是在iOS端斷點(diǎn)獲取到的字典parameters為:

{
phone = 15011058118;
platform = ios;
timestamp = 1525419739;
}

不知道什么原因服務(wù)器收不到參數(shù),后來在TCP層數(shù)據(jù)流中得到參數(shù)傳過去的格式為:

{"phone":"15011058118","platform":"ios","timestamp":"1525423788"}捂贿,

(AFNetworking在請求時(shí)會把body里面的字典轉(zhuǎn)換為json格式或者h(yuǎn)ttp字符串格式)
那么收不到參數(shù)的原因就是服務(wù)器接受格式和客戶端傳送格式不一致纠修,由此修改請求傳送格式:
requestSerializer有三種格式:

  1. AFHTTPRequestSerializer:第一種是普通的http的編碼格式也就是mid=10&method=userInfo&dateInt=20160818,這種格式的厂僧。
  2. AFJSONRequestSerializer:第二種也是json編碼格式的扣草,也就是編碼成{"mid":"11","method":"userInfo","dateInt":"20160818"}
  3. AFPropertyListRequestSerializer:第三種沒用過
AFJSONRequestSerializer *requestSerializer = [AFJSONRequestSerializer serializer];
修改為:
AFHTTPRequestSerializer *requestSerializer = [AFHTTPRequestSerializer serializer];

改了之后還不成,
繼續(xù)調(diào)整到最后將body中字典參數(shù)parameters拼接成要傳的字符串格式颜屠,
另外把AFNetworking內(nèi)部 AFURLRequestSerialization.m 文件中的requestBySerializingRequest 方法中

//這一句注釋掉
// [mutableRequest setHTTPBody:[query dataUsingEncoding:self.stringEncoding]];
//替換為:
NSData *postData = [parameters dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
[mutableRequest setHTTPBody:postData];

調(diào)整后代碼:

#define kTimeOut  35.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;
  //將字典轉(zhuǎn)為字符串
  NSString *parameterStr = [self dictToStringWithDict:parameters];

  postDataTask = [manager POST:url parameters:parameterStr
                                          progress:^(NSProgress * _Nonnull uploadProgress) {
                                              // 這里獲取到目前數(shù)據(jù)請求的進(jìn)度
                                          } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                                              //請求成功回調(diào)
                                              [self requestSuccess:task responseObject:responseObject methodType:methodType];
                                          } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                                              //請求失敗回調(diào)
                                              [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];

    //如果服務(wù)器不接受json辰妙,則服務(wù)器收不到body參數(shù),需要改變請求格式(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;

    //響應(yīng)序列
    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中請求時(shí)數(shù)據(jù)傳送requestSerializer用json格式就可以了蕴坪,但是如果服務(wù)器不按常規(guī)道路走不接收json肴掷,就得調(diào)整數(shù)據(jù)傳送格式了,一般調(diào)整幾個(gè)方面:

  1. parameters信息格式背传,看是不是需要用字典呆瞻;
  2. 查requestSerializer請求頭的"Content-Type"的值與服務(wù)器協(xié)商一致;
  3. 看requestSerializer的請求序列化數(shù)據(jù)傳送格式服務(wù)器能接收哪一種径玖。

如果是服務(wù)器返回的數(shù)據(jù)客戶端接收不到痴脾,就要看看responseSerialiazer中的acceptableContentTypes中接收格式是否缺少。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末梳星,一起剝皮案震驚了整個(gè)濱河市赞赖,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌冤灾,老刑警劉巖前域,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異韵吨,居然都是意外死亡匿垄,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進(jìn)店門归粉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來椿疗,“玉大人,你說我怎么就攤上這事糠悼〗扉” “怎么了?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵倔喂,是天一觀的道長铝条。 經(jīng)常有香客問我童擎,道長,這世上最難降的妖魔是什么攻晒? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任,我火速辦了婚禮班挖,結(jié)果婚禮上鲁捏,老公的妹妹穿的比我還像新娘。我一直安慰自己萧芙,他們只是感情好给梅,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著双揪,像睡著了一般动羽。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上渔期,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天运吓,我揣著相機(jī)與錄音,去河邊找鬼疯趟。 笑死拘哨,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的信峻。 我是一名探鬼主播倦青,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼盹舞!你這毒婦竟也來了产镐?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤踢步,失蹤者是張志新(化名)和其女友劉穎癣亚,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體贾虽,經(jīng)...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡逃糟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蓬豁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绰咽。...
    茶點(diǎn)故事閱讀 40,021評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖地粪,靈堂內(nèi)的尸體忽然破棺而出取募,到底是詐尸還是另有隱情,我是刑警寧澤蟆技,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布玩敏,位于F島的核電站斗忌,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏旺聚。R本人自食惡果不足惜织阳,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望砰粹。 院中可真熱鬧唧躲,春花似錦、人聲如沸碱璃。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽嵌器。三九已至肛真,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間爽航,已是汗流浹背蚓让。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留讥珍,地道東北人凭疮。 一個(gè)月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像串述,于是被迫代替她去往敵國和親执解。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,974評論 2 355

推薦閱讀更多精彩內(nèi)容