AFN中请求序列化的设置

最近遇到一个需求:要求从客户端传到服务器的参数是json字符串,于是我本能的用pod装了afn然后进行了request和response Serialization的相关设置

AFHTTPSessionManager *netMnager = [AFHTTPSessionManager manager];
    netMnager.requestSerializer  = [AFHTTPRequestSerializer serializer];
    netMnager.responseSerializer = [AFHTTPResponseSerializer serializer];
    [netMnager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    NSDictionary *dicJson =@{@"packetHead": @{
                                     @"serviceCode":@"3005",
                                     @"token":@"fdsfdsfsfsf8f8dsfsdfsfsfsfsf0dsf0sdf",
                                     @"sign":@"FHGHGFHFGHFGHGFHGFHGFHFGHF"},
                             @"packetBody": @{
                                     @"abc":@"你好啊"
                                     }
                             };
    [netMnager POST:@"" parameters:dicJson progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
    }];

在我看来一切都是那么的稀疏平常,可是问题就来了,服务器获取到的数据竟然不是json字符串,而是url编码的格式,也就是&key=value的形式,于是我蒙蔽了,好久没遇到过这种问题了,于是请教了下百度和谷歌,最后研究afn源码发现这是afn设置的原因或者说afn内置的原因

简单的解析下上述代码的运行过程:
1.调用POST方法
image.png

2.调用底层URLSESSIONDATATASK
image.png

3.创建request对象
image.png

4.对request对象进行序列化查询
image.png

5.调用对应的request方法
image.png

6.AFHttpRequest中的方法执行,其中当没有设置序列化方法时,会走默认的序列化方法,在此方法中最后序列化成为urlencode编码格式,问题也出在此处
image.png

image.png

最后的优化
第一种方法,设置AFJSONRequetSerializer,此方法中参数以json对象的二进制形式传向后台服务器

  AFHTTPSessionManager *netMnager = [AFHTTPSessionManager manager];
//    netMnager.requestSerializer  = [AFHTTPRequestSerializer serializer];
      netMnager.requestSerializer  = [AFJSONRequestSerializer serializer];
    netMnager.responseSerializer = [AFHTTPResponseSerializer serializer];
//    [netMnager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
//    [netMnager.requestSerializer setQueryStringSerializationWithBlock:^NSString * _Nonnull(NSURLRequest * _Nonnull request, id  _Nonnull parameters, NSError * _Nullable __autoreleasing * _Nullable error) {
//        NSData *data = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:nil];
//
//        NSString *jsonstr = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
//        NSLog(@"--- %@",jsonstr);
//        return jsonstr;
//    }];
    NSDictionary *dicJson =@{@"packetHead": @{
                                     @"serviceCode":@"3005",
                                     @"token":@"fdsfdsfsfsf8f8dsfsdfsfsfsfsf0dsf0sdf",
                                     @"sign":@"FHGHGFHFGHFGHGFHGFHGFHFGHF"},
                             @"packetBody": @{
                                     @"pageType":@"你好啊"
                                     }
                             };
    [netMnager POST:@"http://192.168.1.7:8888/testgateway" parameters:dicJson progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSLog(@"---  %@",[NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil]);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        NSLog(@"error = %@",error.userInfo);
    }];

image.png
第二种,配置request的序列化查询方法,该方法参数以json字符串的二进制流形式传向服务器

 AFHTTPSessionManager *netMnager = [AFHTTPSessionManager manager];
    netMnager.requestSerializer  = [AFHTTPRequestSerializer serializer];
    netMnager.responseSerializer = [AFHTTPResponseSerializer serializer];
    [netMnager.requestSerializer setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [netMnager.requestSerializer setQueryStringSerializationWithBlock:^NSString * _Nonnull(NSURLRequest * _Nonnull request, id  _Nonnull parameters, NSError * _Nullable __autoreleasing * _Nullable error) {
        NSData *data = [NSJSONSerialization dataWithJSONObject:parameters options:0 error:nil];
        
        NSString *jsonstr = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
        NSLog(@"--- %@",jsonstr);
        return jsonstr;
    }];
    NSDictionary *dicJson =@{@"packetHead": @{
                                     @"serviceCode":@"3005",
                                     @"token":@"fdsfdsfsfsf8f8dsfsdfsfsfsfsf0dsf0sdf",
                                     @"sign":@"FHGHGFHFGHFGHGFHGFHGFHFGHF"},
                             @"packetBody": @{
                                     @"pageType":@"你好啊"
                                     }
                             };
    [netMnager POST:@"http://192.168.1.7:8888/testgateway" parameters:dicJson progress:^(NSProgress * _Nonnull uploadProgress) {
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        NSLog(@"---  %@",[NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil]);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        NSLog(@"error = %@",error.userInfo);
    }];
 
原文地址:https://www.cnblogs.com/tig666666/p/7793180.html