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>>中,具体怎么用这个结构这里就不多提了。与前面一样的是必须新开线程处理这些耗时的操作。
Android中实现java与PHP服务器(基于新浪云免费云平台)http通信详解的更多相关文章
-
Android中滑屏实现----手把手教你如何实现触摸滑屏以及Scroller类详解
前言: 虽然本文标题的有点标题党的感觉,但无论如何,通过这篇文章的学习以及你自己的实践认知,写个简单的滑屏小 Demo还是just so so的. 友情提示: 在继续往下面读之前,希望您对以下知识点 ...
-
android中在java代码中设置Button按钮的背景颜色
android中在java代码中设置Button按钮的背景颜色 1.设置背景图片,图片来源于drawable: flightInfoPanel.setBackgroundDrawable(getRes ...
-
基于Java的打包jar、war、ear包的作用与区别详解
本篇文章,小编为大家介绍,基于Java的打包jar.war.ear包的作用与区别详解.需要的朋友参考下 以最终客户的角度来看,JAR文件就是一种封装,他们不需要知道jar文件中有多少个.cla ...
-
Java中对象、对象引用、堆、栈、值传递以及引用传递的详解
Java中对象.对象引用.堆.栈.值传递以及引用传递的详解 1.对象和对象引用的差别: (1).对象: 万物皆对象.对象是类的实例. 在Java中new是用来在堆上创建对象用的. 一个对象能够被多个引 ...
-
[PXE] Linux(centos6)中PXE 服务器搭建,PXE安装、启动及PXE理论详解
[PXE] Linux(centos6)中PXE 服务器搭建,PXE安装.启动及PXE理论详解 本篇blog主要讲述了[PXE] linux(centos)PXE无盘服务器搭建,安装,启动及pxe协议 ...
-
Android Socket通信详解
一.Socket通信简介 Android与服务器的通信方式主要有两种,一是Http通信,一是Socket通信.两者的最大差异在于,http连接使用的是“请求—响应方式”,即在请求时建立连接通道,当客 ...
-
[转帖]基于VIM漏洞CVE-2019-12735的VIM宏后门病毒详解
基于VIM漏洞CVE-2019-12735的VIM宏后门病毒详解 不明觉厉 只要是人做的东西 就会有bug 就会有安全问题 就看发现bug 或者是发现安全问题 有没有收益了 会用linux的都是比较熟 ...
-
Java生鲜电商平台-优惠券系统设计详解
Java生鲜电商平台-优惠券系统设计详解 优惠券作为电商最常用的营销手段,对于商家而言可以起到拉新.促活.提高转化的作用,对用户而言也可以获得实惠,今天就来谈谈优惠券系统的设计逻辑. 我对于优惠券系统 ...
-
《手把手教你》系列技巧篇(三十六)-java+ selenium自动化测试-单选和多选按钮操作-番外篇(详解教程)
1.简介 前边几篇文章是宏哥自己在本地弄了一个单选和多选的demo,然后又找了网上相关联的例子给小伙伴或童鞋们演示了一下如何自动化测试,这一篇宏哥在网上找了一个问卷调查,给小伙伴或童鞋们来演示一下.上 ...
随机推荐
-
Competing Consumers Pattern (竞争消费者模式)
Enable multiple concurrent consumers to process messages received on the same messaging channel. Thi ...
-
【转】【MySql】Waiting for table metadata lock原因分析
MySQL在进行alter table等DDL操作时,有时会出现Waiting for table metadata lock的等待场景.而且,一旦alter table TableA的操作停滞在Wa ...
-
7zip self-extracted executable: To extract file to specific directory
1) Install 7-zip (7zS.sfx will be installed to C:\Program Files\7-Zip): http://7zsfx.solta.ru/en/ 2) ...
-
PLSQL 循环示例
<pre name="code" class="sql"><pre name="code" class="sql ...
-
Linux运维基础
一.服务器硬件 二.Linux的发展史 三.Linux的系统安装和配置 四.Xshell的安装和优化 五.远程连接排错 六.Linux命令初识 七.Linux系统初识与优化 八.Linux目录结构 九 ...
-
Dapp的PVP发模式--magic-maze-2d游戏解读
前言: 未来基于Dapp的游戏可能会多起来吧, 尤其是博彩类游戏, 由于区块链匿名特性, 加之数字货币不受国家监控, 几乎成了一个法外之地. 大量游戏团队都往之涌入. 今天讲讲当前Dapp的一种游戏模 ...
-
索引堆(Index Heap)
首先我们先来看一个由普通数组构建的普通堆. 然后我们通过前面的方法对它进行堆化(heapify),将其构建为最大堆. 结果是这样的: 对于我们所关心的这个数组而言,数组中的元素位置发生了改变.正是因为 ...
-
bzoj4671: 异或图
bzoj4671: 异或图 Description 定义两个结点数相同的图 G1 与图 G2 的异或为一个新的图 G, 其中如果 (u, v) 在 G1 与 G2 中的出现次数之和为 1, 那么边 ( ...
-
Linux lsof 命令
lsof(list open files)是一个查看进程打开的文件的工具. 在 linux 系统中,一切皆文件.通过文件不仅仅可以访问常规数据,还可以访问网络连接和硬件.所以 lsof 命令不仅可以查 ...
-
用U盘制作启动盘后空间变小的恢复方法
先把u盘插好, 运行cmd(按住键盘左下角第二个windows键的同时按R), 输入diskpart,回车, (此时可以再输入list disk,回车,能看到这台电脑的所有磁盘大致情况,u盘一般是磁盘 ...