Android网络之数据解析----使用Google Gson解析Json数据

本文涉及的产品
云解析 DNS,旗舰版 1个月
云解析DNS,个人版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介:

【正文】

文章回顾: Android网络之数据解析----SAX方式解析XML数据

一、Json数据的介绍                                                                                                                

Json(JavaScript Object Notation) 是一种轻量级的数据交换格式。它基于JS的一个子集。 Json采用完全独立于语言的文本格式,这使得Json成为理想的数据交换语言。易于人阅读和编写,同时也易于机器解析和生成。

Json简单来说就是JS中的对象和数组,所以Json也存在两种结构:对象、数组

1、Json对象:

含义:是“‘键/值’对”的无序集合

格式:Json对象定义在花括号“{}”内,以Key:value键值对的形式存放数据,多个键值对之间使用逗号“,”隔开,多个数据使用分号“;”隔开。

举例:

{
    “name”:”jackson”,
    “age”:100
}

注:不同的语言中,它被理解为对象(object)、纪录(record)、结构(struct)、字典(dictionary)、哈希表(hash table)、有键列表(keyed list)、或者关联数组 (associative array)。

2、Json数组:

含义:数组是值(value)的有序集合

格式:Json数组定义在方括号“[]”内,以字符串的形式存放数据,值之间使用逗号“,”隔开,多个数据使用分号“;”隔开。

举例:

复制代码
1 {
2     “students”:
3     [
4         {“name”:”jackson”,“age”:100},
5         {“name”:”michael”,”age”:51}
6     ]
7 }
复制代码

一般情况下,我们用jsp+servlet作服务器端,生成Json的数据;然后在客户端解析Json的数据

解析JSON数据, 首先需要明确待解析的是JSON Object还是JSON array, 然后需要确定采用哪种解析技术。android平台上一般有以下几种解析技术可供选择:android内置的org.json包(Json),google的开源库GSON,还有一些第三方的开源库如Jackson、FastJson等。我们今天来学习一下使用开源库GSON来解析Json数据。

 

二、Gson解析Json的基本思路                                                                                                     

首先在服务器端,将服务器端的Person对象通过Gson解析成json的字符串;然后在客户端,通过Gson类将json的字符串还原为Person对象。Gson支持任意复杂Java对象包括没有源代码的对象。

如果我们将Person对象看成一个泛型,那么不管服务器端的Person对象是什么类型,都可以解析出来。

Gson库神奇在哪里呢?如果解析的是Json对象,它主要就是可以将一段Json格式的字符串自动映射成一个对象,从而不需要我们再手动去编写代码进行解析了。比如一段Json格式的数据如下:

{"name":"tom","age":20} 

那我们就可以写一个Person类,并加入name和age这两个字段,只需要简单地调用如下代码就可以将Json数据自动解析成一个Person对象了:

Gson gson = new Gson();

Person person = gson.fromJson(jsonData,Person.class); 

如果解析的是Json对象数组,就要麻烦一点,需要借助Typetoken(官方提供的一种反射机制)将期望解析成的数据类型传入到fromJson()方法中,如下所示:

List<Person> people = gson.fromJson(jsonData, new TypeToken<List<Person>>().getType()); 

基本用法就是这样,我们现在来看一下具体的实现步骤吧。

 

三、Gson解析Json的步骤(代码实现)                                                                                           

现在通过一个示例程序来讲解一下SAX是怎么解析XML文件的,这个示例程序是运行在Android平台上的,为了模拟真实情况,在tomcat服务器上放置了一个两个静态的XML文件:person.json和perons.json,前者代表对象,后者代表对象数组。即在D:\apache-tomcat-8.0.14\webapps\ROOT目录中新建文件person.json和perons.json.

person.json的内容如下:

{
"id": 1,
"name": "smyhvae",
"address":"成都"
} 

需要特别注意的是,要注意json文件的格式。例如第4行的后面不要有逗号(我就是因为这个低级错误,导致后来调试程序,调了半个多小时才发觉)

persons.json的内容如下:

复制代码
[{
    "id": 1,
    "name": "smyhvae",
    "address":"成都"
},
{
    "id": 2,
    "name": "许嵩",
    "address":"合肥"
}] 
复制代码

注:关于tomcat服务器的配置,如果不清楚的话,请参照本人另外一篇博客的第三段:JavaWeb学习(一)----JSP简介及入门(含Tomcat的使用)

因为我电脑的IP地址是192.168.1.112。现在我们在浏览器输入http://192.168.1.112:8080/person.json和http://192.168.1.112:8080/persons.json,显示效果如下:

62c20a5a-d379-46f8-bd1c-daf38c4e4769

