如何在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. */
@Override
public 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();
}
}
}
我们现在再运行程序 :
执行成功.
示例下载
分享到:
相关推荐
Android Studio下使用Google Gson解析Json数据示例
我的博客中的关于android中gson解析json数据例程,遇到不懂的可以来我的博客中交流。(๑•̀ㅂ•́)و✧
这里进行介绍Gson解析复杂Json和简单Json的数据方式
1、生成Json数据 2、使用Gson解析Json数据(单个json对象、json数组和json对象内嵌json数组) // 这里有两篇好心人的博文,有详细的讲解 http://www.jb51.net/article/32547.htm ...
Eclipse下使用Google Gson解析Json数据示例,挺好用的,亲测
用google的gson 解析json数据 里面有解析数组的方式 可根据自己的json样式自己定制 使用新手 分享一下
Gson解析Json数据信息,生成Json格式的数据
Json是一种类似于XML的通用数据交换格式,具有比XML更高的传输效率;本文将介绍两种方法解析JSON数据,需要的朋友可以参考下
JSON、GSON解析json数据,详细介绍了json和gson的使用,解析复杂json数据
该源码是用Gson解析一个复杂的json,将json中的数据加载到listview中并且根据json中的url地址加载网络图片到listview中。
Eclipse下使用Google Gson解析Json数据示例
android之json和gson数据解析最完整的代码例子(包括各种样式的json数据) 本人在2.3.3模拟器上已亲测可以运行。最适合学习json 或gson数据解析的初学者。
采用Gson解析json数据。博文链接: http://www.cnblogs.com/smyhvae/p/4063452.html
Android通过gson自动解析服务器返回的json数据
Gson解析网络数据显示到listview上,加入万能适配器,适配器就10行,大家可以复制包用,在log日记查看完整的Json数据,listview上我显示了title给大家看效果,适配器只要10行左右,简单易懂。
assets下使用gson读取省市区json数据,并且修改格式。
使用google 提供的gson.jar的包来生成json格式数据,并利用from json解析这些数据将这些数据显示在手机界面上。亲测可用,项目下载后能够直接运行。本资源是项目的原码哦!
可实现简单json数据与复杂json数据解析,详情请看:http://xiaxveliang.blog.163.com/blog/static/297080342014102674623118/
简单的android与服务器实现json数据交互解析,包含Gson方式和普通方式,实现四种json数据的交互解析
网络上有很多Json解析库,这里我使用Gson来解析Json,Gson有个特点,就是要将数据的键作为变量封装到一个个实体中,如果值为数组的,变量的类型还必须是集合,然后通过Gson.fromJson来传入数据和实体类,再通过实体...