AFNetworking 3.0另類的總結
AFNetworking 早已進入了3.0的時代,絕大多數的APP現在都拿3.0的版本來搞一搞,3.0與2.0的區別我這裡就不扯犢子了 。。。。。扯了也白扯,今天總結下幾個另類的冷知識
1.AFNetworking 請求方式
請求方式這個需要總結嗎??? 不就是GET和POST嗎???我們在用到 AFNetworking 可能99%的人用到的請求方式是GET和POST ,但是從一種裝逼的角度上來看,請求方式遠遠不止兩種
GET, POST , PUT , PATCH , DELETE , COTY , HEAD , OPTIONS , LINK , UNLINK , PURGE , LOCK , UNLOCK , PROPFIND , VIEW
大部分的請求方式,我們沒見過甚至都沒聽說過,從服務端的角度,我們開啟spring2.5框架的原始碼
public enum RequestMethod {
GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
}
服務端給我們提供的請求方式有很多種,個人感覺這麼多不是為了裝逼還是為了啥子了 ????裝逼歸裝逼,但是我們需要了解下我們的AFNetworking 框架,但是開啟AFNetworking的原始碼,我們發現AFNetworking只給我們提供了
- (nullable NSURLSessionDataTask *)GET:(NSString *)URLString ...
- (nullable NSURLSessionDataTask *)HEAD:(NSString *)URLString ...
- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString ...
- (nullable NSURLSessionDataTask *)PUT:(NSString *)URLString ...
- (nullable NSURLSessionDataTask *)PATCH:(NSString *)URLString ...
- (nullable NSURLSessionDataTask *)DELETE:(NSString *)URLString ...
其實這基本滿足了我們的需求,但是現實中總有些喜歡裝13的人….上介面
@RequestMapping("/test")
@Controller
public class TestController {
@RequestMapping(value = "/postFlag.do", method = RequestMethod.POST)
public void postActionFlag(String userName, String passWord, HttpServletRequest request,
HttpServletResponse response) throws Exception {
HashMap<String, Object> map = new HashMap<>();
map.put("userName", userName);
map.put("passWord", passWord);
String json = JSONObject.fromObject(map).toString();
response.getOutputStream().write(json.getBytes("UTF-8"));
}
@RequestMapping(value = "/traceFlag.do", method = RequestMethod.TRACE)
public void traceActionFlag(String userName, String passWord, HttpServletRequest request,
HttpServletResponse response) throws Exception {
HashMap<String, Object> map = new HashMap<>();
map.put("userName", userName);
map.put("passWord", passWord);
String json = JSONObject.fromObject(map).toString();
response.getOutputStream().write(json.getBytes("UTF-8"));
}
}
method = RequestMethod.TRACE ,trace請求 。。。。很顯然,你用get和POST是不行滴。。 어떡해 ?
其實所謂GET請求,POST請求或神馬DELETE請求他們本質是沒啥子區別,只不過請求方式上封裝了下,小裝了一下而已。。。 我們來看下原始碼
- (NSURLSessionDataTask *)PUT:(NSString *)URLString
parameters:(id)parameters
success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
{
NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"PUT" URLString:URLString parameters:parameters uploadProgress:nil downloadProgress:nil success:success failure:failure];
[dataTask resume];
return dataTask;
}
我相信你看的的 POST,GET,DELETE也差不多隻不過換了一個字串 “POST”,”GET”, “DELETE” ,那麼trace請求咋搞了???難不成直接把字串換成TRACE,貌似是真是的!!!
再說到這個問題之前我寫過一篇performSelector多個引數的部落格:http://blog.csdn.net/chmod_R_755/article/details/78676395 為什麼要提到這個了 ??? 因為程式碼需要,建議先了解下 performSelector多個引數的這個問題
我們開啟AFNetworking 的原始碼看看,發現AFNetworking 沒有直接給我們提供dataTaskWithHTTPMethod 這個方法,但是,這不重要
-(void)httpPostDataAction{
NSString *url = @"http://10.0.1.199:8088/zc/test/traceFlag.do";
NSDictionary *dic = @{@"userName":@"hebiao",@"passWord":@"12345678"};
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];
manager.requestSerializer = [AFHTTPRequestSerializer serializer];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
SEL anotherSel= NSSelectorFromString(@"dataTaskWithHTTPMethod:URLString:parameters:uploadProgress:downloadProgress:success:failure:");
void (^uploadProgress)(NSProgress *) = ^(NSProgress *uploadProgress){
NSLog(@"######### %@ ===========",uploadProgress);
};
void (^downloadProgress)(NSProgress *) = ^(NSProgress *downloadProgress){
NSLog(@" ^^^^^^^^^ %@ ===========",downloadProgress);
};
void (^success)(NSURLSessionDataTask *, id) = ^(NSURLSessionDataTask *task, id obj){
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:obj options:NSJSONReadingMutableContainers error:nil];
NSLog(@" ~~~~~~~~~~~~ %@ =========== %@",dic , obj);
};
void (^failure)(NSURLSessionDataTask *, NSError *) = ^(NSURLSessionDataTask *task, NSError *error){
NSLog(@" `````````` %@ ===========",[error description] );
};
if ([manager respondsToSelector:anotherSel]) {
NSError *error ;
NSURLSessionDataTask *dataTask = [manager VKCallSelector:anotherSel error:&error,@"TRACE",url,dic,uploadProgress,downloadProgress,success,failure];
[dataTask resume];
}
}
我們很尷尬,也就是我們可以看出來AFNetworking這個框架只支援六種請求 HEAD DELETE POST GET OPTIONS PUT ,但是 我想說的是,六種請求足夠我們在有生之年使用了。。。。。
2.AFNetworking 的 header 傳參和POST傳參
這兩種傳參方式是我們比較常用的,先上程式碼 。。。。
iOS 11端程式碼如下
-(void)testHeadValues{
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject: @"application/json"];
manager.requestSerializer = [AFHTTPRequestSerializer serializer];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
[manager.requestSerializer setValue:@"hebiao" forHTTPHeaderField:@"name"];
[manager.requestSerializer setValue:@"123456" forHTTPHeaderField:@"pwd"];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
NSDictionary *dic = @{@"userName":@"진싼팡",@"passWord":@"습니다"};
[manager POST:@"http://10.0.1.199:8088/zc/test/postFlag.do" parameters:dic progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSDictionary *obj = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];
NSLog(@"success ===================== %@",obj);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
NSLog(@"failure ===================== %@",[error description]);
}];
}
2017-12-22 16:02:54.127061+0800 test[37749:13113786] success ===================== {
date = {
date = 22;
day = 5;
hours = 16;
minutes = 2;
month = 11;
seconds = 54;
time = 1513929774226;
timezoneOffset = "-480";
year = 117;
};
passWord = "\Uc2b5\Ub2c8\Ub2e4";
userName = "\Uc9c4\Uc2fc\Ud321";
}
Java端程式碼如下
@RequestMapping(value = "/postFlag.do", method = RequestMethod.POST)
public void postActionFlag(String userName, String passWord, HttpServletRequest request,
HttpServletResponse response) throws Exception {
Enumeration pHeads =request.getHeaderNames();
while (pHeads.hasMoreElements()) {
String name = (String) pHeads.nextElement();
String value = request.getHeader(name);
String log = "header: name =" + name + " value =" + value;
System.out.println(log);
}
Enumeration pNames = request.getParameterNames();
while (pNames.hasMoreElements()) {
String name = (String) pNames.nextElement();
String value = request.getParameter(name);
String log = "name =" + name + " value =" + value;
System.out.println(log);
}
System.out.println(" ===================== postFlag ======================");
System.out.println("userName ===== "+userName +" passWord ==== "+ passWord);
HashMap<String, Object> map = new HashMap<>();
map.put("userName", userName);
map.put("passWord", passWord);
map.put("date", new Date());
String json = JSONObject.fromObject(map).toString();
response.getOutputStream().write(json.getBytes("UTF-8"));
}
header: name =host value =10.0.1.199:8088
header: name =content-type value =application/x-www-form-urlencoded
header: name =accept value =*/*
header: name =accept-encoding value =gzip, deflate
header: name =connection value =keep-alive
header: name =content-length value =73
header: name =user-agent value =notice/1.0 (iPhone; iOS 10.3.3; Scale/2.00)
header: name =accept-language value =zh-Hans-CN;q=1, ko-CN;q=0.9, en-CN;q=0.8, ko-KR;q=0.7, ja-JP;q=0.6, es-ES;q=0.5
header: name =name value =hebiao
header: name =pwd value =123456
name =passWord value =습니다
name =userName value =진싼팡
===================== postFlag ======================
userName ===== 진싼팡 passWord ==== 습니다
我要說明的是iOS端的header 和 服務端的header 以及 post引數的一種對應關係 ,如果選擇這兩種傳參的形式了 ??? POST 傳參我們發現它僅僅是把服務端需要的欄位傳過去了;而header傳參不僅僅傳遞了所需要的欄位,而且附帶了客戶端資訊(如:使用者代理) 所以選擇什麼傳參是按照業務來定的;但是header傳參有限制,只能給服務端傳字串