iOS开发-Get请求,Post请求,同步请求和异步请求

十度 IOS 2015年12月01日 收藏

标题中的Get和Post是请求的两种方式,同步和异步属于实现的方法,Get方式有同步和异步两种方法,Post同理也有两种。稍微有点Web知识的,对Get和Post应该不会陌生,常说的请求处理响应,基本上请求的是都是这两个哥们,Http最开始定义的与服务器交互的方式有八种,不过随着时间的进化,现在基本上使用的只剩下这两种,有兴趣的可以参考本人之前的博客Http协议中Get和Post的浅谈,iOS客户端需要和服务端打交道,Get和Post是跑不了的,本文中包含iOS代码和少量Java服务端代码,开始正题吧.

Get和Post同步请求

Get和Post同步请求的时候最常见的是登录,输入各种密码才能看到的功能,必须是同步,异步在Web上局部刷新的时候用的比较多,比较耗时的时候执行异步请求,可以让客户先看到一部分功能,然后慢慢刷新,举个例子就是餐馆吃饭的时候点了十几个菜,给你先上一两个吃着,之后给别人上,剩下的慢慢上。大概就是这样的。弄了几个按钮先上图:

先贴下同步请求的代码:

  1. //设置URL路径
  2. NSString *urlStr=[NSString stringWithFormat:@"http://localhost:8080/MyWeb/Book?username=%@&password=%@&type=get",@"博客园",@"keso"];
  3. urlStr=[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
  4. NSURL *url=[NSURL URLWithString:urlStr];
  5. //通过URL设置网络请求
  6. NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10];
  7.  
  8. NSError *error=nil;
  9. //获取服务器数据
  10. NSData *requestData= [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error];
  11. if (error) {
  12. NSLog(@"错误信息:%@",[error localizedDescription]);
  13. }else{
  14. NSString *result=[[NSString alloc]initWithData:requestData encoding:NSUTF8StringEncoding];
  15. NSLog(@"返回结果:%@",result);
  16.  
  17. }

代码很多,需要解释一下:

①URL如果有中文无法传递,需要编码一下:

  1. [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

②设置网路请求中的代码,有两个参数,最后一个设置请求的时间,这个不用说什么,重点说下缓存策略cachePolicy,系统中的定义如下:

  1. typedef NS_ENUM(NSUInteger, NSURLRequestCachePolicy)
  2. {
  3. NSURLRequestUseProtocolCachePolicy = 0,
  4.  
  5. NSURLRequestReloadIgnoringLocalCacheData = 1,
  6. NSURLRequestReloadIgnoringLocalAndRemoteCacheData = 4, // Unimplemented
  7. NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData,
  8.  
  9. NSURLRequestReturnCacheDataElseLoad = 2,
  10. NSURLRequestReturnCacheDataDontLoad = 3,
  11.  
  12. NSURLRequestReloadRevalidatingCacheData = 5, // Unimplemented
  13. };

 NSURLRequestUseProtocolCachePolicy(基础策略),NSURLRequestReloadIgnoringLocalCacheData(忽略本地缓存);

NSURLRequestReloadIgnoringLocalAndRemoteCacheData(无视任何缓存策略,无论是本地的还是远程的,总是从原地址重新下载);

NSURLRequestReturnCacheDataElseLoad(首先使用缓存,如果没有本地缓存,才从原地址下载);

NSURLRequestReturnCacheDataDontLoad(使用本地缓存,从不下载,如果本地没有缓存,则请求失败,此策略多用于离线操作);

NSURLRequestReloadRevalidatingCacheData(如果本地缓存是有效的则不下载,其他任何情况都从原地址重新下载);

Java服务端代码:

  1. protected void doGet(HttpServletRequest request,
  2. HttpServletResponse response) throws ServletException, IOException {
  3. // TODO Auto-generated method stub
  4. response.setContentType("text/html;charset=utf-8;");
  5. PrintWriter out = response.getWriter();
  6. System.out.println(request.getParameter("username"));
  7. System.out.println(request.getParameter("password"));
  8. if (request.getParameter("type") == null) {
  9. out.print("默认测试");
  10. } else {
  11. if (request.getParameter("type").equals("async")) {
  12. out.print("异步Get请求");
  13. } else {
  14. out.print("Get请求");
  15. }
  16. }
  17. }

 最终效果如下:

Post请求的代码,基本跟Get类型,有注释,就不多解释了:

  1. //设置URL
  2. NSURL *url=[NSURL URLWithString:@"http://localhost:8080/MyWeb/Book"];
  3. //创建请求
  4. NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10];
  5. [request setHTTPMethod:@"POST"];//设置请求方式为POST,默认为GET
  6. NSString *param= @"Name=博客园&Address=http://www.cnblogs.com/xiaofeixiang&Type=post";//设置参数
  7. NSData *data = [param dataUsingEncoding:NSUTF8StringEncoding];
  8. [request setHTTPBody:data];
  9. //连接服务器
  10. NSData *received = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
  11.  
  12. NSString *result= [[NSString alloc]initWithData:received encoding:NSUTF8StringEncoding];
  13.  
  14. NSLog(@"%@",result);

 Java服务端代码:

  1. protected void doPost(HttpServletRequest request,
  2. HttpServletResponse response) throws ServletException, IOException {
  3. // TODO Auto-generated method stub
  4. request.setCharacterEncoding("utf-8");
  5. response.setContentType("text/html;charset=utf-8");
  6. PrintWriter out = response.getWriter();
  7. System.out.println("姓名:" + request.getParameter("Name"));
  8. System.out.println("地址:" + request.getParameter("Address"));
  9. System.out.println("类型:" + request.getParameter("Type"));
  10. if (request.getParameter("Type").equals("async")) {
  11. out.print("异步请求");
  12. } else {
  13. out.print("Post请求");
  14. }
  15.  
  16. }

