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界面如下:

    wKiom1WtJVaQGXG-AACHnYU0azU088.jpg 

    以下是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()) {
                     // 已经得到用户名密码,直接拿过来用就行了。
                     String servletPath =  "http://192.168.17.71/QQCenter/login" ;
 
                     // 拼接地址(*********重要步骤*************)
                     String urlPath = servletPath +  "?username="  + username
                             "&password="  + password;
 
                     try  {
                         // 第1步:创建URL
                         URL url =  new  URL(urlPath);
 
                         // 第2步:创建HttpURLConnection连接
                         HttpURLConnection conn = (HttpURLConnection) url
                                 .openConnection();
 
                         // 第3步:设置请求参数
                         conn.setRequestMethod( "GET" );
                         conn.setConnectTimeout( 5 );
 
                         // 第4步:得到响应码
                         int  responseCode = conn.getResponseCode();
 
                         // 第5步:判断响应码
                         if  (responseCode ==  200 ) {
                             // 获取服务器端的返回信息
                             InputStream in = conn.getInputStream();
                             String content = NetUtils.readStream(in);
                             showToast(content);
                             System.out.println( "URLGet方式登陆" );
                         else  {
                             showToast( "服务器找不到资源" );
                         }
                     catch  (Exception e) {
                         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()) {
                     // 已经得到用户名密码,直接拿过来用就行了。
                     String servletPath =  "http://192.168.17.71/QQCenter/login" ;
 
                     //要写入请求体的参数(*******关键步骤********)
                     String data =  "username="  + username +  "&password="
                             + password;
 
                     try  {
                         // 第1步:创建URL
                         URL url =  new  URL(servletPath);
 
                         // 第2步:创建HttpURLConnection连接
                         HttpURLConnection conn = (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 );
                         //得到输出流向服务器发送请求体数据(*****关键步骤******)
                         OutputStream out = conn.getOutputStream();
                         out.write(data.getBytes());
                         out.close();
                         // 第4步:得到响应码
                         int  responseCode = conn.getResponseCode();
 
                         // 第5步:判断响应码
                         if  (responseCode ==  200 ) {
                             // 获取服务器端的返回信息
                             InputStream in = conn.getInputStream();
                             String content = NetUtils.readStream(in);
                             showToast(content);
                             in.close();
                             System.out.println( "以URLPost方式登陆" );
                         else  {
                             showToast( "服务器找不到资源" );
                         }
                     catch  (Exception e) {
                         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()) {
                     // 已经得到用户名密码,直接拿过来用就行了。
                     String servletPath =  "http://192.168.17.71/QQCenter/login" ;
 
                     // 拼接地址
                     String data =  "username="  + username +  "&password="
                             + password;
                     String url = servletPath +  "?"  + data;
 
                     try  {
                         // 第1步:创建HttpClient对象
                         HttpClient client =  new  DefaultHttpClient();
                         // 第2步:创建get请求对象
                         HttpGet get =  new  HttpGet(url);
                         // 第3步:执行get请求对象,得到response对象。
                         HttpResponse response = client.execute(get);
 
                         // 第4步:得到响应码
                         int  responseCode = response.getStatusLine()
                                 .getStatusCode();
 
                         // 第5步:判断响应码
                         if  (responseCode ==  200 ) {
                             // 获取服务器端的返回信息 与 URL不同,先获取的是数据实体。
                             HttpEntity entity = response.getEntity();
                             // 从数据实体中得到服务的输出流
                             InputStream in = entity.getContent();
                             String content = NetUtils.readStream(in);
                             showToast(content);
                             in.close();
                             System.out.println( "以ClientGet方式登陆" );
                         else  {
                             showToast( "服务器找不到资源" );
                         }
                     catch  (Exception e) {
                         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()) {
                     // 已经得到用户名密码,直接拿过来用就行了。
                     String servletPath =  "http://192.168.17.71/QQCenter/login" ;
 
                     // 请求体数据
                     String data =  "username="  + username +  "&password="
                             + password;
                     String url = servletPath;
                     try  {
                         // 第1步:创建HttpClient对象
                         HttpClient client =  new  DefaultHttpClient();
                         // 第2步:创建post请求对象
                         HttpPost post =  new  HttpPost(url);
                         // 将请求参数封装到实体------过程稍微有点复杂
                         List<NameValuePair> listPairs =  new  ArrayList<NameValuePair>();                           //注意name的值与服务器应统一  
                         NameValuePair pair1 =  new  BasicNameValuePair(
                                 "username" , username);
                         NameValuePair pair2 =  new  BasicNameValuePair(
                                 "password" , password);
                         listPairs.add(pair1);
                         listPairs.add(pair2);
                         HttpEntity postDataEntity =  new  UrlEncodedFormEntity(
                                 listPairs);
                         post.setEntity(postDataEntity);
                         // 第3步:执行post请求
                         HttpResponse response = client.execute(post);
                         // 第4步:得到状态码
                         int  statusCode = response.getStatusLine()
                                 .getStatusCode();
                         // 第5步:判断状态码
                         if  (statusCode ==  200 ) {
                             // 得到数据的实体
                             HttpEntity respEntity = response.getEntity();
                             // 从实体得到流
                             InputStream in = respEntity.getContent();
                             String content = NetUtils.readStream(in);
                             showToast(content);
                             in.close();
                             System.out.println( "以ClientPost方式登陆" );
                         else  {
                             showToast( "找不到资源" );
                         }
                     catch  (Exception e) {
                         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()) {
             // 已经得到用户名密码,直接拿过来用就行了。
             String servletPath =  "http://192.168.1.109/QQCenter/login" ;
             
             try  {
                 AsyncHttpClient asyncHttpClient =  new  AsyncHttpClient();
                 //创建get请求参数
                  RequestParams params =  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 )
                         {
                             //得到服务器的返回值 
                             String content =  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, Throwable error) {
                         // TODO Auto-generated method stub
                         
                     }
                     
                 });
             catch  (Exception e) {
                 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()) {
                 // 已经得到用户名密码,直接拿过来用就行了。
                 String servletPath =  "http://192.168.17.71/QQCenter/login" ;
                 try  {
                     //创建AsyncHttpClient对象
                     AsyncHttpClient asyncHttpClient =  new  AsyncHttpClient();
                      RequestParams params =  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 )
                             {
                                 //得到服务器的返回值 
                                 String content =  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, Throwable error) {
                             
                         }
                         
                     });
                     
                 catch  (Exception e) {
                     e.printStackTrace();
                     showToast( "服务器忙!!!" );
                 }
             }
         }

  
    提交数据的方式,这么多种,怎么使用呢?

    HttpClient已被AsyncHttpClient所替代,一般开发都用后者。但是遇到特殊需求时,还是需要

  用到最基础的HttpURLConnection,因为它可以设置请求头的参数信息。


二、提交数据时中文乱码问题

    待进一步理解   

      本文转自屠夫章哥  51CTO博客,原文链接:http://blog.51cto.com/4259297/1676565,如需转载请自行联系原作者







相关文章
|
开发框架 前端开发 Android开发
Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势
本文深入探讨了 Flutter 与原生模块(Android 和 iOS)之间的通信机制,包括方法调用、事件传递等,分析了通信的必要性、主要方式、数据传递、性能优化及错误处理,并通过实际案例展示了其应用效果,展望了未来的发展趋势。这对于实现高效的跨平台移动应用开发具有重要指导意义。
1216 4
|
5月前
|
安全 数据库 Android开发
在Android开发中实现两个Intent跳转及数据交换的方法
总结上述内容,在Android开发中,Intent不仅是活动跳转的桥梁,也是两个活动之间进行数据交换的媒介。运用Intent传递数据时需注意数据类型、传输大小限制以及安全性问题的处理,以确保应用的健壯性和安全性。
377 11
|
7月前
|
存储 XML Java
Android 文件数据储存之内部储存 + 外部储存
简介:本文详细介绍了Android内部存储与外部存储的使用方法及核心原理。内部存储位于手机内存中,默认私有,适合存储SharedPreferences、SQLite数据库等重要数据,应用卸载后数据会被清除。外部存储包括公共文件和私有文件,支持SD卡或内部不可移除存储,需申请权限访问。文章通过代码示例展示了如何保存、读取、追加、删除文件以及将图片保存到系统相册的操作,帮助开发者理解存储机制并实现相关功能。
1839 2
|
9月前
|
API 数据处理 Android开发
Android网络请求演变:从Retrofit到Flow的转变过程。
通过这个比喻,我们解释了 Android 网络请求从 Retrofit 到 Flow 的转变过程。这不仅是技术升级的体现,更是反映出开发者在面对并发编程问题时,持续探索和迭求更好地解决方案的精神。未来,还会有更多新的技术和工具出现,我们期待一同 witness 这一切的发展。
269 36
|
7月前
|
Web App开发 缓存 JavaScript
Android网络小说阅读器的实现
小说阅读Demo,。此Demo使用Jsoup解析HTML,实现小说数据抓取(数据源自网络),并包含自定义View、六章小说缓存等功能,但未实现下载。项目还包括屏幕适配、字体设置等,借助第三方框架完成优化。以下是主页、详情页、阅读页等界面展示。
179 0
|
10月前
|
前端开发 Java Shell
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
649 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
9月前
|
XML JavaScript Android开发
【Android】网络技术知识总结之WebView,HttpURLConnection,OKHttp,XML的pull解析方式
本文总结了Android中几种常用的网络技术,包括WebView、HttpURLConnection、OKHttp和XML的Pull解析方式。每种技术都有其独特的特点和适用场景。理解并熟练运用这些技术,可以帮助开发者构建高效、可靠的网络应用程序。通过示例代码和详细解释,本文为开发者提供了实用的参考和指导。
314 15
|
开发工具 Android开发 开发者
Android平台如何不推RTMP|不发布RTSP流|不实时录像|不回传GB28181数据时实时快照?
本文介绍了一种在Android平台上实现实时截图快照的方法,尤其适用于无需依赖系统接口的情况,如在RTMP推送、RTSP服务或GB28181设备接入等场景下进行截图。通过底层模块(libSmartPublisher.so)实现了截图功能,封装了`SnapShotImpl.java`类来管理截图流程。此外,提供了关键代码片段展示初始化SDK实例、执行截图、以及在Activity销毁时释放资源的过程。此方案还考虑到了快照数据的灵活处理需求,符合GB/T28181-2022的技术规范。对于寻求更灵活快照机制的开发者来说,这是一个值得参考的设计思路。
305 1
|
安全 网络安全 Android开发
安卓与iOS开发:选择的艺术网络安全与信息安全:漏洞、加密与意识的交织
【8月更文挑战第20天】在数字时代,安卓和iOS两大平台如同两座巍峨的山峰,分别占据着移动互联网的半壁江山。它们各自拥有独特的魅力和优势,吸引着无数开发者投身其中。本文将探讨这两个平台的特点、优势以及它们在移动应用开发中的地位,帮助读者更好地理解这两个平台的差异,并为那些正在面临选择的开发者提供一些启示。
213 56
|
网络协议 Shell 网络安全
解决两个 Android 模拟器之间无法网络通信的问题
让同一个 PC 上运行的两个 Android 模拟器之间能相互通信,出(qiong)差(ren)的智慧。
245 3

热门文章

最新文章