先展示需要请求的链接是什么样子
http://192.168.1.172:8110/pictureBookRecord/addPictureBookRecord?usertoken=1234567&userid= app11234234&jsonStr={\"id\": 1,\"userid\": \"22159185hj00115\",\"pageList\": [{\"pageNumber\":
1,\"description\": \" 第 一 页 \",\"bookMaterial\": {\"type\": 1,\"linkAddress\": \"http:
//aaa.mp3\"}}}]}
像这样的数据,见过的人应该不多吧。刚拿到接口文档的时候,也是一脸懵,正常的不应该是这样
http://192.168.1.172:8110/pictureBookRecord/addPictureBookRecord?usertoken=1234567&userid= app11234234
{\"id\": 1,\"userid\": \"22159185hj00115\",\"pageList\": [{\"pageNumber\":
1,\"description\": \" 第 一 页 \",\"bookMaterial\": {\"type\": 1,\"linkAddress\": \"http:
//aaa.mp3\"}}}]}
被突然多的“jsonStr”这个字段搞的不知道怎么弄。第一时间想到去百度,可惜没有百度到。
想让后台改成上面的那种的使用方法,后台说安卓的可以请求成功!
顿时,心中一万头***狂奔而过。没办法,项目比较急,还是的硬着头皮去研究。
自己想到了几个思路
1)直接请求肯定是不行的,那我可不可以将URL拼接好了再进行编码,最后再去请求呢?
NSString * str = MobilRegist;
NSDictionary * dic = [[NSDictionary alloc] initWithObjectsAndKeys:self.model.userName,@"accountName",self.model.userPwd,@"accountPwd",self.model.phone,@"mobilePhone",@"0",@"type",code,@"code", nil];
NSString * paramStr = [self dictionaryToJson:dic];
str = [str stringByAppendingString:[NSString stringWithFormat:@"data=%@",paramStr]];
str = [str stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
事实证明对于字典不是很多个key-Value的有效,如果字典比较大的话,会出现数据内容过长的错误。
从抓包抓到的数据发现发现414的错误,所以这个方法不行。那我们换其它的方法吧!
2)可以直接放在post的parameter的参数中直接请求?
http://192.168.1.172:8110/pictureBookRecord/addPictureBookRecord?usertoken=1234567&userid= app11234234
jsonStr={\"id\": 1,\"userid\": \"22159185hj00115\",\"pageList\": [{\"pageNumber\":
1,\"description\": \" 第 一 页 \",\"bookMaterial\": {\"type\": 1,\"linkAddress\": \"http:
//aaa.mp3\"}}}]}
果不其然,和预料的一样,也是发生了错误
大概意思说的是,parameter需要一个json的参数。
3)就在自己没有办法的时候,安卓兄弟那边是可以进行正常的请求的。那好吧,那我就将安卓的请求是数据抓包,看一下是什么样子的。然后对比一下看看。
惊喜的发现他们也是使用post请求的,里面有一个name="jsonStr"的字段,而且上传的参数也是全部都有,而且大家不知道有没有看见Content-Disposition:form-data怎么感觉似成相识的感觉。我的天啊,这个不就是和上传头像的方法一毛一样吗?不就是在回调的方法中去上传需要上传的数据吗?好了,有了思路,开始添加方法。
4)开始修改
AFHTTPSessionManager * mn = [self sharedHTTPSession];
mn.responseSerializer = [AFHTTPResponseSerializer serializer];
mn.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"text/json",@"text/javascript",@"text/html",nil];
//https sslcertification
[mn POST:url parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
NSData * data = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
[formData appendPartWithFileData:data name:@"jsonStr" fileName: @"json" mimeType:@"application/json"];
}progress:^(NSProgress *uploadProgress){
}success:^(NSURLSessionDataTask *task, id responseObject) {
if(success){
success(responseObject);
}
} failure:^(NSURLSessionDataTask *task, NSError *error) {
if(failure){
failure(error.description);
}
}];
检查一遍,嗯!应该是没有问题的,一跑,我去!什么情况,居然,不行!
那再抓包和安卓的数据对比一下吧!
对比发现多了一个Content-Type:application/Json的参数,问了后台,后台说他们是收到数据了,但是解析不到数据。最后发现是数据类型不对。
那好吧,再修改吧。
5)既然多了这么一个参数,那我换其它的方法吧!
将
[formData appendPartWithFileData:data name:@"jsonStr" fileName: @"json" mimeType:@"application/json"];
换成
[formData appendPartWithFormData:data name:@"jsonStr"];
好,跑一下!哈哈!终于可以了。
最后补充一下将字典转换为字符串的方法。
NSData * data = [NSJSONSerialization dataWithJSONObject:dic options:NSJSONWritingPrettyPrinted error:nil];
NSString * jsonStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSString *temp = [jsonStr stringByReplacingOccurrencesOfString:@" " withString:@""];
temp = [temp stringByReplacingOccurrencesOfString:@"\r" withString:@""];
temp = [temp stringByReplacingOccurrencesOfString:@"\n" withString:@""];
主要是去除特殊格式的字符串。
本人才疏学浅,如有写的不对的地方,请提出。