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

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
云数据库 RDS MySQL,高可用系列 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,如需转载请自行联系原作者

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
打赏
0
0
0
0
51
分享
相关文章
Unity开发中使用UnityWebRequest从HTTP服务器下载资源。
总之,UnityWebRequest就是游戏开发者手中的万能钓鱼竿,既可以获取文本数据,也能钓上图片资源,甚至是那声音的涟漪。使用UnityWebRequest的时候,你需要精心准备,比如确定URL、配置请求类型和头信息;发起请求;巧妙处理钓获的数据;还需要机智面对网络波澜,处理各种可能出现的错误。按照这样的过程,数据的钓取将会是一次既轻松愉快也效率高效的编程钓鱼之旅。
59 18
网关服务器配置指南:实现自动DHCP地址分配、HTTP服务和SSH无密码登录。
哇哈哈,道具都准备好了,咱们的魔术秀就要开始了。现在,你的网关服务器已经魔法满满,自动分配IP,提供网页服务,SSH登录如入无人之境。而整个世界,只会知道效果,不会知道是你在幕后操控一切。这就是真正的数字世界魔法师,随手拈来,手到擒来。
61 14
443端口:HTTPS通信的安全基石
作为互联网安全的基石,443端口通过加密与认证机制,保护了数十亿用户的隐私与数据完整性。无论是开发者、运维人员还是普通用户,理解其原理与作用都至关重要。在享受便利的同时,也需时刻关注安全实践,防范潜在风险。
273 12
|
3月前
|
使用Python实现multipart/form-data文件接收的http服务器
至此,使用Python实现一个可以接收 'multipart/form-data' 文件的HTTP服务器的步骤就讲解完毕了。希望通过我的讲解,你可以更好地理解其中的逻辑,另外,你也可以尝试在实际项目中运用这方面的知识。
193 69
使用curl命令在服务器上执行HTTP请求
总的来说,curl是一个非常强大的工具,它可以让你在命令行中发送各种类型的HTTP请求。通过学习和实践,你可以掌握这个工具,使你的工作更加高效。
180 30
使用HTTP POST协议将本地压缩数据发送到服务器
总的来说,使用HTTP POST协议将本地压缩数据发送到服务器是一个涉及多个步骤的过程,包括创建压缩文件,设置HTTP客户端,发送POST请求,以及服务器端的处理。虽然这个过程可能看起来复杂,但一旦你理解了每个步骤,就会变得相对简单。
110 19
HFS-快速创建HTTP服务器
鉴于HFS的操作简便和方便快捷,它在满足快速,临时的文件分享和传输需求上,能够发挥出巨大的作用。只要明确了以上的安全警告,并做好了必需的安全设置,HFS将是一款实用的HTTP服务器工具。
170 9
网络通讯技术:HTTP POST协议用于发送本地压缩数据到服务器的方案。
总的来说,无论你是一名网络开发者,还是普通的IT工作人员,理解并掌握POST方法的运用是非常有价值的。它就像一艘快速,稳定,安全的大船,始终为我们在网络海洋中的冒险提供了可靠的支持。
106 22
HTTP代理服务器对速度提升有何作用?
在信息化时代,网络成为生活不可或缺的一部分。HTTP代理服务器位于客户端与服务器之间,通过数据压缩、缓存机制和路由优化等方式,有效提高数据传输速度并保护个人信息安全。使用91HTTP等工具,用户可在业务需求中获得更快更安全的网络体验。
109 4
解析HTTP代理服务器不稳定致使掉线的关键原因
随着数字化发展,网络安全和隐私保护成为核心需求。HTTP代理服务器掉线原因主要包括:1. 网络问题,如本地网络不稳定、路由复杂;2. 服务器质量差、IP资源不稳定;3. 用户配置错误、超时或请求频率异常;4. IP失效或协议不兼容。这些问题会影响连接稳定性。
165 8
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等

登录插画

登录以查看您的控制台资源

管理云资源
状态一览
快捷访问