Android用GSon處理Json資料

來源:互聯網
上載者:User
 

此篇接上篇 Android訪問WCF(下篇)-用戶端開發 將伺服器擷取的JSON資料通過GSON這個類庫, 進行還原序列化, 並通過UI顯示出來.

如何在Android平台上用GSON還原序列化JSON資料, 參考了這篇文章 http://benjii.me/2010/04/deserializing-json-in-android-using-gson/

一. 建立我們封裝好的Http請求類檔案 WebDataGetApi.java

package com.demo;</p><p>import java.io.IOException;<br />import java.io.InputStreamReader;<br />import java.io.UnsupportedEncodingException;</p><p>import org.apache.http.HttpEntity;<br />import org.apache.http.HttpResponse;<br />import org.apache.http.client.methods.HttpGet;<br />import org.apache.http.impl.client.DefaultHttpClient;<br />import org.apache.http.params.BasicHttpParams;<br />import org.apache.http.protocol.HTTP;</p><p>import android.util.Log;</p><p>public class WebDataGetApi {</p><p> private static final String TAG = "WebDataGetAPI";<br /> private static final String USER_AGENT = "Mozilla/4.5";</p><p> protected String getRequest(String url) throws Exception {<br /> return getRequest(url, new DefaultHttpClient(new BasicHttpParams()));<br /> }</p><p> protected String getRequest(String url, DefaultHttpClient client)<br /> throws Exception {<br /> String result = null;<br /> int statusCode = 0;<br /> HttpGet getMethod = new HttpGet(url);<br /> Log.d(TAG, "do the getRequest,url=" + url + "");<br /> try {<br /> getMethod.setHeader("User-Agent", USER_AGENT);<br /> // HttpParams params = new HttpParams();</p><p> // 添加使用者密碼驗證資訊<br /> // client.getCredentialsProvider().setCredentials(<br /> // new AuthScope(null, -1),<br /> // new UsernamePasswordCredentials(mUsername, mPassword));</p><p> HttpResponse httpResponse = client.execute(getMethod);<br /> // statusCode == 200 正常<br /> statusCode = httpResponse.getStatusLine().getStatusCode();<br /> Log.d(TAG, "statuscode = " + statusCode);<br /> // 處理返回的httpResponse資訊<br /> result = retrieveInputStream(httpResponse.getEntity());<br /> } catch (Exception e) {<br /> Log.e(TAG, e.getMessage());<br /> throw new Exception(e);<br /> } finally {<br /> getMethod.abort();<br /> }<br /> return result;<br /> }</p><p> /**<br /> * 處理httpResponse資訊,返回String<br /> *<br /> * @param httpEntity<br /> * @return String<br /> */<br /> protected String retrieveInputStream(HttpEntity httpEntity) {<br /> int length = (int) httpEntity.getContentLength();<br /> if (length < 0)<br /> length = 10000;<br /> StringBuffer stringBuffer = new StringBuffer(length);<br /> try {<br /> InputStreamReader inputStreamReader = new InputStreamReader(<br /> httpEntity.getContent(), HTTP.UTF_8);<br /> char buffer[] = new char[length];<br /> int count;<br /> while ((count = inputStreamReader.read(buffer, 0, length - 1)) > 0) {<br /> stringBuffer.append(buffer, 0, count);<br /> }<br /> } catch (UnsupportedEncodingException e) {<br /> Log.e(TAG, e.getMessage());<br /> } catch (IllegalStateException e) {<br /> Log.e(TAG, e.getMessage());<br /> } catch (IOException e) {<br /> Log.e(TAG, e.getMessage());<br /> }<br /> return stringBuffer.toString();<br /> }<br />}二. 建立JsonDataGetApi.java package com.demo;</p><p>import org.json.JSONArray;<br />import org.json.JSONException;<br />import org.json.JSONObject;</p><p>public class JsonDataGetApi extends WebDataGetApi {<br /> private static final String BASE_URL = "http://10.0.2.2:82/AccountService/";<br /> private static final String EXTENSION = "Json/";;</p><p> public JSONObject getObject(String sbj) throws JSONException, Exception {<br /> return new JSONObject(getRequest(BASE_URL + EXTENSION + sbj));<br /> }</p><p> public JSONArray getArray(String sbj) throws JSONException, Exception {<br /> return new JSONArray(getRequest(BASE_URL + EXTENSION + sbj));<br /> }<br />}

三. 建立Android端Account模型Account.java

import java.util.Date;</p><p>public class Account {</p><p>public String Name;</p><p>public int Age;</p><p>public String Address;</p><p>public Date Birthday;<br />}四. 在我們的主Activity中調用剛才的方法, 在這一步中我們需要引入Google的gson 庫gson-1.6.jar至我們的工程()package com.demo;</p><p>import java.util.Date;</p><p>import org.json.JSONArray;<br />import org.json.JSONObject;</p><p>import com.google.gson.Gson;<br />import com.google.gson.GsonBuilder;</p><p>import android.app.Activity;<br />import android.os.Bundle;<br />import android.util.Log;<br />import android.widget.TextView;<br />import android.widget.Toast;</p><p>public class WebData extends Activity {<br /> /** Called when the activity is first created. */<br /> @Override<br /> public void onCreate(Bundle savedInstanceState) {<br /> super.onCreate(savedInstanceState);<br /> setContentView(R.layout.main);<br /> getJsonData();<br /> }</p><p> public void getJsonData() {<br /> JsonDataGetApi api = new JsonDataGetApi();<br /> JSONArray jArr;<br /> JSONObject jobj;<br /> try {<br /> //調用GetAccountData方法<br /> jArr = api.getArray("GetAccountData");<br /> //從返回的Account Array中取出第一個資料<br /> jobj = jArr.getJSONObject(0);</p><p> GsonBuilder gsonb = new GsonBuilder();<br /> //Json中的日期表達方式沒有辦法直接轉換成我們的Date類型, 因此需要單獨註冊一個Date的還原序列化類.<br /> //DateDeserializer ds = new DateDeserializer();<br /> //給GsonBuilder方法單獨指定Date類型的還原序列化方法<br /> //gsonb.registerTypeAdapter(Date.class, ds);</p><p> Gson gson = gsonb.create();</p><p> Account account = gson.fromJson(jobj.toString(), Account.class);</p><p> Log.d("LOG_CAT", jobj.toString());<br /> ((TextView) findViewById(R.id.Name)).setText(account.Name);<br /> ((TextView) findViewById(R.id.Age)).setText(account.Age);<br /> ((TextView) findViewById(R.id.Birthday)).setText(account.Birthday<br /> .toGMTString());<br /> ((TextView) findViewById(R.id.Address)).setText(account.Address);</p><p> } catch (Exception e) {<br /> Toast.makeText(getApplicationContext(), e.getMessage(),<br /> Toast.LENGTH_LONG).show();<br /> e.printStackTrace();<br /> TextView movie_Address = (TextView) findViewById(R.id.Address);<br /> movie_Address.setText(e.getMessage());<br /> }<br /> }<br />}<br />五.我們開始構建UI

開啟layout下的main.xml

<?xml version="1.0" encoding="utf-8"?><br /><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"<br /> android:orientation="vertical" android:layout_width="fill_parent"<br /> android:layout_height="fill_parent"><br /> <TextView android:id="@+id/Name" android:layout_width="fill_parent"<br /> android:layout_height="wrap_content" /><br /> <TextView android:id="@+id/Age" android:layout_width="fill_parent"<br /> android:layout_height="wrap_content" /><br /> <TextView android:id="@+id/Birthday" android:layout_width="fill_parent"<br /> android:layout_height="wrap_content" /><br /> <TextView android:id="@+id/Address" android:layout_width="fill_parent"<br /> android:layout_height="wrap_content" /><br /></LinearLayout></p><p>在配置好RunConfiguration之後,我們開始運行程式,  查看Log發現有以下錯誤,

意思是說訪問被禁止,也就是未授權訪問,  其意思並不是我們的服務未授權, 因為Andriod具有很好的很好很好的安全機制, 我們要訪問網路必須要經過授權才可以;

我們開啟res目錄下AndroidManifest.xml, 注意字型加粗放大的那句, 就是給我們的程式加入Internet的訪問授權.

<?xml version="1.0" encoding="utf-8"?><br /><manifest xmlns:android="http://schemas.android.com/apk/res/android"<br /> package="com.demo"<br /> android:versionCode="1"<br /> android:versionName="1.0"></p><p> <uses-permission android:name="android.permission.INTERNET"></uses-permission></p><p> <application android:icon="@drawable/icon" android:label="@string/app_name"><br /> <activity android:name=".WebData"<br /> android:label="@string/app_name"><br /> <intent-filter><br /> <action android:name="android.intent.action.MAIN" /><br /> <category android:name="android.intent.category.LAUNCHER" /><br /> </intent-filter><br /> </activity></p><p> </application><br /></manifest>再次運行程式, 會發現顯示如下:

 

 

從中的statuscode = 200來看,說明我們的請求已經成功, 問題出現在Json Parse(Json資料轉換/還原序列化/格式化)的過程中, 我們現在把從伺服器傳過來的資料拿出來看看, 在瀏覽器輸入我們的服務地址: http://localhost:82/AccountService/Json/GetAccountData 

[ {     "Address": "YouYi East Road",     "Age": 56,     "Birthday": "/Date(1298605481453+0800)/",     "Name": "Bill Gates" }, {     "Address": "YouYi West Road",     "Age": 57,     "Birthday": "/Date(1298605481453+0800)/",     "Name": "Steve Paul Jobs" }, {     "Address": "YouYi North Road",     "Age": 65,     "Birthday": "/Date(1298605481453+0800)/",     "Name": "John D. Rockefeller" }]

我們發現其中的Birthday的結果並非我們想象中yyyy-mm-dd HH:mm:ss類型, 究其原因可以查看MSDN文章《JavaScript 和 .NET 中的 JavaScript Object Notation (JSON) 簡介》

現在我們給我們的GsonBuilder指定Date的序列化方法, 先增加一個Date還原序列化的類DateDeserializer.java

package com.demo;</p><p>import java.lang.reflect.Type;<br />import java.util.Date;<br />import java.util.regex.Matcher;<br />import java.util.regex.Pattern;</p><p>import com.google.gson.JsonDeserializationContext;<br />import com.google.gson.JsonDeserializer;<br />import com.google.gson.JsonElement;<br />import com.google.gson.JsonParseException;</p><p>public class DateDeserializer implements JsonDeserializer<Date> {<br /> public Date deserialize(JsonElement json, Type typeOfT,<br /> JsonDeserializationContext context) throws JsonParseException {<br /> String JSONDateToMilliseconds = "\\/(Date\\((.*?)(\\+.*)?\\))\\/";<br /> Pattern pattern = Pattern.compile(JSONDateToMilliseconds);<br /> Matcher matcher = pattern.matcher(json.getAsJsonPrimitive()<br /> .getAsString());<br /> String result = matcher.replaceAll("$2");<br /> return new Date(new Long(result));<br /> }<br />}其次修改Activity類中的GetDate方法如下, 注意其中加粗的部分. public void getJsonData() {<br /> JsonDataGetApi api = new JsonDataGetApi();<br /> JSONArray jArr;<br /> JSONObject jobj;<br /> try {<br /> //調用GetAccountData方法<br /> jArr = api.getArray("GetAccountData");<br /> //從返回的Account Array中取出第一個資料<br /> jobj = jArr.getJSONObject(0);</p><p> GsonBuilder gsonb = new GsonBuilder();<br /> //Json中的日期表達方式沒有辦法直接轉換成我們的Date類型, 因此需要單獨註冊一個Date的還原序列化類.<br /> DateDeserializer ds = new DateDeserializer();<br /> //給GsonBuilder方法單獨指定Date類型的還原序列化方法<br /> gsonb.registerTypeAdapter(Date.class, ds);</p><p> Gson gson = gsonb.create();</p><p> Account account = gson.fromJson(jobj.toString(), Account.class);</p><p> Log.d("LOG_CAT", jobj.toString());<br /> ((TextView) findViewById(R.id.Name)).setText(account.Name);<br /> ((TextView) findViewById(R.id.Age)).setText(String.valueOf(account.Age));<br /> ((TextView) findViewById(R.id.Birthday)).setText(account.Birthday<br /> .toGMTString());<br /> ((TextView) findViewById(R.id.Address)).setText(account.Address);</p><p> } catch (Exception e) {<br /> Toast.makeText(getApplicationContext(), e.getMessage(),<br /> Toast.LENGTH_LONG).show();<br /> e.printStackTrace();<br /> }<br /> }<br />}<br />我們現在再運行程式 :

 

執行成功.

樣本下載

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.