Android中实现java与PHP服务器(基于新浪云免费云平台)http通信详解

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介:

Android中实现java与PHP服务器(基于新浪云免费云平台)http通信详解

   

(本文转自: http://blog.csdn.net/yinhaide/article/details/44756989)        

前言:现在很多APP都需要云的功能,也就是通过网络与服务器交换数据。有的采用tcp/ip协议,但是你必须拥有一个固定ip的服务器,可以购买阿里云服务器之类的,就是贵了点。如果只是个人的小应用的的话可以采用新浪云平台这种免费的服务器,采用的协议是http协议,具体实现方式如下:

方式一、在线登陆

这种方式一般是手机端向服务器提交用户名与密码两个参数,服务器通过数据库中查找匹配,找到与没找到都回复手机一个应答数据即可。

手机端代码实现

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
HttpClient httpClient =  new  DefaultHttpClient();
//这里是你与服务器交互的地址  
String validateUrl = " 
//设置读取超时
httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,  8000 );
//设置读取超时
httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT,  8000 );
HttpPost httpRequst =  new  HttpPost(validateUrl);                 
//准备传输的数据
List<BasicNameValuePair> params =  new  ArrayList<BasicNameValuePair>();
//以post的方式给服务器传一下数据 健-值结构
params.add( new  BasicNameValuePair( "name" "zhangsan" ));
params.add( new  BasicNameValuePair( "password" "123" ));  
 
try
{
     //发送请求
     httpRequst.setEntity( new  UrlEncodedFormEntity(params, HTTP.UTF_8));
     //得到响应
     HttpResponse response = httpClient.execute(httpRequst);
     //返回值如果为200的话则证明成功的得到了数据
     if (response.getStatusLine().getStatusCode() ==  200 ){
         StringBuilder builder =  new  StringBuilder();
         //将得到的数据进行解析
         BufferedReader buffer =  new  BufferedReader( new  InputStreamReader(response.getEntity().getContent()));
         for (String s =buffer.readLine(); s!=  null ; s = buffer.readLine()){
             builder.append(s);
         }
         //得到Json对象
         JSONObject jsonObject   =  new  JSONObject(builder.toString());
         //通过得到键值对的方式得到值,其中success是服务器定义返回的数据
         String result = jsonObject.getString( "success" );
         Log.e( "message" , result);
     else {
         Log.e( "login" , "erro" );
         result= "erro" ;
     }
catch  (Exception e) {
     Log.e( "sharehotel" , "exception" );
     result= "exception" ;
}

 当然 Menifest必须添加联网权限啦~

1
< uses-permission  android:name = "android.permission.INTERNET"  />

服务器端代码实现

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
<?php  
     require_once ( "database.php" );  
     $db  new  DB();  
     $name  $_POST [ 'name' ];  
         $name  = iconv( "utf-8" , "gbk" , $name );  
     $passwd  $_POST [ 'passwd' ];  
         $passwd  = iconv( "utf-8" , "gbk" , $passwd );  
     //查看用户名和密码是否正确  
     $sql  "select name from `user_database` where name='%s' and password='%s' limit 1" ;  
     $sql  = sprintf( $sql $name $password );  
     $result  $db ->select( $sql );  
     if  (! count ( $result )){  
         $ret [ 'success' ] =  "false" ;  
         $ret [ 'msg' ] =  "fromuser or passwd is invalid" ;  
         $json  = json_encode( $ret );  
         echo  $json ;  
         exit ;  
     }     
         //密码或用户名正确  
     $ret [ 'success' ] =  "true" ;  
     $ret [ 'msg' ] =  "success login" ;  
     $json  = json_encode( $ret );  
     echo  $json ;  
     exit ;  
?>

前面两行输连接上新浪云平台的数据库,第三行是GBK文字编码转成UTF-8,因为有时候手机端采用的是GBK的编码方式。可以通过eclipse-右键工程-property-Android查看编码方式。再下面就是数据库查询了,如果查询成功即给手机返回json数据(键值格式success-true),如果失败返回false。

附上新浪云数据库函数database.php

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
<?php  
class  DB{  
   
     private  $mysql ;  
     function  __construct( $charset = "GBK" ){  
           
         //使用sae接口连接到数据库  
         $this ->mysql =  new  SaeMysql();  
         $this ->mysql->setCharset( $charset );        //设置字符集  
     }  
     /** 
      * @return:成功返回数组,失败时返回false 
      */  
     public  function  select( $sql ){  
         $result  $this ->mysql->getData( $sql );  
         if  ( $this ->mysql->errno() != 0){  
             die "Error:"  $this ->mysql->errmsg());  
         }  
         return  $result ;  
     }  
     /** 
      * @return:运行Sql语句,不返回结果集 
      */  
     public  function  query( $sql ){  
         $this ->mysql->runSql( $sql );  
         if  ( $this ->mysql->errno() != 0){  
             die "Error:" . $this ->mysql->errmsg());  
         }  
           
     }  
     public  function  exec ( $sql ){  
         $this ->query( $sql );  
     }  
     function  __destruct(){  
   
         $this ->mysql->closeDb();  
   
     }  
     public  function  get_con(){  
         return  $this ->mysql;  
     }  
}  
?>

