1. 程式人生 > >Android開發之JSON資料解析詳解(二)

Android開發之JSON資料解析詳解(二)

在上一篇我們講解了Android開發JSON的基本介紹以及JSON的資料結構等,

今天我們來講解一下JSON的工作原理以及基本用法:

JSON解析分為兩種情況,一種是在伺服器端解析,另一種是在客戶端解析

第一種:在伺服器段解析:

   通常,客戶端在請求伺服器資料時,伺服器可以使用XML文件、JSON資料或HTML的形式將資料傳送給客戶端。

  那麼如何在伺服器端生成JSON資料呢?首先需要完成以下兩個準備工作。

  (1)我們需要使用Eclipse建立了一個Web Project,這裡我將該工程命名為了“AndroidToJSON解析”(方便檢視,開發時不要用中文),用來模擬伺服器端的Web服務。

  (2)我們還需要在該工程中匯入JSON的API資料包json-lib-2.2.2-jdk15.jar

  在JSON的API中,提供了JSONObject類,通過呼叫JSONObject類的put(Object key, Object value)方法,可以將一個Object物件以鍵值對的形式存入JSONObject物件。通過呼叫JSONObject類的toString()方法,則可以將JSONObject物件轉化為JSON資料。

  如下的程式碼建立了一個JsonTools類,並實現了靜態方法createJsonString(),用來生成JSON資料。

public class JsonTools {
	/**
	 * 
	 * @param   key   json資料的鍵值
	 * @param   value 生成的json資料的value值
	 * @return  json物件的值
	 * @author  brucecheng夏夏
	 */
	public static String createJsonString(String key,Object value){
		//建立
		JSONObject json=new JSONObject();
		//此處要try----catch一下
		try {
			json.put(key, value);
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return json.toString();
	}


通過使用該方法,我們可以很方便的將各種資料傳遞進來,並將其轉化成JSON資料。比如,我們可以在JsonService類中,實現一個簡單的獲取Person物件列表的方法,具體如下:

編寫一個JavaBeans:

Person類:id,name,age三個屬性

public class JsonService {
	public List<Person> getListPerson(){
		List<Person> list=new ArrayList<Person>();
		Person p1=new Person(1001, "Bruce", 20);
		Person p2=new Person(1002, "Jack", 21);
		Person p3=new Person(1003, "David", 22);
		list.add(p1);
		list.add(p2);
		list.add(p3);
		return list;
	}
}
最後,我們可以建立一個繼承自HttpServlet的JsonAction類,並實現其中的doPost()方法,用來響應客戶端對伺服器的請求。具體如下:
public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html;charset=utf-8");
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        PrintWriter out = response.getWriter();
        
        List<Person> listPerson = jsonService.getListPerson();
        
        String str = null;
        String action_flag = request.getParameter("action_flag");    //獲取URL引數
        if(action_flag.equals("persons")) {
            str = JsonTools.createJsonString("persons", listPerson);
        }
        out.println(str);
        out.flush();
        out.close();
    }

可以看到,在doPost()方法中,我們通過呼叫getListPerson()方法獲得了Person物件列表listPerson,並將其傳入JsonTools.createJsonString()方法中,從而獲得了一串JSON資料。

  將該工程釋出到Tomcat上,使用瀏覽器訪問該Web工程,可以看到如圖4所示的介面,Person物件列表被成功的轉化成了JSON資料。


以上就成功的將資料部署到伺服器中了,

接下來我們新建一個安卓的工程來獲取相應的解析資料:

當點選Button時將解析出來的資料繫結到textView上去

佈局檔案程式碼如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <Button
        android:id="@+id/btn_json"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="@string/json"
        android:textColor="#0000ff"
        android:textSize="20sp" />

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_below="@id/btn_json" >

        <TextView
            android:id="@+id/tv_show"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:text="@string/hello_world"
            android:textColor="#0000ff"
            android:textSize="20sp" />
    </ScrollView>

</RelativeLayout>

要完成解析我們需要編寫以下幾個類:

第一個:
Person類的java beans和之前的一樣不再重寫

第二個:

JsonTools類其功能是根據key和json資料來解析獲得資料

package com.brucecheng.json;

import java.util.ArrayList;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONObject;

public class JsonTools {
	//自定義一個方法解析
	public static List<Person> getPerson(String key,String jsonString){
		List<Person> persons=new ArrayList<Person>();
		try {
			//獲取Json物件
			JSONObject jsonObj=new JSONObject(jsonString);
			//由Json物件獲取JsonArray
			JSONArray jsonArr=jsonObj.getJSONArray(key);
			//遍歷陣列獲得每一個jsonObject物件
			for (int i = 0; i < jsonArr.length(); i++) {
				JSONObject personObj=jsonArr.getJSONObject(i);
				int id=personObj.getInt("id");
				String name=personObj.getString("name");
				int age=personObj.getInt("age");
				Person p=new Person(id,name,age);
				persons.add(p);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return persons;
	}
}

第三個:

HttpUtils類,本類的作用是根據路徑開啟連接獲取json資料

package com.brucecheng.json;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;

public class HttpUtils {
	//定義一個靜態的方法獲取JSON內容
	//這裡的path是web服務的網址
	public static String getJsonContent(String path){
		try {
			//根據路徑建立URL地址
			URL url=new URL(path);
			//通過url地址開啟連線
			HttpURLConnection conn=(HttpURLConnection) url.openConnection();
			//設定超時時間
			conn.setConnectTimeout(10000);
			//設定請求方式
			conn.setRequestMethod("GET");
			//設定屬性
			conn.setRequestProperty("User-Agent","Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)");
			//設定該連線是否可輸入
			//conn.setDoInput(true);
			int code=conn.getResponseCode();
			System.out.println(code+"****");
			if(code==200){
				return changeInputString(conn.getInputStream());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";
	}
	//自定義方法根據io流得到字串
	public static String changeInputString(InputStream is){
		String jsonString="";
		ByteArrayOutputStream baos=new ByteArrayOutputStream();
		byte[] data=new byte[1024];
		int len=0;
		try {
			while((len=is.read(data))!=-1){
				baos.write(data,0,len);
			}
			jsonString=new String(baos.toByteArray());
		} catch (Exception e) {
			e.printStackTrace();
		}
		return jsonString;
	}
}

執行結果如下: