在開發用戶端與服務端的應用當中,資料交換介面通常都是通過XML格式來進行資料交換的。近年來,隨著AJAX技術的興起,JSON作為一種羽量級的資料交換格式,以其易於閱讀和編寫的優點,也越來越多的被使用到各個專案中。在OPhoneSDK中,也提供了JSON的類庫方便對JSON格式的資料進行處理。本文將快速講解 JSON格式,並通過代碼示例演示如何分別在用戶端和伺服器端進行 JSON 格式資料的處理。

 

什麼是JSON
JSON(JavaScript ObjectNotation)是一種羽量級的資料交換格式,易於閱讀和編寫,同時也易於機器解析和生成,非常適合於伺服器與用戶端的交互。JSON採用與程式設計語言無關的文本格式,但是也使用了類C語言的習慣,這些特性使JSON成為理想的資料交換格式。
和 XML 一樣,JSON 也是基於純文字的資料格式。由於 JSON 天生是為 JavaScript 準備的,因此,JSON的資料格式非常簡單,您可以用 JSON 傳輸一個簡單的 String,Number,Boolean,也可以傳輸一個陣列,或者一個複雜的Object 物件。

 

String,Number 和 Boolean 用 JSON 表示非常簡單。例如,用 JSON 表示一個簡單的字串 “ abc ”,其格式為:"abc"。



除了字元 ",\,/ 和一些控制符(\b,\f,\n,\r,\t)需要編碼外,其他 Unicode 字元可以直接輸出。下圖是一個 String 的完整表示結構:

3207688834595220285.jpg  



圖1.String的完整表示結構

 

一個 Number 可以根據整型或浮點數表示如下:

3207688834595220286.jpg  


圖2.Number 的表示結構



這與絕大多數程式設計語言的表示方法一致,例如:
12345(整數)
-3.9e10(浮點數)

 

Boolean 類型表示為 true 或 false 。此外,JavaScript 中的 null 被表示為 null,注意,true、false 和 null 都沒有雙引號,否則將被視為一個 String 。



JSON 還可以表示一個陣列物件,使用 [] 包含所有元素,每個元素用逗號分隔,元素可以是任意的 Value,例如,以下陣列包含了一個 String,Number,Boolean 和一個 null:

3676344670818766015.jpg  



Object 物件在 JSON 中是用 {} 包含一系列無序的Key-Value 鍵值對表示的,實際上此處的 Object 相當於 Java 中的 Map<String,Object>,而不是 Java 的 Class 。注意 Key 只能用 String 表示。例如,一個 Address 物件包含如下Key-Value:



city:Beijing
street:Chaoyang Road
postcode:100025(整數)

 

用JSON 表示如下:

 

{"city":"Beijing","street":" Chaoyang Road ","postcode":100025}
{"city":"Beijing","street":" Chaoyang Road ","postcode":100025}

 

其中 Value 也可以是另一個 Object 或者陣列,因此,複雜的 Object 可以巢狀表格示,例如,一個 Person 物件包含 name 和 address 物件,可以表示如下:





{"name":"Michael","address":
{"city":"Beijing","street":" Chaoyang Road ","postcode":100025} }






{"name":"Michael","address": {"city":"Beijing","street":" Chaoyang Road ","postcode":100025}}





一個實際例子
接下來,我會通過一個例子來詳細說明OPhone用戶端程式如何訪問服務端的介面程式讀取使用者清單資料,並在模擬器上顯示使用者清單資料。






1、服務端介面程式
首先,我們創建一個名為User的JavaBean作為使用者物件類,用來保存演示資料。



public class User {
private int id;
private String name;
private String email;
private String gender;

 

public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}

 

}

 

接下來,我們創建一個名為JSONDemoServlet的Servlet類來作為服務端的介面程式。在這個程式裡,定義了一個List物件用來保存使用者清單。private List<User> list;



用戶端程式訪問伺服器端介面時,介面通過prepareData方法為使用者清單初始化資料,添加使用者資料到List物件中。
private void prepareData(){
list = new ArrayList<User>();
User bean1 = new User();
bean1.setId(1001);
bean1.setName("Tony");
bean1.setEmail("tony@toeach.net");
bean1.setGender("male");
list.add(bean1);
……
}

 

接著遍歷使用者清單,把清單中的每個Java使用者物件轉換為JSONObject物件,再加入到JSONArray中去。
JSONArray array = new JSONArray();
for(User bean:list){
//單個使用者JSON物件
JSONObject obj = new JSONObject();

 

try{
obj.put("id", bean.getId());
obj.put("name", bean.getName());
obj.put("email", bean.getEmail());
obj.put("gender", bean.getGender());
} catch (Exception e) {}

 

array.put(obj);
}

 

最後,通過 Servlet輸出 JSON 時,需要設置正確的 MIME 類型和字元編碼。假定伺服器使用 UTF-8 編碼,則可以使用以下代碼輸出編碼後的 JSON 文本:
response.setContentType("text/plain");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.write(array.toString());
out.flush();
out.close();

 

JSONDemoServlet.java的完整代碼如下:
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

 

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

 

import org.json.JSONArray;
import org.json.JSONObject;

 

