Android Day05-网络编程之提交数据
Android网络:HTTP之利用HttpURLConnection访问网页、获取网络图片实例 (附源码) http://blog.csdn.net/yanzi1225627/article/details/22222735 一、提交数据 手机App向服务器提交数据原理与web页面向服务器提交数据的原理是一样的,都是依赖于Http协 议,只是使用的API不一样而已。 Android最常见的提交数据的类有3个:HttpURLConnection、HttpClient、AsyncHttpClient,它 们都分get和post两种提交方式其中HttpURLConnection是SDK自带的类;HttpClient本来是第3方开源 项目,不过被google纳入了SDK;AsyncHttpClient是一个使用起来特别简单的第3方开源项目,需要去 GitHub下载jar包。 我将6种不同的提交方式整合到了一起,App UI界面如下: 以下是6种不同方式提交数据的源代码: 1)URLGet方式 URLGet的特点就是直接将请求参数拼接到提交地址的后面 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 //1-以URLGet方式登陆 public void loginByURLGet(){ new Thread(){ public void run(){ //如果用户名和账号不为空 if (checkEmpty()){ //已经得到用户名密码,直接拿过来用就行了。 StringservletPath= "http://192.168.17.71/QQCenter/login" ; //拼接地址(*********重要步骤*************) StringurlPath=servletPath+ "?username=" +username + "&password=" +password; try { //第1步:创建URL URLurl= new URL(urlPath); //第2步:创建HttpURLConnection连接 HttpURLConnectionconn=(HttpURLConnection)url .openConnection(); //第3步:设置请求参数 conn.setRequestMethod( "GET" ); conn.setConnectTimeout( 5 ); //第4步:得到响应码 int responseCode=conn.getResponseCode(); //第5步:判断响应码 if (responseCode== 200 ){ //获取服务器端的返回信息 InputStreamin=conn.getInputStream(); Stringcontent=NetUtils.readStream(in); showToast(content); System.out.println( "URLGet方式登陆" ); } else { showToast( "服务器找不到资源" ); } } catch (Exceptione){ e.printStackTrace(); showToast( "服务器忙!!!" ); } } } }.start(); } 2)URLPost方式 URLPost的特点就是将提交的参数通过流写到服务器,相比URLGet方式,要多设两个头信 息,且设置向服务器写入流的权限。 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 public void loginByURLPost(){ new Thread(){ public void run(){ //如果用户名和账号不为空 if (checkEmpty()){ //已经得到用户名密码,直接拿过来用就行了。 StringservletPath= "http://192.168.17.71/QQCenter/login" ; //要写入请求体的参数(*******关键步骤********) Stringdata= "username=" +username+ "&password=" +password; try { //第1步:创建URL URLurl= new URL(servletPath); //第2步:创建HttpURLConnection连接 HttpURLConnectionconn=(HttpURLConnection)url .openConnection(); //第3步:设置请求参数 conn.setRequestMethod( "POST" ); conn.setConnectTimeout( 5 ); //注意设置两个请求头信息(*****关键步骤*****) conn.setRequestProperty( "Content-Type" , "application/x-www-form-urlencoded" ); conn.setRequestProperty( "Content-Length" ,data.length() + "" ); //设置向服务器写入流的权限(****关键步骤***) conn.setDoOutput( true ); //得到输出流向服务器发送请求体数据(*****关键步骤******) OutputStreamout=conn.getOutputStream(); out.write(data.getBytes()); out.close(); //第4步:得到响应码 int responseCode=conn.getResponseCode(); //第5步:判断响应码 if (responseCode== 200 ){ //获取服务器端的返回信息 InputStreamin=conn.getInputStream(); Stringcontent=NetUtils.readStream(in); showToast(content); in.close(); System.out.println( "以URLPost方式登陆" ); } else { showToast( "服务器找不到资源" ); } } catch (Exceptione){ e.printStackTrace(); showToast( "服务器忙!!!" ); } } } }.start(); } 3)ClientGet方式 HttpClient这个类,相比HttpURLConnection语法上有很多的不同。将请求和响应单独封装 成了一个类。获取服务器数据是经过多层包装的,需要先得到数据的实体HttpEntity,根据实体 再得到服务器的输出流。 android DefaultHttpClient 超时 http://blog.csdn.net/howlaa/article/details/17437463 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 public void loginByClientGet(){ new Thread(){ public void run(){ //如果用户名和账号不为空 if (checkEmpty()){ //已经得到用户名密码,直接拿过来用就行了。 StringservletPath= "http://192.168.17.71/QQCenter/login" ; //拼接地址 Stringdata= "username=" +username+ "&password=" +password; Stringurl=servletPath+ "?" +data; try { //第1步:创建HttpClient对象 HttpClientclient= new DefaultHttpClient(); //第2步:创建get请求对象 HttpGetget= new HttpGet(url); //第3步:执行get请求对象,得到response对象。 HttpResponseresponse=client.execute(get); //第4步:得到响应码 int responseCode=response.getStatusLine() .getStatusCode(); //第5步:判断响应码 if (responseCode== 200 ){ //获取服务器端的返回信息与URL不同,先获取的是数据实体。 HttpEntityentity=response.getEntity(); //从数据实体中得到服务的输出流 InputStreamin=entity.getContent(); Stringcontent=NetUtils.readStream(in); showToast(content); in.close(); System.out.println( "以ClientGet方式登陆" ); } else { showToast( "服务器找不到资源" ); } } catch (Exceptione){ e.printStackTrace(); showToast( "服务器忙!!!" ); } } } }.start(); } 4)ClientPost方式 相对ClientGet方式,这种方式提交数据稍微有些复杂。创建post请求的实体数据时,要经 过多层包装。 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 public void loginByClientPost(){ new Thread(){ public void run(){ //如果用户名和账号不为空 if (checkEmpty()){ //已经得到用户名密码,直接拿过来用就行了。 StringservletPath= "http://192.168.17.71/QQCenter/login" ; //请求体数据 Stringdata= "username=" +username+ "&password=" +password; Stringurl=servletPath; try { //第1步:创建HttpClient对象 HttpClientclient= new DefaultHttpClient(); //第2步:创建post请求对象 HttpPostpost= new HttpPost(url); //将请求参数封装到实体------过程稍微有点复杂 List<NameValuePair>listPairs= new ArrayList<NameValuePair>(); //注意name的值与服务器应统一 NameValuePairpair1= new BasicNameValuePair( "username" ,username); NameValuePairpair2= new BasicNameValuePair( "password" ,password); listPairs.add(pair1); listPairs.add(pair2); HttpEntitypostDataEntity= new UrlEncodedFormEntity( listPairs); post.setEntity(postDataEntity); //第3步:执行post请求 HttpResponseresponse=client.execute(post); //第4步:得到状态码 int statusCode=response.getStatusLine() .getStatusCode(); //第5步:判断状态码 if (statusCode== 200 ){ //得到数据的实体 HttpEntityrespEntity=response.getEntity(); //从实体得到流 InputStreamin=respEntity.getContent(); Stringcontent=NetUtils.readStream(in); showToast(content); in.close(); System.out.println( "以ClientPost方式登陆" ); } else { showToast( "找不到资源" ); } } catch (Exceptione){ e.printStackTrace(); showToast( "服务器忙!!!" ); } } }; }.start(); } 5)AsyncHttpClientGet方式 在使用这个类之前,去GitHub下载并导一下这个包com.loopj.android.http到项目的src目 录下。使用AsyncHttpClient还有一个十分爽的地方,就是这个类不需要使用在子线程中,那么 也就可以直接更新UI。请求地址就直接写servlet了,也不用拼接参数了,因为参数都写在了 RequestParams对象中去了。 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 public void loginByAsyncHttpClientGet(){ //如果用户名和账号不为空 if (checkEmpty()){ //已经得到用户名密码,直接拿过来用就行了。 StringservletPath= "http://192.168.1.109/QQCenter/login" ; try { AsyncHttpClientasyncHttpClient= new AsyncHttpClient(); //创建get请求参数 RequestParamsparams= new RequestParams(); params.put( "username" ,username); params.put( "password" ,password); asyncHttpClient.get(getApplicationContext(),servletPath,params, new AsyncHttpResponseHandler(){ //请求成功 @Override public void onSuccess( int statusCode,Header[]headers, byte []responseBody){ if (statusCode== 200 ) { //得到服务器的返回值 Stringcontent= new String(responseBody); Toast.makeText(getApplicationContext(),content, 0 ).show(); System.out.println( "AsyncHttpClientGet方式登陆" ); } else { Toast.makeText(getApplicationContext(), "找不到资源" , 0 ).show(); } } @Override public void onFailure( int statusCode,Header[]headers, byte []responseBody,Throwableerror){ //TODOAuto-generatedmethodstub } }); } catch (Exceptione){ e.printStackTrace(); showToast( "服务器忙!!!" ); } } } 6)AsyncHttpClientPost方式 和AsyncHttpClientGet方式相差无几,调用的是post方法。其它的一样 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 public void loginByAsyncHttpClientPost(){ //如果用户名和账号不为空 if (checkEmpty()){ //已经得到用户名密码,直接拿过来用就行了。 StringservletPath= "http://192.168.17.71/QQCenter/login" ; try { //创建AsyncHttpClient对象 AsyncHttpClientasyncHttpClient= new AsyncHttpClient(); RequestParamsparams= new RequestParams(); params.put( "username" ,username); params.put( "password" ,password); asyncHttpClient.post(getApplicationContext(),servletPath,params, new AsyncHttpResponseHandler(){ @Override public void onSuccess( int statusCode,Header[]headers, byte []responseBody){ if (statusCode== 200 ) { //得到服务器的返回值 Stringcontent= new String(responseBody); Toast.makeText(getApplicationContext(),content, 0 ).show(); System.out.println( "AsyncHttpClientPost方式登陆" ); } else { Toast.makeText(getApplicationContext(), "找不到资源" , 0 ).show(); } } @Override public void onFailure( int statusCode,Header[]headers, byte []responseBody,Throwableerror){ } }); } catch (Exceptione){ e.printStackTrace(); showToast( "服务器忙!!!" ); } } } 提交数据的方式,这么多种,怎么使用呢? HttpClient已被AsyncHttpClient所替代,一般开发都用后者。但是遇到特殊需求时,还是需要 用到最基础的HttpURLConnection,因为它可以设置请求头的参数信息。 二、提交数据时中文乱码问题 待进一步理解 本文转自屠夫章哥 51CTO博客,原文链接:http://blog.51cto.com/4259297/1676565,如需转载请自行联系原作者