6d9e0f81-9f9f-4360-a71f-7f0193a49b02

上方的中文出现了乱码,不过没关系,在稍后解析的时候是不会出现这种情况的。

现在我们需要做的是:通过Android程序去获取并解析这段Json数据。因为是Android程序,所以别忘了赋予其访问网络的权限

整个工程文件的目录结构如下:

e51039d5-853b-416f-b73f-05658ead3455

(1)下载并添加Gson的jar包:

下载地址:https://code.google.com/p/google-gson/  网页界面如下:

812a5333-9666-4300-ac76-e13c5a0692fe

点击上图中的红框部分,出现如下界面:

83df9ed0-fde0-45cb-9119-01a5682afe3d

上图中的红框部分gson-2.3.jar就是我们需要下载的内容,如果需要帮助文档的话,也可以把箭头处的文件下载下来。然后把gson-2.3.jar拷贝到工程文件的libs目录下,Gson库就自动添加到项目中去了。

(2)新建工类HttpUtils通过URLHttpConnection获取服务器上的XML流:返回的是字符串

复制代码
 1 package com.example.android_gson_json.http;
 2 
 3 import java.io.ByteArrayOutputStream;
 4 import java.io.IOException;
 5 import java.io.InputStream;
 6 import java.net.HttpURLConnection;
 7 import java.net.URL;
 8 
 9 
10 //通过HttpURLCnnection获取链接里的数据,放到流里,然后把流里面的数据转换为字符串(借鉴于:老罗老版本1-04)
11 public class HttpUtils {
12 
13     public HttpUtils() {
14         // TODO Auto-generated constructor stub
15     }
16 
17     public static String getJsonContent(String url_path) {
18         try {
19             URL url = new URL(url_path);
20             HttpURLConnection connection = (HttpURLConnection) url
21                     .openConnection();
22             connection.setConnectTimeout(3000);
23             connection.setRequestMethod("GET");
24             connection.setDoInput(true);
25             int code = connection.getResponseCode();
26             if (code == 200) {
27                 return changeInputStream(connection.getInputStream());
28             }
29         } catch (Exception e) {
30             // TODO: handle exception
31         }
32         return "";
33     }
34 
35     private static String changeInputStream(InputStream inputStream) {
36         // TODO Auto-generated method stub
37         String jsonString = "";
38         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
39         int len = 0;
40         byte[] data = new byte[1024];
41         try {
42             while ((len = inputStream.read(data)) != -1) {
43                 outputStream.write(data, 0, len);
44             }
45             jsonString = new String(outputStream.toByteArray());
46         } catch (IOException e) {
47             // TODO Auto-generated catch block
48             e.printStackTrace();
49         }
50         return jsonString;
51     }
52 }
复制代码

(3)【新建类Person】新建实体类Person,用于存放解析完成后的对象数据

复制代码
 1 package com.example.android_gson_json.domain;
 2 
 3 public class Person {
 4     private int id;
 5     private String name;
 6     private String address;
 7     public Person() {
 8         super();
 9     }
10     public Person(int id, String name, String address) {
11         super();
12         this.id = id;
13         this.name = name;
14         this.address = address;
15     }
16     public int getId() {
17         return id;
18     }
19     public void setId(int id) {
20         this.id = id;
21     }
22     public String getName() {
23         return name;
24     }
25     public void setName(String name) {
26         this.name = name;
27     }
28     public String getAddress() {
29         return address;
30     }
31     public void setAddress(String address) {
32         this.address = address;
33     }
34     @Override
35     public String toString() {
36         return "Person [id=" + id + ", name=" + name + ", address=" + address
37                 + "]";
38     }    
39     
40 }
复制代码

(4)【新建类GsonTools】真正用于解析Json数据

复制代码
 1 package com.example.android_gson_json.gson;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 
 6 import com.google.gson.Gson;
 7 import com.google.gson.reflect.TypeToken;
 8 
 9 public class GsonTools {
10 
11     public GsonTools() {
12         // TODO Auto-generated constructor stub
13     }
14 
15     //使用Gson进行解析Person
16     public static <T> T getPerson(String jsonString, Class<T> cls) {
17         T t = null;
18         try {
19             Gson gson = new Gson();
20             t = gson.fromJson(jsonString, cls);
21         } catch (Exception e) {
22             // TODO: handle exception
23         }
24         return t;
25     }
26     
27     
28     // 使用Gson进行解析 List<Person>
29     public static <T> List<T> getPersons(String jsonString, Class<T> cls) {
30         List<T> list = new ArrayList<T>();
31         try {
32             Gson gson = new Gson();
33             list = gson.fromJson(jsonString, new TypeToken<List<T>>() {
34             }.getType());
35         } catch (Exception e) {
36         }
37         return list;
38     }
39 
40 }
复制代码

