在前面两篇博客《Android之Http网络编程(一)》、《Android之Http网络编程(二)》中,简单的介绍了对网页的请求和客户端与服务端的简单的参数交互。那么,这一篇博客就来认识一下Android客户端获取服务端返回的数据。

大家都知道客户端与服务端的交互大体过程如下:

  • Android客户端向服务器发出请求。
  • 服务端接收请求并响应。
  • 服务端返回数据给客户端。

对于Android客户端来说,最重要的也就莫过于获取服务端返回的数据来展示了。

那么,首先我们要知道服务端返回的数据格式是什么?(因为对于服务端返回的数据内容,我们只需要完完整整呈现即可。因此,更重要的就是数据的格式了,因为不同的数据格式获取数据的方式会稍有不同。)最常见的数据格式有:JSON和XML两种。(这两种数据格式的优劣,请参考文章《JSON与XML的区别比较》)对于后者,XML的解析方式有三种:pull解析、sax解析、dom解析。个人认为PULL解析最简单,详情请看另一篇博客《Android XML解析》(这里只有PULL解析,找时间我把另外两种也写上)

这篇博客,我们重点来学习从服务器端返回JSON格式的数据。

JSON格式的数据分为两种,一种是JSON对象,另一种是JSON对象数组。

下面我们分别来实现:

我们先实现获取JSON对象。

我们将下面的JSON字符串复制到一个新建的文本文件(就是记事本打开的那个)中,取名为“testjson”,将后缀改为.json。

{"PubId":"001","PubTitle":"testContent","PubTime":"2014-9-30 12:01:13","PubAuthor":"Admin"}

并将该文件放在Tomcat的文件路径下(我放的路径是E:\编程软件及工具\tomcat\apache-tomcat-7.0.55\webapps\ROOT\mytest),对Tomcat不熟悉的话请看博客《Android中Tomcat的简单配置和使用》。

放在Tomcat文件下后,启动Tomcat服务,在在浏览器中输入访问地址:http://127.0.0.1:8080/mytest/testjson.json

得到如下结果:

这就是通过浏览器查看我们需要获得的JSON格式的数据。

下面我们用代码来实现:

(方便起见,直接在启动Activity时就访问,并输出数据返回结果)

