标题中的Get和Post是请求的两种方式,同步和异步属于实现的方法,Get方式有同步和异步两种方法,Post同理也有两种。稍微有点Web知识的,对Get和Post应该不会陌生,常说的请求处理响应,基本上请求的是都是这两个哥们,Http最开始定义的与服务器交互的方式有八种,不过随着时间的进化,如今基本上使用的只剩下这两种,有兴趣的能够参考本人以前的博客Http协议中Get和Post的浅谈,iOS客户端须要和服务端打交道,Get和Post是跑不了的,本文中包含iOS代码和少许Java服务端代码,开始正题吧.html
Get和Post同步请求的时候最多见的是登陆,输入各类密码才能看到的功能,必须是同步,异步在Web上局部刷新的时候用的比较多,比较耗时的时候执行异步请求,可让客户先看到一部分功能,而后慢慢刷新,举个例子就是餐馆吃饭的时候点了十几个菜,给你先上一两个吃着,以后给别人上,剩下的慢慢上。大概就是这样的。弄了几个按钮先上图:java
先贴下同步请求的代码:缓存
//设置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若是有中文没法传递,须要编码一下:服务器
[urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
②设置网路请求中的代码,有两个参数,最后一个设置请求的时间,这个不用说什么,重点说下缓存策略cachePolicy,系统中的定义以下:网络
typedef NS_ENUM(NSUInteger, NSURLRequestCachePolicy) { NSURLRequestUseProtocolCachePolicy = 0, NSURLRequestReloadIgnoringLocalCacheData = 1, NSURLRequestReloadIgnoringLocalAndRemoteCacheData = 4, // Unimplemented NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData, NSURLRequestReturnCacheDataElseLoad = 2, NSURLRequestReturnCacheDataDontLoad = 3, NSURLRequestReloadRevalidatingCacheData = 5, // Unimplemented };
NSURLRequestUseProtocolCachePolicy(基础策略),NSURLRequestReloadIgnoringLocalCacheData(忽略本地缓存);app
NSURLRequestReloadIgnoringLocalAndRemoteCacheData(无视任何缓存策略,不管是本地的仍是远程的,老是从原地址从新下载);异步
NSURLRequestReturnCacheDataElseLoad(首先使用缓存,若是没有本地缓存,才从原地址下载);
async
NSURLRequestReturnCacheDataDontLoad(使用本地缓存,从不下载,若是本地没有缓存,则请求失败,此策略多用于离线操做);post
NSURLRequestReloadRevalidatingCacheData(若是本地缓存是有效的则不下载,其余任何状况都从原地址从新下载);
Java服务端代码:
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类型,有注释,就很少解释了:
//设置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服务端代码:
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请求"); } }
效果以下:
异步实现的时候须要实现协议NSURLConnectionDataDelegate,Get异步代码以下:
//设置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];
实现协议的链接过程的方法:
-(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]); }
异步传输的过程数据须要拼接,因此这个时候须要设置一个属性接收数据:
@property (strong,nonatomic) NSMutableData *myResult;
效果以下:
Post异步传递代码:
//设置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中代码以下:
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请求"); } } }
①同步请求一旦发送,程序将中止用户交互,直至服务器返回数据完成,才能够进行下一步操做(例如登陆验证);
②异步请求不会阻塞主线程,会创建一个新的线程来操做,发出异步请求后,依然能够对UI进行操做,程序能够继续运行;
③Get请求,将参数直接写在访问路径上,容易被外界看到,安全性不高,地址最多255字节;
④Post请求,将参数放到body里面,安全性高,不易被捕获;