上面有两个方法,分别用于解析Person对象、List嵌套的Person。如果还有更复杂的数据类型,以后再说吧~O(∩_∩)O~这里只需要注意关键的思路就行。

核心代码:19至20行、32至34行

(5)在MainActicity中实例化:即实例化需要访问的链接path并解析它

布局界面很简单,只有两个按钮控件,这里就不展示布局代码了。点击按钮后,触发点击事件,因为是Android4.0+,所以不能在主线程中访问网络,需要另起一个线程,这里使用Thread类。代码如下: 

复制代码
 1 package com.example.android_gson_json;
 2 
 3 import java.util.List;
 4 
 5 import android.app.Activity;
 6 import android.os.Bundle;
 7 import android.util.Log;
 8 import android.view.View;
 9 import android.view.View.OnClickListener;
10 import android.widget.Button;
11 
12 import com.example.android_gson_json.domain.Person;
13 import com.example.android_gson_json.gson.GsonTools;
14 import com.example.android_gson_json.http.HttpUtils;
15 
16 public class MainActivity extends Activity implements OnClickListener {
17 
18     private Button button1, button2;
19     private static final String TAG = "MainActivity";
20 
21     @Override
22     protected void onCreate(Bundle savedInstanceState) {
23         super.onCreate(savedInstanceState);
24         setContentView(R.layout.activity_main);
25 
26         button1 = (Button) this.findViewById(R.id.button1);
27         button2 = (Button) this.findViewById(R.id.button2);
28         button1.setOnClickListener(this);
29         button2.setOnClickListener(this);
30     }
31 
32     //点击按钮,开始使用Gson解析Json数据:Person对象、List嵌套的Person对象的集合
33     @Override
34     public void onClick(final View v) {
35         Thread thread = new Thread(new Runnable() {
36 
37             @Override
38             public void run() {
39                 switch (v.getId()) {
40                 case R.id.button1:
41                     String path = "http://192.168.1.112:8080/person.json";
42                     String jsonString = HttpUtils.getJsonContent(path);//从网络获取数据
43                     Person person = GsonTools.getPerson(jsonString, Person.class);//解析json数据
44                     Log.i(TAG, person.toString());
45                     break;
46                 case R.id.button2:
47                     String path2 = "http://192.168.1.112:8080/persons.json";
48                     String jsonString2 = HttpUtils.getJsonContent(path2);//从网络获取数据
49                     List<Person> list = GsonTools.getPersons(jsonString2, Person.class);//解析json数据
50                     Log.i(TAG, list.toString());
51                     break;
52                 }
53 
54             }
55         });
56         thread.start();
57 
58     }
59 
60 }
复制代码

核心代码:43行、49行

(6)添加网络权限:(这个千万不要忘记了)

<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.INTERNET"/> 

程序运行在模拟器上运行后,界面如下:

5568d68e-7a46-4414-973b-40024f1f39c2

分别点击这两个按钮,后台打印的日志如下:

abc4a572-4423-4ceb-afd7-700839babf93

在真机上运行的效果如下:

f420ae51-991c-4d9c-8c5b-ba096eb3c05b

说明Json数据解析成功,大功告成。

最后声明:

其实,如果是在模拟器上运行,即使不添加网络权限,也是没有关系的;但是,如果在真机上运行(前提是真机和电脑在同一个局域网),不添加网络权限,程序是绝对运行不了的,点击按钮,程序就会死掉,这个地方又耽误了我半个小时,罪过。

