首页 > 代码库 > 使用Gson详解
使用Gson详解
解析json:
Gson gson=new Gson();
Person person=gson.fromJson(jsonData,Person.class);
解析json数组:
需要用到TypeToken将期望解析成的数据类型传入到fromJson()方法中:
List<Person> people=gson.fromJson(jsonData,newTypeToken<List<Person>>(){}.getType());
package com.jia.networktest; import java.io.BufferedReader; import java.io.DataOutputStream; import java.io.InputStream; import java.io.InputStreamReader; import java.io.StringReader; import java.net.HttpURLConnection; import java.net.URL; import java.util.List; import javax.xml.parsers.SAXParserFactory; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.util.EntityUtils; import org.xml.sax.InputSource; import org.xml.sax.XMLReader; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserFactory; import android.app.Activity; import android.os.Bundle; import android.os.Handler; import android.os.Message; import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; public class MainActivity extends Activity implements OnClickListener { public static final int SHOW_RESPONSE = 0; public static final int SHOW_HTTPCLIENT = 1; private Button send_request; private TextView responseText; private Button btn_httpClient; private Handler handler = new Handler() { public void handleMessage(Message msg) { switch (msg.what) { case SHOW_RESPONSE: String response = (String) msg.obj; // 在这里进行UI操作,将结果显示到界面上 responseText.setText(response); case SHOW_HTTPCLIENT: String m_httpClient = (String) msg.obj; // 在这里进行UI操作,将结果显示到界面上 responseText.setText(m_httpClient); } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); send_request = (Button) findViewById(R.id.send_request); responseText = (TextView) findViewById(R.id.response); btn_httpClient = (Button) findViewById(R.id.HttpClient); send_request.setOnClickListener(this); btn_httpClient.setOnClickListener(this); } @Override public void onClick(View v) { if (v.getId() == R.id.send_request) { sendRequestWithHttpURLConnection(); } else if (v.getId() == R.id.HttpClient) { sendRequestWithHttpClient(); } } private void sendRequestWithHttpClient() { new Thread(new Runnable() { @Override public void run() { try { HttpClient httpClient = new DefaultHttpClient(); // 指定访问的服务器地址是电脑本机 HttpGet httpGet = new HttpGet( "http://192.168.1.88:8080/jia/get_data.json"); /* * HttpPost httpPost = new * HttpPost("http://192.168.1.88:8080/jia/get_data.txt"); * List<NameValuePair> params = new * ArrayList<NameValuePair>(); params.add(new * BasicNameValuePair("username","yao_jiawei@hotmail.com")); * params.add(new BasicNameValuePair("password", * "yaowentian")); UrlEncodedFormEntity urlEncodedFormEntity * = new UrlEncodedFormEntity(params, "utf-8"); * httpPost.setEntity(urlEncodedFormEntity); * * HttpResponse httpResponse = httpClient.execute(httpPost); */ HttpResponse httpResponse = httpClient.execute(httpGet); if (httpResponse.getStatusLine().getStatusCode() == 200) { // 请求和响应都成功了 HttpEntity entity = httpResponse.getEntity();// 获取到一个HttpEntity实例 String response = EntityUtils.toString(entity, "utf-8");// 用EntityUtils.toString()这个方法将HttpEntity转换成字符串 /* * Message message = new Message(); message.what * =SHOW_HTTPCLIENT; // 将服务器返回的结果存放到Message中 * message.obj= response.toString(); * handler.sendMessage(message); */ // parseXMLWithPull(response); // parseXMLWithSAX(response); parseJSONWithGSON(response); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void parseXMLWithSAX(String response) { try { SAXParserFactory factory = SAXParserFactory.newInstance(); XMLReader xmlReader = factory.newSAXParser().getXMLReader(); ContentHandler handler = new ContentHandler(); // 将ContentHandler的实例设置到XMLReader中 xmlReader.setContentHandler(handler); // 开始执行解析 xmlReader .parse(new InputSource(new StringReader(response))); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } private void parseXMLWithPull(String xmlData) { try { // 创建一个xmlPullParser的工厂 XmlPullParserFactory factory = XmlPullParserFactory .newInstance(); // 获取一个解析实例 XmlPullParser xmlPullParser = factory.newPullParser(); xmlPullParser.setInput(new StringReader(xmlData)); // 当前事件的类型 int eventType = xmlPullParser.getEventType(); String id = ""; String name = ""; String version = ""; while (eventType != xmlPullParser.END_DOCUMENT) { // 当前节点的名称 String nodeName = xmlPullParser.getName(); switch (eventType) { // 开始解析某个结点 case XmlPullParser.START_TAG: { if ("id".equals(nodeName)) { id = xmlPullParser.nextText(); } else if ("name".equals(nodeName)) { name = xmlPullParser.nextText(); } else if ("version".equals(nodeName)) { version = xmlPullParser.nextText(); } break; }// 完成解析某个结点 case XmlPullParser.END_TAG: { if ("app".equals(nodeName)) { Log.d("jia", "id is----------------->" + id); Log.d("jia", "name is--------------->" + name); Log.d("jia", "version is------------>" + version); } break; } default: break; } eventType = xmlPullParser.next(); } } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } }).start(); } private void parseJSONWithGSON(String jsonData) { Gson gson = new Gson(); List<App> appList = gson.fromJson(jsonData, new TypeToken<List<App>>() { }.getType()); for (App app : appList) { Log.d("jia", "id is----------->" + app.getId()); Log.d("jia", "name is----------->" + app.getName()); Log.d("jia", "version is----------->" + app.getVersion()); } } private void sendRequestWithHttpURLConnection() { // 开启线程来发起网络请求 new Thread(new Runnable() { @Override public void run() { HttpURLConnection connection = null; try { URL url = new URL("http://www.baidu.com"); connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); connection.setConnectTimeout(8000); connection.setReadTimeout(8000); DataOutputStream out = new DataOutputStream(connection .getOutputStream()); out.writeBytes("username=yao_jiawei@hotmail.com&password=yaowentian"); InputStream in = connection.getInputStream(); // 下面对获取到的输入流进行读取 BufferedReader reader = new BufferedReader( new InputStreamReader(in)); StringBuilder response = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { response.append(line); } Message message = new Message(); message.what = SHOW_RESPONSE; // 将服务器返回的结果存放到message中 message.obj = response.toString(); handler.sendMessage(message); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { if (connection != null) { connection.disconnect(); } } } }).start(); } }
JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,采用完全独立于语言的文本格式,为Web应用开发提供了一种理想的数据交换格式。
在上一篇博文《Android学习笔记44:JSON数据解析》中,我们使用基本的JSON API完成了在服务器端创建JSON数据,以及在Android客户端对JSON数据进行解析。
其实,要创建和解析JSON数据,也可以使用GSON来完成。GSON是Google提供的用来在Java对象和JSON数据之间进行映射的Java类库。使用GSON,可以很容易的将一串JSON数据转换为一个Java对象,或是将一个Java对象转换为相应的JSON数据。
1.GSON的两个重要方法
在GSON的API中,提供了两个重要的方法:toJson()和fromJson()方法。其中,toJson()方法用来实现将Java对象转换为相应的JSON数据,fromJson()方法则用来实现将JSON数据转换为相应的Java对象。
1.1 toJson()方法
toJson()方法用于将Java对象转换为相应的JSON数据,主要有以下几种形式:
(1)String toJson(JsonElement jsonElement);
(2)String toJson(Object src);
(3)String toJson(Object src, Type typeOfSrc);
其中,方法(1)用于将JsonElement对象(可以是JsonObject、JsonArray等)转换成JSON数据;方法(2)用于将指定的Object对象序列化成相应的JSON数据;方法(3)用于将指定的Object对象(可以包括泛型类型)序列化成相应的JSON数据。
1.2 fromJson()方法
fromJson()方法用于将JSON数据转换为相应的Java对象,主要有以下几种形式:
(1)<T> T fromJson(JsonElement json, Class<T> classOfT);
(2)<T> T fromJson(JsonElement json, Type typeOfT);
(3)<T> T fromJson(JsonReader reader, Type typeOfT);
(4)<T> T fromJson(Reader reader, Class<T> classOfT);
(5)<T> T fromJson(Reader reader, Type typeOfT);
(6)<T> T fromJson(String json, Class<T> classOfT);
(7)<T> T fromJson(String json, Type typeOfT);
以上的方法用于将不同形式的JSON数据解析成Java对象。
2.在服务器端生成JSON数据
要使用GSON技术在服务器端生成JSON数据,首先需要完成以下两个准备工作。
(1)使用MyEclipse创建了一个Web Project,这里我将该工程命名为了“GsonDemoProject”,用来模拟服务器端的Web服务。
(2)往该工程中导入GSON的API数据包gson-2.2.1.jar。
然后,我们便可以在该工程中创建一个JsonTools工具类,并实现静态方法createJsonString(),在该方法中通过使用GSON技术来生成JSON数据。该方法的具体实现如下。
1 public class JsonTools { 2 3 /* 4 * Function : 生成JSON字符串 5 * Param : value 想要转换成JSON字符串的Object对象 6 * Retuen : JSON字符串 7 * Author : 博客园-依旧淡然 8 */ 9 public static String createJsonString(Object value) { 10 Gson gson = new Gson(); 11 String string = gson.toJson(value); 12 return string; 13 } 14 15 }
可以看到,这个方法的具体实现非常简单,首先创建一个Gson对象,然后通过调用Gson对象的toJson()方法,将传进来的value(任意的Java对象)转换成JSON字符串即可。
通过使用该方法,我们可以很方便的将任意Java对象传递进来,并将其转化成JSON数据。和上一篇博文中一样,我们可以在JsonService类中,实现一个简单的获取Person对象列表的方法,具体如下:
1 /* 2 * Function : 获取Person对象列表 3 * Author : 博客园-依旧淡然 4 */ 5 public List<Person> getListPerson() { 6 List<Person> list = new ArrayList<Person>(); 7 Person person1 = new Person(001, "jack", 25); 8 Person person2 = new Person(002, "rose", 24); 9 Person person3 = new Person(003, "bob", 26); 10 list.add(person1); 11 list.add(person2); 12 list.add(person3); 13 return list; 14 }
在该方法中,我们向List列表中加入了3个Person对象,每个Person对象具有id(int)、name(String)和age(int)三个属性。
最后,我们还需要创建一个继承自HttpServlet的JsonAction类,并实现其中的doPost()方法,用来响应客户端对服务器的请求。具体如下:
1 public void doPost(HttpServletRequest request, HttpServletResponse response) 2 throws ServletException, IOException { 3 4 response.setContentType("text/html;charset=utf-8"); 5 request.setCharacterEncoding("utf-8"); 6 response.setCharacterEncoding("utf-8"); 7 PrintWriter out = response.getWriter(); 8 9 List<Person> listPerson = jsonService.getListPerson(); 10 11 String str = null; 12 String action_flag = request.getParameter("action_flag"); 13 if(action_flag.equals("persons") { 14 str = JsonTools.createJsonString(listPerson); 15 } 16 out.println(str); 17 out.flush(); 18 out.close(); 19 }
在该方法中,我们通过调用JsonService类中的getListPerson()方法获得了Person对象列表listPerson,并将其传入JsonTools.createJsonString()方法中,生成了Person对象列表的JSON数据。将该工程发布到Tomcat上,使用浏览器访问该Web工程,可以看到如图1所示的界面,Person对象列表被成功的转化成了JSON数据。
图1 生成的JSON数据
3.在客户端解析JSON数据
在Android工程中,我们可以通过HttpURLConnection接口访问图1所示的URL来获得服务器上的JSON数据。
得到JSON数据之后,便可以通过使用前面提到的fromJson()方法,将图1 所示的JSON数据还原成对应的Person对象列表了。当然了,因为这里使用到了GSON,同样需要向Android工程中导入gson-2.2.1.jar包。具体的实现方法如下。
1 /* 2 * Function : 解析JSON数据,还原成Person对象列表 3 * Param : jsonString 从服务器获得的Json数据 4 * Retuen : Person对象列表 5 * Author : 博客园-依旧淡然 6 */ 7 public static List<Person> getListPerson(String jsonString) { 8 List<Person> list = new ArrayList<Person>(); 9 Gson gson = new Gson(); 10 list = gson.fromJson(jsonString, new TypeToken<List<Person>>(){}.getType()); 11 return list; 12 }
可以看到,使用GSON解析JSON数据的代码实现也非常简单。其中,TypeToken是GSON提供的数据类型转换器,支持多种数据集合类型转换,其反射机制可以实现将解析出来的Java对象映射到对应的数据集合中。
在本实例中,同样点击Button按钮向服务器发送获取JSON数据的请求,从服务器获得JSON数据后,使用以上的代码完成对JSON数据的解析,最后将解析得到的Person对象依次显示在TextView控件中。程序运行的结果如图2所示。
- public static String CreateJsonStringbyGson(Object value) {
- Gson gson = new Gson();
- String Str = gson.toJson(value);
- return Str;
- }
- public class JsonService {
- //一个person对象
- public Person getPerson(){
- Person person=new Person(1001,"hang","suqian");
- return person;
- }
- public List<Person> getlistPerson(){
- List<Person> list=new ArrayList<Person>();
- Person person1=new Person(1001,"zhang","suqian");
- Person person2=new Person(2002,"hang","yangzhou");
- list.add(person1);
- list.add(person2);
- return list;
- }
- public List<String> getlistString(){
- List<String> list=new ArrayList<String>();
- list.add("beijing");
- list.add("suqian");
- return list;
- }
- public List<Map<String,Object>> getlistMap(){
- List<Map<String,Object>> list=new ArrayList<Map<String,Object>>();
- Map<String,Object> map1=new HashMap<String, Object>();
- map1.put("id", 1001);
- map1.put("name","zhang");
- map1.put("address", "beijing");
- Map<String,Object> map2=new HashMap<String, Object>();
- map2.put("id", 1002);
- map2.put("name","hang");
- map2.put("address", "shanghai");
- list.add(map1);
- list.add(map2);
- return list;
- }
- }
android客户端解析
- package com.example.andorid_json;
- import java.util.ArrayList;
- import java.util.List;
- import java.util.Map;
- import com.google.gson.Gson;
- import com.google.gson.reflect.TypeToken;
- import android.widget.EditText;
- public class GsonTools {
- public static <T> T getPerson(String jsonString, Class<T> cls) {
- T t = null;
- try {
- Gson gson = new Gson();
- t = gson.fromJson(jsonString, cls);
- } catch (Exception e) {
- e.printStackTrace();
- }
- return t;
- }
- public static <T> List<T> getPersons(String jsonString, Class<T> cls) {
- List<T> list = new ArrayList<T>();
- try {
- Gson gson = new Gson();
- list = gson.fromJson(jsonString, new TypeToken<List<T>>() {
- }.getType());
- } catch (Exception e) {
- e.printStackTrace();
- }
- return list;
- }
- public static List<String> getList(String jsonString) {
- List<String> list = new ArrayList<String>();
- try {
- Gson gson = new Gson();
- list = gson.fromJson(jsonString, new TypeToken<List<String>>() {
- }.getType());
- } catch (Exception e) {
- // TODO: handle exception
- }
- return list;
- }
- public static List<Map<String,Object>> listKeyMap(String jsonString){
- List<Map<String,Object>> list=new ArrayList<Map<String,Object>>();
- try {
- Gson gson = new Gson();
- list = gson.fromJson(jsonString, new TypeToken<List<Map<String,Object>>>() {
- }.getType());
- } catch (Exception e) {
- // TODO: handle exception
- }
- return list;
- }
- }
使用Gson详解