public class MainActivity extends Activity {

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getData();
} private void getData() {
new Thread(new Runnable() {
@Override
public void run() {
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(
"http://192.168.1.101:8080/mytest/testjson.json"); HttpResponse response;
try {
response = client.execute(get);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
String str = EntityUtils.toString(response.getEntity());
//将返回的字符串转换成JSON对象
JSONObject json = new JSONObject(str);
//获取JSON对象的标签关键字对应的值
String id = json.getString("PubId");
String title = json.getString("PubTitle");
String author = json.getString("PubAuthor");
String time = json.getString("PubTime");
//输出JSON对象的值
System.out.println("id:" + id);
System.out.println("title:" + title);
System.out.println("author:" + author);
System.out.println("time:" + time);
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start(); } }

注意:在Android4.0之后不能在主线程中访问网络,记得在清单文件中添加网络访问权限:<uses-permission android:name="android.permission.INTERNET" />

运行程序,结果如下:

这样,我们就获取到了从服务器端返回的JSON格式的数据了,是不是很简单。

接下来我们实现获取JSON对象数组。其实和上面获取JSON对象相似。

将JSON对象数据源换成JSON对象数组,如下:

[{"PubId":"001","PubTitle":"test1","PubTime":"2014-9-30 12:01:13","PubAuthor":"Admin"},{"PubId":"002","PubTitle":"test2","PubTime":"2014-9-31 12:01:13","PubAuthor":"Admin"},{"PubId":"003","PubTitle":"test3","PubTime":"2014-9-31","PubAuthor":"Admin"}]

接下来的操作和获取JSON对象相同。

我们在浏览器中查看:

获取json对象数组的代码实现:

private void getData() {
new Thread(new Runnable() {
@Override
public void run() {
HttpClient client = new DefaultHttpClient();
HttpGet get = new HttpGet(
"http://192.168.1.101:8080/mytest/testjsonArray.json"); HttpResponse response;
try {
response = client.execute(get);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
String str = EntityUtils.toString(response.getEntity());
// 将返回的字符串转换成JSON对象数组
JSONArray jsonArray = new JSONArray(str);
for (int i = 0; i < jsonArray.length(); i++) {
                //获取JSON数组中的某一具体JSON对象
JSONObject json = jsonArray.getJSONObject(i);
// 获取JSON对象的标签关键字对应的值
String id = json.getString("PubId");
String title = json.getString("PubTitle");
String author = json.getString("PubAuthor");
String time = json.getString("PubTime");
// 输出JSON对象的值
System.out.println("id:" + id);
System.out.println("title:" + title);
System.out.println("author:" + author);
System.out.println("time:" + time);
System.out
.println("----------------华丽的分割线---------------------");
} }
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start(); }

运行结果如下:

OK,现在获取JSON格式数据的常用操作就完了。

其实,如果是JSON的话,也可以使用第三方包来解析并获取数据,更加方便快捷。比如:Gson包(需要有相对应的实体类)。

GSON的下载地址:https://code.google.com/p/google-gson/downloads/list?can=1&q

打开网址后下载2.2.4版(目前最新版)

下载后解压压缩包,有如下文件:

其中gson-2.2.4.jar就是我们所需要的。将其添加到项目的libs文件夹下,并添加到项目中。

设置实体类为:

public class Entity {
//字段应与返回的JSON格式数据的关键字相同
private String PubId;
private String PubTitle;
private String PubTime;
private String PubAuthor;
public String getPubId() {
return PubId;
}
public void setPubId(String pubId) {
PubId = pubId;
}
public String getPubTitle() {
return PubTitle;
}
public void setPubTitle(String pubTitle) {
PubTitle = pubTitle;
}
public String getPubTime() {
return PubTime;
}
public void setPubTime(String pubTime) {
PubTime = pubTime;
}
public String getPubAuthor() {
return PubAuthor;
}
public void setPubAuthor(String pubAuthor) {
PubAuthor = pubAuthor;
} }

以上面实例返回的json格式的数据为例,如果返回的是一个JSON对象,则需要代码:

     Gson gson=new Gson();
Entity entity=gson.fromJson(str, Entity.class);
Log.e("Gson", entity.getPubId());
Log.e("Gson", entity.getPubTitle());
Log.e("Gson", entity.getPubAuthor());
Log.e("Gson", entity.getPubTime());

即可打印出获取到的JSON对象数据。

如果返回的是一个JSON对象数组,则代码为:

    Gson gson=new Gson();
//获取一个JSON对象数组
List<Entity> entitylist=gson.fromJson(str, new TypeToken<List<Entity>>(){}.getType());
for(Entity entity:entitylist){
Log.d("Gson jsonArray", entity.getPubId());
Log.d("Gson jsonArray", entity.getPubTitle());
Log.d("Gson jsonArray", entity.getPubAuthor());
Log.d("Gson jsonArray", entity.getPubTime());
}

即可打印出返回的JSON对象数组。

public class MainActivity extends Activity {

    @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
testGson();
} public void testGson() {
new Thread(new Runnable() {
private String str; @Override
public void run() {
HttpClient client = new DefaultHttpClient();
// 设置路径
// HttpPost request = new HttpPost(
// "http://172.27.35.9:8080/mytest/testjson.json");
HttpPost request = new HttpPost(
"http://172.27.35.9:8080/mytest/testjsonArray.json");
HttpResponse response; try {
response = client.execute(request);
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { str = EntityUtils.toString(response.getEntity(),"GBK").trim();
parseToJson(str);
} else {
str = "请求失败";
}
System.out.println(str);// 打印返回结果 } catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
}).start();
} protected void parseToJson(String str) {
Gson gson=new Gson();
//获取一个JSON对象数组
List<Entity> entitylist=gson.fromJson(str, new TypeToken<List<Entity>>(){}.getType());
for(Entity entity:entitylist){
Log.d("Gson jsonArray", entity.getPubId());
Log.d("Gson jsonArray", entity.getPubTitle());
Log.d("Gson jsonArray", entity.getPubAuthor());
Log.d("Gson jsonArray", entity.getPubTime());
} //获取一个JSON对象
// Gson gson=new Gson();
// Entity entity=gson.fromJson(str, Entity.class);
// Log.e("Gson", entity.getPubId());
// Log.e("Gson", entity.getPubTitle());
// Log.e("Gson", entity.getPubAuthor());
// Log.e("Gson", entity.getPubTime()); } }

运行程序,结果如下:

获取到的一个JSON对象:

获取到的JSON对象数组:

获取JSON格式数据的操作,总体上还是比较简单,就不附上DEMO了。

注意:如果要将获取到的网络数据添加到界面上,需要使用到Android的异步消息处理机制。因为对网络的操作属于耗时操作,为了不阻塞主线程我们一般新开一个新的线程来执行网络请求。然而,只有主线程(即UI线程)可以更新界面,因此我们获取的网络数据通过异步消息处理机制从子线程传递到主线程,并最终实现更新UI。

对异步消息处理机制不熟悉的话 ,可以参考另外两篇博文《Android线程与异步消息处理机制》、《Android 在子线程中更新UI》。

Android之Http网络编程(三)的更多相关文章

  1. Android系列之网络(三)----使用HttpClient发送HTTP请求(分别通过GET和POST方法发送数据)

    ​[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...

  2. Android之Http网络编程(一)

    Android应用作为一个客户端程序绝大部分都是需要进行网络请求和访问的,而http通信是一种比较常见并常用的通信方式. 在Android中http网络编程中有两种实现方式,一种是使用HttpURLC ...

  3. Linux网络编程(三)

    Linux网络编程(三) wait()还是waitpid() Linux网络编程(二)存在客户端断开连接后,服务器端存在大量僵尸进程.这是由于服务器子进程终止后,发送SIGCHLD信号给父进程,而父进 ...

  4. Android应用开发-网络编程(一)(重制版)

    网络图片查看器 1. 确定图片的网址 2. 发送http请求 URL url = new URL(address); // 获取客户端和服务器的连接对象,此时还没有建立连接 HttpURLConnec ...

  5. Linux 网络编程三(socket代码详解)

    //网络编程客户端 #include <stdio.h> #include <stdlib.h> #include <string.h> #include < ...

  6. Android应用开发-网络编程(一)

    网络图片查看器 1. 确定图片的网址 2. 发送http请求 URL url = new URL(address); // 获取客户端和服务器的连接对象,此时还没有建立连接 HttpURLConnec ...

  7. Android之Http网络编程(四)

    前面几篇博文简单的介绍了一些常见的Http的操作,这些操作几乎都是在新开的线程中进行的网络请求,并在日志中打印出获取到的网络数据.那么,问题来了!(呃~感觉下一句是蓝翔有木有?)如何在把获取到的网络数 ...

  8. Android中的网络编程

    谷歌在Android6.0之后就废弃了使用HttpClinet进行网络连接.所以,这里需要重点学习的是通过HttpUrlConnect进行网络连接. String path="这里是你想要的 ...

  9. Java高并发网络编程(三)NIO

    从Java 1.4开始,Java提供了新的非阻塞IO操作API,用意是替代Java IO和Java Networking相关的API. NIO中有三个核心组件: Buffer缓冲区 Channel通道 ...

随机推荐

  1. 洛谷 P1169 [ZJOI2007]棋盘制作

    2016-05-31 14:56:17 题目链接: 洛谷 P1169 [ZJOI2007]棋盘制作 题目大意: 给定一块矩形,求出满足棋盘式黑白间隔的最大矩形大小和最大正方形大小 解法: 神犇王知昆的 ...

  2. Java之文件的随机访问和读写RandomAccessFile

    package FileDemo; import java.io.IOException; import java.io.RandomAccessFile; public class RandomAc ...

  3. SHH入门:Spring框架简介

    (1)Spring 七大模块 核心容器:核心容器提供Spring 框架的基本功能.核心容器的主要组件是 BeanFactory,它是工厂模式的实现.BeanFactory 使用控制反转 (IOC) 模 ...

  4. .NET设计模式(1):开篇

    转载:http://terrylee.cnblogs.com/archive/2005/12/09/293465.html .NET设计模式开篇 --.NET设计模式系列之一 Terrylee,200 ...

  5. 【Away3D代码解读】(二):渲染核心流程(简介、实体对象收集)

    我之前解析过Starling的核心渲染流程,相比Away3D而言Starling真的是足够简单,不过幸运的是两者的渲染流程是大体上相似的:Starling的渲染是每帧调用Starling类中的rend ...

  6. ThinkPHP CURD方法盘点:where方法

    今天来给大家讲下查询最常用但也是最复杂的where方法,where方法也属于模型类的连贯操作方法之一,主要用于查询和操作条件的设置.where方法的用法是ThinkPHP查询语言的精髓,也是Think ...

  7. Tomcat部署web应用的三种方式

    原文:http://my.oschina.net/sunchp/blog/90235 一:相关概念 CATALINA_HOME:tomcat安装目录 CATALINA_BASE:tomcat工作目录 ...

  8. [React Fundamentals] Composable Components

    To make more composable React components, you can define common APIs for similar component types. im ...

  9. ConvertHelper与泛型集合

    在机房重构时.我们常常会用到ConvertHelper. 它把从数据库中查询到的dateTable(也是一个暂时表)转化为泛型,然后再填充到DataGridView控件中. ConvertHelper ...

  10. 【linux c learn 之stat】获取文件的属性

    NAME stat 获取文件属性 这个函数位于<sys/stat.h>头文件里 函数原型: int stat(const char *path, struct stat *buf); 參数 ...