iOS开发-Get请求,Post请求,同步请求和异步请求
标题中的Get和Post是请求的两种方式,同步和异步属于实现的方法,Get方式有同步和异步两种方法,Post同理也有两种。稍微有点Web知识的,对Get和Post应该不会陌生,常说的请求处理响应,基本上请求的是都是这两个哥们,Http最开始定义的与服务器交互的方式有八种,不过随着时间的进化,现在基本上使用的只剩下这两种,有兴趣的可以参考本人之前的博客Http协议中Get和Post的浅谈,iOS客户端需要和服务端打交道,Get和Post是跑不了的,本文中包含iOS代码和少量Java服务端代码,开始正题吧. Get和Post同步请求 Get和Post同步请求的时候最常见的是登录,输入各种密码才能看到的功能,必须是同步,异步在Web上局部刷新的时候用的比较多,比较耗时的时候执行异步请求,可以让客户先看到一部分功能,然后慢慢刷新,举个例子就是餐馆吃饭的时候点了十几个菜,给你先上一两个吃着,之后给别人上,剩下的慢慢上。大概就是这样的。弄了几个按钮先上图: 先贴下同步请求的代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 //设置URL路径 NSString *urlStr=[ NSString stringWithFormat:@ "http://localhost:8080/MyWeb/Book?username=%@&password=%@&type=get" ,@ "博客园" ,@ "keso" ]; urlStr=[urlStr stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding ]; NSURL *url=[ NSURL URLWithString:urlStr]; //通过URL设置网络请求 NSURLRequest *request = [[ NSURLRequest alloc]initWithURL:url cachePolicy: NSURLRequestUseProtocolCachePolicy timeoutInterval:10]; NSError *error= nil ; //获取服务器数据 NSData *requestData= [ NSURLConnection sendSynchronousRequest:request returningResponse: nil error:&error]; if (error) { NSLog (@ "错误信息:%@" ,[error localizedDescription]); } else { NSString *result=[[ NSString alloc]initWithData:requestData encoding: NSUTF8StringEncoding ]; NSLog (@ "返回结果:%@" ,result); } 代码很多,需要解释一下: ①URL如果有中文无法传递,需要编码一下: 1 [urlStr stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding ]; ②设置网路请求中的代码,有两个参数,最后一个设置请求的时间,这个不用说什么,重点说下缓存策略cachePolicy,系统中的定义如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 typedef NS_ENUM ( NSUInteger , NSURLRequestCachePolicy ) { NSURLRequestUseProtocolCachePolicy = 0, NSURLRequestReloadIgnoringLocalCacheData = 1, NSURLRequestReloadIgnoringLocalAndRemoteCacheData = 4, // Unimplemented NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData , NSURLRequestReturnCacheDataElseLoad = 2, NSURLRequestReturnCacheDataDontLoad = 3, NSURLRequestReloadRevalidatingCacheData = 5, // Unimplemented }; NSURLRequestUseProtocolCachePolicy(基础策略),NSURLRequestReloadIgnoringLocalCacheData(忽略本地缓存); NSURLRequestReloadIgnoringLocalAndRemoteCacheData(无视任何缓存策略,无论是本地的还是远程的,总是从原地址重新下载); NSURLRequestReturnCacheDataElseLoad(首先使用缓存,如果没有本地缓存,才从原地址下载); NSURLRequestReturnCacheDataDontLoad(使用本地缓存,从不下载,如果本地没有缓存,则请求失败,此策略多用于离线操作); NSURLRequestReloadRevalidatingCacheData(如果本地缓存是有效的则不下载,其他任何情况都从原地址重新下载); Java服务端代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.setContentType( "text/html;charset=utf-8;" ); PrintWriter out = response.getWriter(); System.out.println(request.getParameter( "username" )); System.out.println(request.getParameter( "password" )); if (request.getParameter( "type" ) == null ) { out.print( "默认测试" ); } else { if (request.getParameter( "type" ).equals( "async" )) { out.print( "异步Get请求" ); } else { out.print( "Get请求" ); } } } 最终效果如下: Post请求的代码,基本跟Get类型,有注释,就不多解释了: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 //设置URL NSURL *url=[ NSURL URLWithString:@ "http://localhost:8080/MyWeb/Book" ]; //创建请求 NSMutableURLRequest *request = [[ NSMutableURLRequest alloc]initWithURL:url cachePolicy: NSURLRequestUseProtocolCachePolicy timeoutInterval:10]; [request setHTTPMethod:@ "POST" ]; //设置请求方式为POST,默认为GET NSString *param= @ "Name=博客园&Address=http://www.cnblogs.com/xiaofeixiang&Type=post" ;//设置参数 NSData *data = [param dataUsingEncoding: NSUTF8StringEncoding ]; [request setHTTPBody:data]; //连接服务器 NSData *received = [ NSURLConnection sendSynchronousRequest:request returningResponse: nil error: nil ]; NSString *result= [[ NSString alloc]initWithData:received encoding: NSUTF8StringEncoding ]; NSLog (@ "%@" ,result); Java服务端代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub request.setCharacterEncoding( "utf-8" ); response.setContentType( "text/html;charset=utf-8" ); PrintWriter out = response.getWriter(); System.out.println( "姓名:" + request.getParameter( "Name" )); System.out.println( "地址:" + request.getParameter( "Address" )); System.out.println( "类型:" + request.getParameter( "Type" )); if (request.getParameter( "Type" ).equals( "async" )) { out.print( "异步请求" ); } else { out.print( "Post请求" ); } } 效果如下: Get和Post异步请求 异步实现的时候需要实现协议NSURLConnectionDataDelegate,Get异步代码如下: 1 2 3 4 5 6 7 8 9 10 //设置URL路径 NSString *urlStr=[ NSString stringWithFormat:@ "http://localhost:8080/MyWeb/Book?username=%@&password=%s&type=async" ,@ "FlyElephant" , "keso" ]; urlStr=[urlStr stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding ]; NSURL *url=[ NSURL URLWithString:urlStr]; //创建请求 NSURLRequest *request = [[ NSURLRequest alloc]initWithURL:url cachePolicy: NSURLRequestUseProtocolCachePolicy timeoutInterval:10]; //连接服务器 NSURLConnection *connection = [[ NSURLConnection alloc]initWithRequest:request delegate: self ]; 实现协议的连接过程的方法: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 -( void )connection:( NSURLConnection *)connection didReceiveResponse:( NSURLResponse *)response{ NSHTTPURLResponse *res = ( NSHTTPURLResponse *)response; NSLog (@ "%@" ,[res allHeaderFields]); self .myResult = [ NSMutableData data]; } ////接收到服务器传输数据的时候调用,此方法根据数据大小执行若干次 -( void )connection:( NSURLConnection *)connection didReceiveData:( NSData *)data { [ self .myResult appendData:data]; } //数据传输完成之后执行方法 -( void )connectionDidFinishLoading:( NSURLConnection *)connection { NSString *receiveStr = [[ NSString alloc]initWithData: self .myResult encoding: NSUTF8StringEncoding ]; NSLog (@ "%@" ,receiveStr); } //网络请求时出现错误(断网,连接超时)执行方法 -( void )connection:( NSURLConnection *)connection didFailWithError:( NSError *)error { NSLog (@ "%@" ,[error localizedDescription]); } 异步传输的过程数据需要拼接,所以这个时候需要设置一个属性接收数据: 1 @property (strong, nonatomic ) NSMutableData *myResult; 效果如下: Post异步传递代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 //设置URL NSURL *url=[ NSURL URLWithString:@ "http://localhost:8080/MyWeb/Book" ]; //设置请求 NSMutableURLRequest *request = [[ NSMutableURLRequest alloc]initWithURL:url cachePolicy: NSURLRequestUseProtocolCachePolicy timeoutInterval:10]; [request setHTTPMethod:@ "POST" ]; //设置请求方式为POST,默认为GET NSString *param= @ "Name=keso&Address=http://www.cnblogs.com/xiaofeixiang&Type=async" ;//设置参数 NSData *data = [param dataUsingEncoding: NSUTF8StringEncoding ]; [request setHTTPBody:data]; //连接服务器 NSURLConnection *connection = [[ NSURLConnection alloc]initWithRequest:request delegate: self ]; 效果如下: 异步的请求比较简单,需要的方法都已经被封装好了,需要注意数据是动态拼接的,请求的代码都是在Java Servlet中实现的,Java项目中的目录如下: Book.java中代码如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 import java.io.IOException; import java.io.PrintWriter; import java.net.URLDecoder; import java.net.URLEncoder; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet implementation class Book */ @WebServlet ( "/Book" ) public class Book extends HttpServlet { private static final long serialVersionUID = 1L; /** * @see HttpServlet#HttpServlet() */ public Book() { super (); // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse * response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub response.setContentType( "text/html;charset=utf-8;" ); PrintWriter out = response.getWriter(); System.out.println(request.getParameter( "username" )); System.out.println(request.getParameter( "password" )); if (request.getParameter( "type" ) == null ) { out.print( "默认测试" ); } else { if (request.getParameter( "type" ).equals( "async" )) { out.print( "异步Get请求" ); } else { out.print( "Get请求" ); } } } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse * response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub request.setCharacterEncoding( "utf-8" ); response.setContentType( "text/html;charset=utf-8" ); PrintWriter out = response.getWriter(); System.out.println( "姓名:" + request.getParameter( "Name" )); System.out.println( "地址:" + request.getParameter( "Address" )); System.out.println( "类型:" + request.getParameter( "Type" )); if (request.getParameter( "Type" ).equals( "async" )) { out.print( "异步Post请求" ); } else { out.print( "Post请求" ); } } } Get和Post总结 ①同步请求一旦发送,程序将停止用户交互,直至服务器返回数据完成,才可以进行下一步操作(例如登录验证); ②异步请求不会阻塞主线程,会建立一个新的线程来操作,发出异步请求后,依然可以对UI进行操作,程序可以继续运行; ③Get请求,将参数直接写在访问路径上,容易被外界看到,安全性不高,地址最多255字节; ④Post请求,将参数放到body里面,安全性高,不易被捕获; 本文转自Fly_Elephant博客园博客,原文链接:http://www.cnblogs.com/xiaofeixiang/p/4306786.html,如需转载请自行联系原作者