效果如下:

Get和Post异步请求

异步实现的时候需要实现协议NSURLConnectionDataDelegate,Get异步代码如下:

  1. //设置URL路径
  2. NSString *urlStr=[NSString stringWithFormat:@"http://localhost:8080/MyWeb/Book?username=%@&password=%s&type=async",@"FlyElephant","keso"];
  3. urlStr=[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
  4. NSURL *url=[NSURL URLWithString:urlStr];
  5. //创建请求
  6. NSURLRequest *request = [[NSURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10];
  7. //连接服务器
  8. NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self];

 实现协议的连接过程的方法:

  1. -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
  2. NSHTTPURLResponse *res = (NSHTTPURLResponse *)response;
  3. NSLog(@"%@",[res allHeaderFields]);
  4. self.myResult = [NSMutableData data];
  5. }
  6.  
  7. ////接收到服务器传输数据的时候调用,此方法根据数据大小执行若干次
  8. -(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
  9. {
  10. [self.myResult appendData:data];
  11. }
  12.  
  13. //数据传输完成之后执行方法
  14. -(void)connectionDidFinishLoading:(NSURLConnection *)connection
  15.  
  16. {
  17. NSString *receiveStr = [[NSString alloc]initWithData:self.myResult encoding:NSUTF8StringEncoding];
  18. NSLog(@"%@",receiveStr);
  19. }
  20.  
  21. //网络请求时出现错误(断网,连接超时)执行方法
  22. -(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
  23.  
  24. {
  25. NSLog(@"%@",[error localizedDescription]);
  26. }

异步传输的过程数据需要拼接,所以这个时候需要设置一个属性接收数据:

  1. @property (strong,nonatomic) NSMutableData *myResult;

效果如下:

 

Post异步传递代码:

  1. //设置URL
  2. NSURL *url=[NSURL URLWithString:@"http://localhost:8080/MyWeb/Book"];
  3. //设置请求
  4. NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10];
  5. [request setHTTPMethod:@"POST"];//设置请求方式为POST,默认为GET
  6. NSString *param= @"Name=keso&Address=http://www.cnblogs.com/xiaofeixiang&Type=async";//设置参数
  7. NSData *data = [param dataUsingEncoding:NSUTF8StringEncoding];
  8. [request setHTTPBody:data];
  9. //连接服务器
  10. NSURLConnection *connection = [[NSURLConnection alloc]initWithRequest:request delegate:self];

效果如下:

异步的请求比较简单,需要的方法都已经被封装好了,需要注意数据是动态拼接的,请求的代码都是在Java Servlet中实现的,Java项目中的目录如下:

Book.java中代码如下:

  1. import java.io.IOException;
  2. import java.io.PrintWriter;
  3. import java.net.URLDecoder;
  4. import java.net.URLEncoder;
  5.  
  6. import javax.servlet.ServletException;
  7. import javax.servlet.annotation.WebServlet;
  8. import javax.servlet.http.HttpServlet;
  9. import javax.servlet.http.HttpServletRequest;
  10. import javax.servlet.http.HttpServletResponse;
  11.  
  12. /**
  13. * Servlet implementation class Book
  14. */
  15. @WebServlet("/Book")
  16. public class Book extends HttpServlet {
  17. private static final long serialVersionUID = 1L;
  18.  
  19. /**
  20. * @see HttpServlet#HttpServlet()
  21. */
  22. public Book() {
  23. super();
  24. // TODO Auto-generated constructor stub
  25. }
  26.  
  27. /**
  28. * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse
  29. * response)
  30. */
  31. protected void doGet(HttpServletRequest request,
  32. HttpServletResponse response) throws ServletException, IOException {
  33. // TODO Auto-generated method stub
  34. response.setContentType("text/html;charset=utf-8;");
  35. PrintWriter out = response.getWriter();
  36. System.out.println(request.getParameter("username"));
  37. System.out.println(request.getParameter("password"));
  38. if (request.getParameter("type") == null) {
  39. out.print("默认测试");
  40. } else {
  41. if (request.getParameter("type").equals("async")) {
  42. out.print("异步Get请求");
  43. } else {
  44. out.print("Get请求");
  45. }
  46. }
  47. }
  48.  
  49. /**
  50. * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse
  51. * response)
  52. */
  53. protected void doPost(HttpServletRequest request,
  54. HttpServletResponse response) throws ServletException, IOException {
  55. // TODO Auto-generated method stub
  56. request.setCharacterEncoding("utf-8");
  57. response.setContentType("text/html;charset=utf-8");
  58. PrintWriter out = response.getWriter();
  59. System.out.println("姓名:" + request.getParameter("Name"));
  60. System.out.println("地址:" + request.getParameter("Address"));
  61. System.out.println("类型:" + request.getParameter("Type"));
  62. if (request.getParameter("Type").equals("async")) {
  63. out.print("异步Post请求");
  64. } else {
  65. out.print("Post请求");
  66. }
  67.  
  68. }
  69.  
  70. }

Get和Post总结

①同步请求一旦发送,程序将停止用户交互,直至服务器返回数据完成,才可以进行下一步操作(例如登录验证);

②异步请求不会阻塞主线程,会建立一个新的线程来操作,发出异步请求后,依然可以对UI进行操作,程序可以继续运行;

③Get请求,将参数直接写在访问路径上,容易被外界看到,安全性不高,地址最多255字节;

④Post请求,将参数放到body里面,安全性高,不易被捕获;