引言
只說IOS和Android官方自帶的網(wǎng)絡(luò)請求,不說第三方框架.
IOS
介紹
An NSURLConnection object lets you load the contents of a URL by providing a URL request object. The interface for NSURLConnection is sparse, providing only the controls to start and cancel asynchronous loads of a URL request. You perform most of your configuration on the URL request object itself.
NSURLConnection通過提供一個URL request對象下載URL的內(nèi)容,提供給NSURLConnection的接口是稀少的,只提供了控制開始和結(jié)束異步下載.但是可以對request object本身做更多的配置.
NSURLConnection只分異步和同步請求,如果要區(qū)分GET和POST請求,下面會說.
-
同步請求
+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse * _Nullable *)response error:(NSError * _Nullable *)error
參數(shù) | 解釋 |
---|---|
request | 用來下載的URL request,這個request對象是深度復(fù)制的過程,當前方法的時候不會影響其他正在請求的進程. |
response | 返回response信息 |
error | 請求時如果錯誤發(fā)生輸出錯誤信息,可能是NULL |
returnValue | 返回的是NSData數(shù)據(jù),即請求成功返回的數(shù)據(jù) |
DEMO
NSURL * url = [NSURL URLWithString:@"http://www.baidu.com"];
NSURLRequest * request = [NSURLRequest requestWithURL:url];
NSData * data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSLog(@"%@",data);
NSLog(@"繼續(xù)執(zhí)行");
-
異步請求
+ (void)sendAsynchronousRequest:(NSURLRequest *)request queue:(NSOperationQueue *)queue completionHandler:(void (^)(NSURLResponse *response, NSData *data, NSError *connectionError))handler
參數(shù) | 解釋 |
---|---|
request | 用來下載的URL request,這個request對象是深度復(fù)制的過程,當前方法的時候不會影響其他正在請求的進程. |
queue | 選擇哪一個隊列去處理當請求結(jié)束 |
handler | 請求處理函數(shù),就是回調(diào)函數(shù) |
DEMO
NSURL *url=[NSURL URLWithString:@"http://apis.juhe.cn/mobile/get"];
NSURLRequest * request=[NSURLRequest requestWithURL:url];
NSOperationQueue *queue =[NSOperationQueue mainQueue];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
//解析json
NSDictionary *dict=[NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil];
NSLog(@"%@",dict);
}];
-
GET 和 POST請求
ios設(shè)置get或者post請求使用NSMutableURLRequest這個類來創(chuàng)建request,異步同步和上面,只需要替換request就行.
NSMutableURLRequest is a subclass of NSURLRequest provided to aid developers who may find it more convenient to mutate a single request object for a series of URL load requests instead of creating an immutable NSURLRequest object for each load.
NSMutableURLRequest是NSURLRequest的子類,是為了幫助開發(fā)者能夠容易改造簡單的請求,從而代替NSURLConnection.
DEMO: (block的方式異步,無法對請求進行監(jiān)控)
- (void)NSURLConnectionSendAsynchronousPostRequest{
NSURL *url=[NSURL URLWithString:@"www.baidu.com"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10];
[request setHTTPMethod:@"POST"];//設(shè)置請求方式為POST肴茄,默認為GET
NSDictionary *dict=@{
@"key":@"0f91954955628c69dd7610ea9a5229ff",
@"dtype":@"json",
@"ps":@"100",
@"pno":@"2"
} ; //數(shù)據(jù)
NSData *data = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil ];
[request setHTTPBody:data];//設(shè)置http body傳輸?shù)臄?shù)據(jù) json格式
NSOperationQueue *queue =[NSOperationQueue mainQueue];
[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
//在這里做回調(diào)處理
NSString *test1=[[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
NSLog(@"---%@",test1);
}];
}
DEMO (代理的方式,可以監(jiān)控請求)
只需要實現(xiàn)下面的delgete,然后這樣請求就行:
[NSURLConnection connectionWithRequest:request delegate:self];
// 服務(wù)器開始給客戶端回傳數(shù)據(jù),這個方法只會執(zhí)行一次
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
// 服務(wù)器開始回傳數(shù)據(jù),客戶端需要創(chuàng)建一個空的,可變的Data對象,用于存儲每次獲取的數(shù)據(jù)片段
// @property (nonatomic,retain)NSMutableData * returnInfoData;
self.returnInfoData = [[NSMutableData alloc]init];
NSHTTPURLResponse * httpResponse = (NSHTTPURLResponse *)response;
// 狀態(tài)碼
NSLog(@"%ld",httpResponse.statusCode);
// 響應(yīng)報頭
NSLog(@"%@",httpResponse.allHeaderFields);
NSLOG_FUNCTION;
}
// 客戶端持續(xù)接收數(shù)據(jù),data是數(shù)據(jù)片段,整個數(shù)據(jù)分段返回,這個方法執(zhí)行的次數(shù)取決于數(shù)據(jù)總長度[response expectedContentLength]
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
[_returnInfoData appendData:data];
NSLOG_FUNCTION;
}
// 數(shù)據(jù)完全下載成功,接收到完整數(shù)據(jù)
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
// _returnInfoData 是完整的數(shù)據(jù)了
[_returnInfoData release];
NSLOG_FUNCTION;
}
// 數(shù)據(jù)下載失敗
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
NSLog(@"didFailWithError");
NSLOG_FUNCTION;
}
ios7之后提出用NSURLSession替代NSURLConnection.
The NSURLSession class and related classes provide an API for downloading content. This API provides a rich set of delegate methods for supporting authentication and gives your app the ability to perform background downloads when your app is not running or, in iOS, while your app is suspended.
NSURLSession 類和相關(guān)類提供下載的api.這些api提供豐富的委托方法來處理后臺下載的流程,當你的app中斷或者無法運行.
- NSURLSession :一個session對象
- NSURLSessionConfiguration :當初始化session的配置對象
- NSURLSessionTask :處理任務(wù)的基類
- NSURLSessionDataTask:這個類是用來獲取數(shù)據(jù),將返回數(shù)據(jù)作為NSData返回
- NSURLSessionUploadTask :上傳文件的一個類
- NSURLSessionDownloadTask :下載臨時性的文件
- NSURLSessionStreamTask:用來建立TCP/IP連接的
我們用NSURLSessionDataTask進行請求數(shù)據(jù),所以我們使用NSURLSessionDataDelegate代理來請求.
NSURLSessionDataDelegate:
URLSession:dataTask:didReceiveResponse:completionHandler :告知代理任務(wù)獲取到了服務(wù)器剛開始的回復(fù)
URLSession:dataTask:didBecomeDownloadTask:告知數(shù)據(jù)任務(wù)這個任務(wù)邊為下載任務(wù)
URLSession:dataTask:didBecomeStreamTask:告知這個數(shù)據(jù)任務(wù)轉(zhuǎn)變?yōu)橄螺dstream的任務(wù)
URLSession:dataTask:didReceiveData:告知代理data任務(wù)已經(jīng)獲取期望的數(shù)據(jù)
URLSession:dataTask:willCacheResponse:completionHandler:詢問代理數(shù)據(jù)任務(wù)返回的response是否要存到緩存中
DEMO:
-(void)NSURLSessionDelgete{
NSURL *url=[NSURL URLWithString:@"http://apis.juhe.cn/mobile/get"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10];
[request setHTTPMethod:@"POST"];//設(shè)置請求方式為POST晌畅,默認為GET
NSDictionary *dict=@{
@"key":@"0f91954955628c69dd7610ea9a5229ff",
@"dtype":@"json",
@"ps":@"100",
@"pno":@"2"
} ; //數(shù)據(jù)
NSData *data = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:nil ];
[request setHTTPBody:data];//設(shè)置http body傳輸?shù)臄?shù)據(jù) json格式
//代理的方法,主線程
NSURLSession *session_1 = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] delegate: self delegateQueue:[NSOperationQueue mainQueue]];
//創(chuàng)建任務(wù)(因為要使用代理方法但指,就不需要block方法初始化)
NSURLSessionDataTask *task_1 = [session_1 dataTaskWithRequest:request];
//啟動
[task_1 resume];
}
//服務(wù)器開始響應(yīng),準備返回數(shù)據(jù)
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler
{
//運行出來服務(wù)器的響應(yīng)
completionHandler(NSURLSessionResponseAllow);
//當網(wǎng)絡(luò)請求是基于http協(xié)議的時候抗楔,response的本質(zhì)為NSHTTPURLResponse
// NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
//初始化容器
_mData = [NSMutableData data];
}
//客戶端接收數(shù)據(jù)
-(void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data
{
[_mData appendData:data];
}
//數(shù)據(jù)請求完成網(wǎng)絡(luò)請求成功棋凳,當error不為空,說明響應(yīng)出錯
-(void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error
{
if (error) {
NSLog(@"error -- %@",error);
}
else
{
NSString *str = [[NSString alloc]initWithData:_mData encoding:NSUTF8StringEncoding];
NSLog(@"delegate -- %@",str);
}
}
Android
Android自帶的有兩種:
- HttpClient (已經(jīng)被棄用)
- HttpURLConnection
所以我們只簡單說一下HttpURLConnection.
同步異步:
Android中的同步只需要在主線程執(zhí)行下面demo代碼就行,異步就是new Thread()一個線程.
Demo:(通過建立連接,對輸出輸入流讀寫來傳遞和獲取數(shù)據(jù))
HttpURLConnection conn = null;
try {
// 創(chuàng)建一個URL對象
URL mURL = new URL(url);
// 調(diào)用URL的openConnection()方法,獲取HttpURLConnection對象
conn = (HttpURLConnection) mURL.openConnection();
conn.setRequestMethod("POST");// 設(shè)置請求方法為post
conn.setReadTimeout(5000);// 設(shè)置讀取超時為5秒
conn.setConnectTimeout(10000);// 設(shè)置連接網(wǎng)絡(luò)超時為10秒
conn.setDoOutput(true);// 設(shè)置此方法,允許向服務(wù)器輸出內(nèi)容
// post請求的參數(shù)
String data = content;
// 獲得一個輸出流,向服務(wù)器寫數(shù)據(jù),默認情況下,系統(tǒng)不允許向服務(wù)器輸出內(nèi)容
OutputStream out = conn.getOutputStream();// 獲得一個輸出流,向服務(wù)器寫數(shù)據(jù)
out.write(data.getBytes());
out.flush();
out.close();
int responseCode = conn.getResponseCode();// 調(diào)用此方法就不必再使用conn.connect()方法
if (responseCode == 200) {
InputStream is = conn.getInputStream();
String response = getStringFromInputStream(is);
return response;
} else {
throw new NetworkErrorException("response status is "+responseCode);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (conn != null) {
conn.disconnect();// 關(guān)閉連接
}
}