Android用GSon处理Json数据
此篇接上篇 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;import java.io.IOException; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException;import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.params.BasicHttpParams; import org.apache.http.protocol.HTTP;import android.util.Log;public class WebDataGetApi {private static final String TAG = "WebDataGetAPI";private static final String USER_AGENT = "Mozilla/4.5";protected String getRequest(String url) throws Exception {return getRequest(url, new DefaultHttpClient(new BasicHttpParams()));}protected String getRequest(String url, DefaultHttpClient client)throws Exception {String result = null;int statusCode = 0;HttpGet getMethod = new HttpGet(url);Log.d(TAG, "do the getRequest,url=" + url + "");try {getMethod.setHeader("User-Agent", USER_AGENT);// HttpParams params = new HttpParams();// 添加用戶密碼驗證信息// client.getCredentialsProvider().setCredentials(// new AuthScope(null, -1),// new UsernamePasswordCredentials(mUsername, mPassword));HttpResponse httpResponse = client.execute(getMethod);// statusCode == 200 正常statusCode = httpResponse.getStatusLine().getStatusCode();Log.d(TAG, "statuscode = " + statusCode);// 處理返回的httpResponse信息result = retrieveInputStream(httpResponse.getEntity());} catch (Exception e) {Log.e(TAG, e.getMessage());throw new Exception(e);} finally {getMethod.abort();}return result;}/*** 處理httpResponse信息,返回String* * @param httpEntity* @return String*/protected String retrieveInputStream(HttpEntity httpEntity) {int length = (int) httpEntity.getContentLength();if (length < 0)length = 10000;StringBuffer stringBuffer = new StringBuffer(length);try {InputStreamReader inputStreamReader = new InputStreamReader(httpEntity.getContent(), HTTP.UTF_8);char buffer[] = new char[length];int count;while ((count = inputStreamReader.read(buffer, 0, length - 1)) > 0) {stringBuffer.append(buffer, 0, count);}} catch (UnsupportedEncodingException e) {Log.e(TAG, e.getMessage());} catch (IllegalStateException e) {Log.e(TAG, e.getMessage());} catch (IOException e) {Log.e(TAG, e.getMessage());}return stringBuffer.toString();} } 二. 建立JsonDataGetApi.java package com.demo;import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject;public class JsonDataGetApi extends WebDataGetApi {private static final String BASE_URL = "http://10.0.2.2:82/AccountService/";private static final String EXTENSION = "Json/";;public JSONObject getObject(String sbj) throws JSONException, Exception {return new JSONObject(getRequest(BASE_URL + EXTENSION + sbj));}public JSONArray getArray(String sbj) throws JSONException, Exception {return new JSONArray(getRequest(BASE_URL + EXTENSION + sbj));} }三. 建立Android端Account模型Account.java
package com.demo;import java.util.Date;public class Account {public String Name;public int Age;public String Address;public Date Birthday; }四. 在我們的主Activity中調用剛才的方法, 在這一步中我們需要引入Google的gson 庫gson-1.6.jar至我們的工程(下載地址)
package com.demo;import java.util.Date;import org.json.JSONArray; import org.json.JSONObject;import com.google.gson.Gson; import com.google.gson.GsonBuilder;import android.app.Activity; import android.os.Bundle; import android.util.Log; import android.widget.TextView; import android.widget.Toast;public class WebData extends Activity {/** Called when the activity is first created. */@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.main);getJsonData();}public void getJsonData() {JsonDataGetApi api = new JsonDataGetApi();JSONArray jArr;JSONObject jobj;try {//調用GetAccountData方法jArr = api.getArray("GetAccountData");//從返回的Account Array中取出第一個數據jobj = jArr.getJSONObject(0);GsonBuilder gsonb = new GsonBuilder();//Json中的日期表達方式沒有辦法直接轉換成我們的Date類型, 因此需要單獨注冊一個Date的反序列化類.//DateDeserializer ds = new DateDeserializer();//給GsonBuilder方法單獨指定Date類型的反序列化方法//gsonb.registerTypeAdapter(Date.class, ds);Gson gson = gsonb.create();Account account = gson.fromJson(jobj.toString(), Account.class);Log.d("LOG_CAT", jobj.toString());((TextView) findViewById(R.id.Name)).setText(account.Name);((TextView) findViewById(R.id.Age)).setText(account.Age);((TextView) findViewById(R.id.Birthday)).setText(account.Birthday.toGMTString());((TextView) findViewById(R.id.Address)).setText(account.Address);} catch (Exception e) {Toast.makeText(getApplicationContext(), e.getMessage(),Toast.LENGTH_LONG).show();e.printStackTrace();TextView movie_Address = (TextView) findViewById(R.id.Address);movie_Address.setText(e.getMessage());}} }五.我們開始構建UI
打開layout下的main.xml
<?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/Name" android:layout_width="fill_parent"android:layout_height="wrap_content" /><TextView android:id="@+id/Age" android:layout_width="fill_parent"android:layout_height="wrap_content" /><TextView android:id="@+id/Birthday" android:layout_width="fill_parent"android:layout_height="wrap_content" /><TextView android:id="@+id/Address" android:layout_width="fill_parent"android:layout_height="wrap_content" /> </LinearLayout>在配置好RunConfiguration之后,我們開始運行程序,? 查看Log發現有以下錯誤,
意思是說訪問被禁止,也就是未授權訪問,? 其意思并不是我們的服務未授權, 因為Andriod具有很好的很好很好的安全機制, 我們要訪問網絡必須要經過授權才可以;
我們打開res目錄下AndroidManifest.xml, 注意字體加粗放大的那句, 就是給我們的程序加入Internet的訪問授權.
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.demo"android:versionCode="1"android:versionName="1.0"><uses-permission android:name="android.permission.INTERNET"></uses-permission> <application android:icon="@drawable/icon" android:label="@string/app_name"><activity android:name=".WebData"android:label="@string/app_name"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity></application> </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;import java.lang.reflect.Type; import java.util.Date; import java.util.regex.Matcher; import java.util.regex.Pattern;import com.google.gson.JsonDeserializationContext; import com.google.gson.JsonDeserializer; import com.google.gson.JsonElement; import com.google.gson.JsonParseException;public class DateDeserializer implements JsonDeserializer<Date> {public Date deserialize(JsonElement json, Type typeOfT,JsonDeserializationContext context) throws JsonParseException {String JSONDateToMilliseconds = "\\/(Date\\((.*?)(\\+.*)?\\))\\/";Pattern pattern = Pattern.compile(JSONDateToMilliseconds);Matcher matcher = pattern.matcher(json.getAsJsonPrimitive().getAsString());String result = matcher.replaceAll("$2");return new Date(new Long(result));} }其次修改Activity類中的GetDate方法如下, 注意其中加粗的部分.
public void getJsonData() {JsonDataGetApi api = new JsonDataGetApi();JSONArray jArr;JSONObject jobj;try {//調用GetAccountData方法jArr = api.getArray("GetAccountData");//從返回的Account Array中取出第一個數據jobj = jArr.getJSONObject(0);GsonBuilder gsonb = new GsonBuilder(); //Json中的日期表達方式沒有辦法直接轉換成我們的Date類型, 因此需要單獨注冊一個Date的反序列化類.DateDeserializer ds = new DateDeserializer();//給GsonBuilder方法單獨指定Date類型的反序列化方法gsonb.registerTypeAdapter(Date.class, ds);Gson gson = gsonb.create();Account account = gson.fromJson(jobj.toString(), Account.class);Log.d("LOG_CAT", jobj.toString());((TextView) findViewById(R.id.Name)).setText(account.Name);((TextView) findViewById(R.id.Age)).setText(String.valueOf(account.Age));((TextView) findViewById(R.id.Birthday)).setText(account.Birthday.toGMTString());((TextView) findViewById(R.id.Address)).setText(account.Address);} catch (Exception e) {Toast.makeText(getApplicationContext(), e.getMessage(),Toast.LENGTH_LONG).show();e.printStackTrace();}} }我們現在再運行程序 :
執行成功.
示例下載
轉載于:https://www.cnblogs.com/VinC/archive/2011/02/25/Use-GSon-Hand-JsonData-For-Android-Device.html
總結
以上是生活随笔為你收集整理的Android用GSon处理Json数据的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: J-LINK7 固件修复
- 下一篇: uitableview 默认选中行