Android網絡之數據解析----使用Google Gson解析Json數據

【聲明】 html

歡迎轉載,但請保留文章原始出處→_→ java

生命壹號:http://www.cnblogs.com/smyhvae/android

文章來源:http://www.cnblogs.com/smyhvae/p/4063452.htmlweb

 

【正文】apache

文章回顧: Android網絡之數據解析----SAX方式解析XML數據json

1、Json數據的介紹                                                                                                                數組

Json(JavaScript Object Notation) 是一種輕量級的數據交換格式。它基於JS的一個子集。 Json採用徹底獨立於語言的文本格式,這使得Json成爲理想的數據交換語言。易於人閱讀和編寫,同時也易於機器解析和生成。瀏覽器

Json簡單來講就是JS中的對象和數組,因此Json也存在兩種結構:對象、數組tomcat

一、Json對象:服務器

含義:是「‘鍵/值’對」的無序集合

格式:Json對象定義在花括號「{}」內,以Key:value鍵值對的形式存放數據,多個鍵值對之間使用逗號「,」隔開,多個數據使用分號「;」隔開。

舉例:

{
    「name」:」jackson」,
    「age」:100
}

注:不一樣的語言中,它被理解爲對象(object)、紀錄(record)、結構(struct)、字典(dictionary)、哈希表(hash table)、有鍵列表(keyed list)、或者關聯數組 (associative array)。

二、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數據。

 

2、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()); 

基本用法就是這樣,咱們如今來看一下具體的實現步驟吧。

 

3、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數據解析成功,大功告成。

最後聲明:

其實,若是是在模擬器上運行,即便不添加網絡權限,也是沒有關係的;可是,若是在真機上運行(前提是真機和電腦在同一個局域網),不添加網絡權限,程序是絕對運行不了的,點擊按鈕,程序就會死掉,這個地方又耽誤了我半個小時,罪過。

【工程文件】

連接:http://pan.baidu.com/s/1mgj0FY4

密碼:61u3

相關文章
相關標籤/搜索