public class JSONDemoServlet extends HttpServlet{
private static final long serialVersionUID = -7368225680407826408L;
private List<User> list;

 

/**
* 處理post方式提交的資料
*/
public void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
doGet(request,response);
}
/**
* 出來get方式提交的資料
*/
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/plain");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();

//準備使用者資料
prepareData();

//JSON陣列
JSONArray array = new JSONArray();
for(User bean:list){
//單個使用者JSON物件
JSONObject obj = new JSONObject();

try{
obj.put("id", bean.getId());
obj.put("name", bean.getName());
obj.put("email", bean.getEmail());
obj.put("gender", bean.getGender());
} catch (Exception e) {}

array.put(obj);
}

//輸出
out.write(array.toString());
out.flush();
out.close();
}
private void prepareData(){
list = new ArrayList<User>();
User bean1 = new User();
bean1.setId(1001);
bean1.setName("Tony");
bean1.setEmail("tony@toeach.net");
bean1.setGender("male");
list.add(bean1);

User bean2 = new User();
bean2.setId(1002);
bean2.setName("Jack");
bean2.setEmail("jack@hotmail.com");
bean2.setGender("male");
list.add(bean2);

User bean3 = new User();
bean3.setId(1003);
bean3.setName("Marry");
bean3.setEmail("marry@163.com");
bean3.setGender("female");
list.add(bean3);

User bean4 = new User();
bean4.setId(1004);
bean4.setName("Linda");
bean4.setEmail("linda@21cn.com");
bean4.setGender("female");
list.add(bean4);
}
}

把該Servlet部署到Tomcat下,在流覽器輸入介面位址http://localhost:8080/article/JSONDemoServlet,輸出結果如下:
[{"id":1001,"email":"[url=mailto:tony@toeach.net%22,%22name%22:%22Tony%22,%22gender%22:%22male%22%7D,%7B%22id%22:1002,%22email%22:%22jack@hotmail.com%22,%22name%22:%22Jack%22,%22gender%22:%22male%22%7D,%7B%22id%22:1003,%22email%22:%22marry@163.com%22,%22name%22:%22Marry%22,%22gender%22:%22female%22%7D,%7B%22id%22:1004,%22email%22:%22linda@21cn.com%22,%22name%22:%22Linda%22,%22gender%22:%22female]tony@toeach.net","name":"Tony","gender":"male"},{"id":1002,"email":"jack@hotmail.com","name":"Jack","gender":"male"},{"id":1003,"email":"marry@163.com","name":"Marry","gender":"female"},{"id":1004,"email":"linda@21cn.com","name":"Linda","gender":"female[/url]"}]
2、手機用戶端程式
準備好服務端的介面後,接下來就是準備寫用戶端的程式了。打開Eclipse新建一個OPhone專案。我們創建一個名為MainActivity的Activity類,如下圖所示:


3208533259525303788.png  




因為要訪問外部網路,所以要在AndroidManifest.xml檔裡增加一行安全許可:
<uses-permission android:name="android.permission.INTERNET"/>

這樣我們的應用程式就可以訪問網路了。

接著修改佈局檔res\layout\main.xml,增加一個TextView物件,用來顯示解析後的使用者資料

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView android:id="@+id/textView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</LinearLayout>

OPhone SDK提供了Apache的HttpClient類處理網路訪問,相信很多讀者朋友都在其他專案當中用到過HttpClient。我寫了一個方法,獲取某一網址的網頁內容,代碼如下:
/**
* 獲取網址內容
* @param url
* @return
* @throws Exception
*/
private String getContent(String url) throws Exception{
StringBuilder sb = new StringBuilder();

HttpClient client = new DefaultHttpClient();
HttpParams httpParams = client.getParams();
//設置網路超時參數
HttpConnectionParams.setConnectionTimeout(httpParams, 3000);
HttpConnectionParams.setSoTimeout(httpParams, 5000);
HttpResponse response = client.execute(new HttpGet(url));
HttpEntity entity = response.getEntity();
if (entity != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"), 8192);

String line = null;
while ((line = reader.readLine())!= null){
sb.append(line + "\n");
}
reader.close();
}
return sb.toString();
}

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

try{
StringBuffer sb = new StringBuffer();
//在測試過程中,經常是用本機做測試伺服器,訪問本機的IP位址要設置為10.0.2.2
String url = "http://10.0.2.2:8080/article/JSONDemoServlet";
String body = getContent(url);
JSONArray array = new JSONArray(body);
for(int i=0; i<array.length(); i++){
JSONObject obj = array.getJSONObject(i);
sb.append("id:").append(obj.getInt("id")).append("\t");
sb.append("name:").append(obj.getString("name")).append("\r\n");
sb.append("gender:").append(obj.getString("gender")).append("\t");
sb.append("email:").append(obj.getString("email")).append("\r\n");
sb.append("----------------------\r\n");
}
TextView textView = (TextView)findViewById(R.id.textView);
textView.setText(sb.toString());
}catch(Exception e){}
}

運行後的介面如下圖:

3207688834595220287.jpg  









總結
本文簡單介紹了JSON的相關知識,以及在OPhone平臺中如何通過JSON來和服務端的應用進行資料交換。
arrow
arrow
    全站熱搜

    戮克 發表在 痞客邦 留言(0) 人氣()