当然,不得不说的是,因为手机端登陆访问服务器是个耗时操作,你不能在主线程中直接调用以上代码,必须要新开辟一个线程处理这些耗时的操作。具体怎么开辟线程处理这里就不多讲了!

方式二:批量的数据获取

相对第一种方式来说,这种方式获得的数据结构更加复杂。比如说,你需要服务器返回给你十条数据,其中每条数据中都包含若干个键值数据,相当于一个二维数组。手机端的请求代码一样,只是在收到数据之后需要解包,因为服务器把数据打包发送来的。

服务器端实现代码:

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
<?php  
     require_once ( "database.php" );  
     //解码  
     function  JSON( $array ) {  
             arrayRecursive( $array 'urlencode' , true);  
             $json  = json_encode( $array );  
             return  urldecode( $json );  
             }  
     function  arrayRecursive(& $array $function $apply_to_keys_also  = false)  
         {  
             static  $recursive_counter  = 0;  
             if  (++ $recursive_counter  > 1000) {  
                 die ( 'possible deep recursion attack' );  
             }  
             foreach  ( $array  as  $key  =>  $value ) {  
                 if  ( is_array ( $value )) {  
                     arrayRecursive( $array [ $key ],  $function $apply_to_keys_also );  
                 else  {  
                     $array [ $key ] =  $function ( $value );  
                 }  
            
                 if  ( $apply_to_keys_also  &&  is_string ( $key )) {  
                     $new_key  $function ( $key );  
                     if  ( $new_key  !=  $key ) {  
                         $array [ $new_key ] =  $array [ $key ];  
                         unset( $array [ $key ]);  
                     }  
                 }  
             }  
             $recursive_counter --;  
         }  
     //解码  
     $db  new  DB();  
     $content  $_POST [ 'content' ];  
         $content  = iconv( "utf-8" , "gbk" , $content );  
     $name  $_POST [ 'name' ];  
         $name  = iconv( "utf-8" , "gbk" , $name );  
     $sql  "select * from `advice` order by time desc limit 20" ;  
     $result  $db ->select( $sql );  
     if  (! count ( $result )){  
         $ret [ 'success' ] =  "false" ;  
         $ret [ 'msg' ] =  "no message record" ;  
         $json  = json_encode( $ret );  
         echo  $json ;  
         exit ;  
     }  
     $i  = 0;  
         foreach  ( $result  as  $val ){  
             $ret [ 'data' ][ $i ][ 'remarks' ] = iconv( "gbk" , "utf-8" , $val [ 'remarks' ]);  
         $ret [ 'data' ][ $i ][ 'name' ] = iconv( "gbk" , "utf-8" , $val [ 'name' ]);  
             $ret [ 'data' ][ $i ][ 'time' ] = iconv( "gbk" , "utf-8" , $val [ 'time' ]);  
             $ret [ 'data' ][ $i ][ 'content' ] = iconv( "gbk" , "utf-8" , $val [ 'content' ]);  
         $i ++;     
     }  
     $ret [ 'success' ] =  "true" ;  
     $ret [ 'msg' ] =  "receiver message success" ;  
         $json  = JSON( $ret );  
     echo  $json ;  
     exit ;  
?>

与前面的服务器代码有所不同的是,这段代码在前面多了两个函数,有什么用呢?首先说的是,服务器在获得手机的请求成功之后将一大堆的数据经过json打包发给手机,但是,json是不支持中文的,所以如果需要传输中文的话必须经过前面两个函数进行编码才能传输。最后传给手机的$json变量其实就是一个二维键值数据,只要手机那边经过合理的解析即可。数据库请求成功之后的返回值result其实就是一个二维数组,通过一个类似for循环的foreach函数将数据获取下来之后经过json打包发给手机端。

手机端实现:

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
List<Map<String,Object>>  listiterms= new  ArrayList<Map<String,Object>>();  
HashMap<String, Object>  hashmap= new  HashMap<String,Object>();  
String result =  null ;                             
HttpClient httpClient =  new  DefaultHttpClient();                
//这里是你与服务器交互的地址  
String validateUrl =  "http://" ;                 
//设置读取超时  
httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,  5000 );                
//设置读取超时  
httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT,  5000 );                 
HttpPost httpRequst =  new  HttpPost(validateUrl);                
//准备传输的数据  
List<BasicNameValuePair> params =  new  ArrayList<BasicNameValuePair>();     
params.add( new  BasicNameValuePair( "content" "example" ));  
params.add( new  BasicNameValuePair( "name" "zhangsan" ));                                           
try  
{       
     //发送请求  
     httpRequst.setEntity( new  UrlEncodedFormEntity(params, HTTP.UTF_8));  
     //得到响应  
     HttpResponse response = httpClient.execute(httpRequst);                           
     //返回值如果为200的话则证明成功的得到了数据  
     if (response.getStatusLine().getStatusCode() ==  200 )  
     {  
         StringBuilder builder =  new  StringBuilder();                                    
         //将得到的数据进行解析  
         BufferedReader buffer =  new  BufferedReader( new  InputStreamReader(response.getEntity().getContent()));                   
         for (String s =buffer.readLine(); s!=  null ; s = buffer.readLine()){  
             builder.append(s);                                                
         }  
         //得到Json对象  
         JSONObject jsonObject   =  new  JSONObject(builder.toString());  
         //通过得到键值对的方式得到值  
         result = jsonObject.getString( "success" ); //判断时候获得数据  
         if (result.equals( "true" )){  
             //得到json数据  
             String data = jsonObject.getString( "data" );    
             //将json数据进行解析  
             JSONArray arr =  new  JSONArray(data);  
             int  i= 0 ;  
             //循环解析json数组,得到一个需要的键-值变量  
             for  ( i =  0 ; i < arr.length(); i++) {   
                 Map<String,Object> map= new  HashMap<String,Object>();  
                 JSONObject temp = (JSONObject) arr.get(i);     
                 map.put( "remarks" , temp.getString( "remarks" ));  
                 map.put( "name" , temp.getString( "name" ));  
                 Log.e( "innername" , temp.getString( "name" ));  
                 map.put( "content" , temp.getString( "content" ));  
                 map.put( "time" , temp.getString( "time" ));                                              
                 listiterms.add(map);                
             }                                        
         } else {      
             //没有数据  
             hashmap.put( "remarks" "no_data" );  
             listiterms.add(hashmap);  
         }  
                 
     else {  
         //连接失败  
         hashmap.put( "remarks" "connect_erro" );  
         listiterms.add( hashmap);   
     }  
catch  (Exception e) {    
     //连接异常  
     hashmap.put( "remarks" "exception" );  
     listiterms.add(hashmap);   
}

与登陆代码不同的是这里多了json数据解析,将二维键值数组存储到List<Map<String,Object>>中,具体怎么用这个结构这里就不多提了。与前面一样的是必须新开线程处理这些耗时的操作。

 


本文转自Work Hard Work Smart博客园博客,原文链接:http://www.cnblogs.com/linlf03/p/4660830.html,如需转载请自行联系原作者

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
5月前
|
PHP Android开发
android通过http上传文件,服务器端用php写(原创)
android通过http上传文件,服务器端用php写(原创)
57 4
|
19天前
|
JavaScript 安全 Java
谈谈UDP、HTTP、SSL、TLS协议在java中的实际应用
下面我将详细介绍UDP、HTTP、SSL、TLS协议及其工作原理,并提供Java代码示例(由于Deno是一个基于Node.js的运行时,Java代码无法直接在Deno中运行,但可以通过理解Java示例来类比Deno中的实现)。
45 1
|
5月前
|
JSON Java 数据安全/隐私保护
java中的http请求的封装(GET、POST、form表单、JSON形式、SIGN加密形式)
java中的http请求的封装(GET、POST、form表单、JSON形式、SIGN加密形式)
414 1
|
5月前
|
JSON Android开发 数据格式
android与Web服务器交互时的cookie使用-兼谈大众点评数据获得(原创)
android与Web服务器交互时的cookie使用-兼谈大众点评数据获得(原创)
77 2
|
5月前
|
监控 Unix 应用服务中间件
Android-音视频学习系列-(八)基于-Nginx-搭建(rtmp、http)直播服务器
Android-音视频学习系列-(八)基于-Nginx-搭建(rtmp、http)直播服务器
|
5月前
|
安全 Android开发
Android之OKHttp基本使用和OKHttp发送https请求安全认证
Android之OKHttp基本使用和OKHttp发送https请求安全认证
149 0
|
3月前
|
弹性计算 Linux 网络安全
使用阿里云服务器迁移中心SMC将其他云平台业务迁移至阿里云教程参考
现在越来越多的个人和企业用户选择将其他云平台或者服务商的业务迁移到阿里云,但是如何快速且安全完成迁移是很多用户比较关注的问题,我们可以选择使用阿里云提供的服务器迁移中心(Server Migration Center,简称SMC),这个产品是阿里云提供给您的迁移平台,专注于提供能力普惠、体验一致、效率至上的迁移服务,满足您在阿里云的迁移需求。本文为大家展示使用阿里云服务器迁移中心SMC将其他云平台业务迁移至阿里云的教程,以供参考。
使用阿里云服务器迁移中心SMC将其他云平台业务迁移至阿里云教程参考
|
3月前
|
安全 网络协议 Java
Java中的网络通信:HTTP详解
Java中的网络通信:HTTP详解
|
4月前
|
安全 网络协议 算法
Android网络基础面试题之HTTPS的工作流程和原理
HTTPS简述 HTTPS基于TCP 443端口,通过CA证书确保服务器身份,使用DH算法协商对称密钥进行加密通信。流程包括TCP握手、证书验证(公钥解密,哈希对比)和数据加密传输(随机数加密,预主密钥,对称加密)。特点是安全但慢,易受特定攻击,且依赖可信的CA。每次请求可能复用Session ID以减少握手。
60 2
|
4月前
|
移动开发 Java
Java Socket编程 - 基于Socket实现HTTP下载客户端
Java Socket编程 - 基于Socket实现HTTP下载客户端
33 1