相关文章
|
18天前
|
Java 调度 Android开发
深入解析Android应用开发中的响应式编程与RxJava应用
在现代Android应用开发中,响应式编程及其核心框架RxJava正逐渐成为开发者的首选。本文将深入探讨响应式编程的基本概念、RxJava的核心特性以及如何在Android应用中利用RxJava提升代码的可读性和性能。 【7月更文挑战第7天】
|
9天前
|
网络协议 算法 程序员
提高网络稳定性的关键:TCP滑动窗口与拥塞控制解析
**TCP可靠传输与拥塞控制概要:** 小米讲解TCP如何确保数据可靠性。TCP通过分割数据、编号段、校验和、流量控制(滑动窗口)和拥塞控制(慢开始、拥塞避免、快重传、快恢复)保证数据安全传输。拥塞控制动态调整窗口大小,防止网络过载,提升效率。当连续收到3个相同ACK时执行快重传,快恢复避免剧烈波动。关注“软件求生”获取更多技术内容。
29 4
提高网络稳定性的关键:TCP滑动窗口与拥塞控制解析
|
2天前
|
安全 网络安全 数据安全/隐私保护
网络安全漏洞、加密技术与安全意识的深度解析
本文将深入探讨网络安全漏洞、加密技术以及安全意识的重要性和影响。我们将从网络安全漏洞的定义、类型及其产生的原因开始,然后详细解析加密技术的工作原理、种类及其在保护信息安全中的作用。最后,我们将讨论安全意识的重要性,以及如何通过提高公众的安全意识来防止网络攻击。
9 3
|
7天前
|
网络协议 程序员
TCP报文格式全解析:网络小白变高手的必读指南
**TCP报文格式详解摘要** 探索TCP,传输层的关键协议,提供可靠数据传输。报文含源/目的端口(标识应用),32位序号(跟踪字节顺序),确认序号(确认接收),4位首部长度,6位标志(URG, ACK, PSH, RST, SYN, FIN),窗口大小(流量控制),检验和(数据完整性),紧急指针(优先数据)及可变长选项(如MSS, 时间戳)。了解这些字段,能更好地理解TCP连接的建立、管理和数据交换。
22 3
|
11天前
|
SQL 安全 网络安全
网络安全与信息安全:从漏洞到防护的全方位解析
【7月更文挑战第14天】在数字时代的浪潮中,网络安全与信息安全成为维护社会稳定和保护个人隐私的关键。本文深入探讨了网络环境中常见的安全漏洞、先进的加密技术以及提升安全意识的有效策略。通过分析最新的网络攻击案例和防御手段,旨在为读者提供一套实用的网络安全知识体系,帮助公众和企业构建更为坚固的信息安全防线。
|
12天前
|
域名解析 存储 网络协议
一次读懂网络分层:应用层到物理层全解析
**网络五层模型简介:** 探索网络服务的分层结构,从应用层开始,包括HTTP(网页传输)、SMTP(邮件)、DNS(域名解析)和FTP(文件传输)协议。传输层涉及TCP(可靠数据传输)和UDP(高效但不可靠)。网络层由IP(路由数据包)、ICMP(错误报告)和路由器构成。数据链路层处理MAC地址和帧传输,物理层规定了电缆、连接器和信号标准。了解这些基础,有助于深入理解网络运作机制。
22 5
|
12天前
|
SQL 安全 网络安全
数字堡垒的裂缝与防御:网络安全漏洞解析与加密技术应用
【7月更文挑战第13天】在数字化浪潮中,网络安全漏洞如同潜藏的陷阱,威胁着信息资产的安全。本文将深入剖析常见的网络攻击手段和安全漏洞,揭示它们背后的原因和影响。同时,探讨加密技术如何成为守护数据安全的利剑,以及提升个人与企业的安全意识在防范网络风险中的关键作用。通过案例分析和策略建议,旨在为读者提供一套实用的网络安全知识框架,强化数字世界的防护壁垒。
|
13天前
|
网络协议 程序员 定位技术
学习网络的第一步:全面解析OSI与TCP/IP模型
**网络基础知识概览:** 探索网络通信的关键模型——OSI七层模型和TCP/IP五层模型。OSI模型(物理、数据链路、网络、传输、会话、表示、应用层)提供理论框架,而TCP/IP模型(物理、数据链路、网络、传输、应用层)更为实际,合并了会话、表示和应用层。两者帮助理解数据在网络中的传输过程,为网络设计和管理提供理论支持。了解这些模型,如同在复杂的网络世界中持有了地图。
22 2
|
14天前
|
开发工具 Android开发 Swift
安卓与iOS开发环境的差异性解析
【7月更文挑战第11天】在移动应用开发的广阔天地中,安卓与iOS两大阵营各据一方,它们的开发环境差异如同东西方文化的差异一样鲜明。本文将深入探讨这两个平台在开发工具、编程语言、用户界面设计以及系统架构等方面的不同,旨在为开发者提供一个清晰的对比视角,帮助他们根据项目需求和个人偏好选择最合适的开发路径。
|
18天前
|
存储 安全 网络安全
网络安全中的安全审计与合规性:技术深度解析
【7月更文挑战第7天】安全审计与合规性是保障网络安全的重要环节。通过安全审计,企业可以及时发现并修复安全漏洞,提高系统的安全性;通过合规性管理,企业可以确保自身在法律法规和行业标准方面的合规性,降低违规风险。然而,在实施安全审计与合规性管理的过程中,企业也面临着技术复杂性、数据量大以及法规和合规性要求变化等挑战。因此,企业需要不断加强技术投入和人员培训,提高自身的安全审计与合规性管理水平。

推荐镜像

更多