【攻克Android (40)】JSON解析
本文围绕以下三个部分展开:
一、JSON解析
二、Gson
三、Fast-json
一、JSON解析
1.基本概念
JSON:JavaScriptObjectNotation,是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。
它基于JavaScriptProgrammingLanguage,StandardECMA-2623rdEdition-December1999的一个子集。
JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C,C++,C#,Java,JavaScript,Perl,Python等)。它通用于C,C++,C#,Java,JavaScript,Perl,Python,PHP等编程语言的数据交换传输。
2.JSON基本结构
(1)对象
名值对的集合(Acollectionofname/valuepairs)。
一个对象以“{”(左括号)开始,“}”(右括号)结束。每个“名称”后跟一个“:”(冒号)。名值对之间使用“,”(逗号)分隔。
var myobj ={"name":"Tom","age":20};
(2)数组
值的有序列表(Anorderedlistofvalues)。
3.JSON具有以下这些形式:对象(object)、数组(array)、值(value)、字符串(string)、数值(number)。
JSON解析案例
创建测试类:JsonTest,继承自InstrumentationTestCase类,用于单元测试。
package com.android.dataparsing; import android.test.InstrumentationTestCase; /** * Created by Xiangdong on 2015/9/5. */ public class JsonTest extends InstrumentationTestCase { }
1.将java对象转化为JSON对象/数组
package com.android.dataparsing; import android.test.InstrumentationTestCase; import android.util.Log; import org.json.JSONArray; import org.json.JSONObject; /** * Created by Xiangdong on 2015/9/5. */ public class JsonTest extends InstrumentationTestCase { private static final String TAG = "MainActivity"; /** * 将 java对象 转化为 JSON 对象/数组 * * @throws Exception */ public void testObject2Json() throws Exception { // 情况1:java对象 -> JSON对象 JSONObject jsonObject = new JSONObject(); jsonObject.put("name", "段誉"); jsonObject.put("age", 16); // 输出:{"name":"段誉","age":16} Log.v(TAG, jsonObject.toString()); // 情况2:JSON对象中嵌套JSON对象 JSONObject addressObj = new JSONObject(); addressObj.put("city", "长沙"); addressObj.put("street", "南阳街"); // 嵌套 jsonObject.put("address", addressObj); // 输出:{"name":"段誉","age":16,"address":{"city":"长沙",""street","南阳街"}} Log.v(TAG, jsonObject.toString()); // 情况3:java对象 -> JSON数组 JSONArray ja = new JSONArray(); ja.put("130"); ja.put("155"); ja.put("188"); // 输出:["130","155","188"] Log.v(TAG, ja.toString()); // 情况4:JSON对象中嵌套JSON数组 jsonObject.put("phone", ja); // 输出:{"name":"段誉","age":16,"address":{"city":"长沙","street":"南阳街"},"phone":["130","155","188"]} Log.v(TAG, jsonObject.toString()); } }
2.JSON格式的字符串转换为JSON对象;JSON对象转换为字符串。
package com.android.dataparsing; import android.test.InstrumentationTestCase; import android.util.Log; import org.json.JSONObject; /** * Created by Xiangdong on 2015/9/5. */ public class JsonTest extends InstrumentationTestCase { private static final String TAG = "MainActivity"; /** * JSON格式的字符串 转换为 JSON对象; * JSON对象 转换为 字符串 * * @throws Exception */ public void testJson2Object() throws Exception { String json = "{'name':'Tom','age':20}"; // 情况1:将 JSON格式的字符串 转为 JSON对象 JSONObject jsonObj = new JSONObject(json); // 输出:{"name":"Tom","age":"20"} - 引号就没有了。 Log.v(TAG, jsonObj.toString()); // 情况2:将JSON对象转换为 字符串 String name = jsonObj.getString("name"); int age = jsonObj.getInt("age"); String text = String.format("%s,%d", name, age); // 输出:String->JSON: Tom,20 Log.v(TAG, "JSON->String: " + text); } }
3.JSON数组格式的字符串转换为JSON数组;JSON数组中的每一项转换为字符串。
package com.android.dataparsing; import android.test.InstrumentationTestCase; import android.util.Log; import org.json.JSONArray; /** * Created by Xiangdong on 2015/9/5. */ public class JsonTest extends InstrumentationTestCase { private static final String TAG = "MainActivity"; /** * JSON数组格式的字符串 转换为 JSON数组; * JSON数组中的每一项 转换为 字符串 * * @throws Exception */ public void testArray2Object() throws Exception { String json = "[jack,tom,rose]"; JSONArray array = new JSONArray(json); for (int i = 0; i < array.length(); i++) { String s = String.format("%s", array.get(i)); // jack // tom // rose Log.v(TAG, s); } } }
4.读取JSON格式的文本文件,并进行解析。
(1)先创建/导入json.txt/json.json(是一个json格式文本文件)到java目录下面。
[ {"name":"段誉","age":"16","sex":"男","address":"大理"}, {"name":"王语嫣","age":"17","sex":"女","address":"姑苏"}, {"name":"乔峰","age":"32","sex":"男","address":"契丹"}, {"name":"Tom","age":"20","sex":"M","address":"New York"} ]
(2)将json.txt打包成jar包,并放到libs目录下,这样才能读取。
(3)读取JSON格式的文本文件,并进行解析。
package com.android.dataparsing; import android.test.InstrumentationTestCase; import android.util.Log; import org.json.JSONArray; import org.json.JSONObject; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; /** * Created by Xiangdong on 2015/9/5. */ public class JsonTest extends InstrumentationTestCase { private static final String TAG = "MainActivity"; /** * 读取 JSON 格式的文本文件,并进行解析 * * @throws Exception */ public void testReadFile() throws Exception { // 读取文件到缓冲 InputStream in = getClass().getClassLoader() .getResourceAsStream("json.txt"); // 用 BufferedReader 包装(因为要用文件的内容,因此要通过这个流去读) BufferedReader reader = new BufferedReader(new InputStreamReader(in)); // 情况1:文件内容 转换为 字符串 // 方法(1):使用 StringBuilder。 // StringBuilder 类似于 StringBuffer,用来拼接字符串 StringBuilder builder = new StringBuilder(); String line; while ((line = reader.readLine()) != null) { builder.append(line); } // json.txt文件的内容 String data = builder.toString(); Log.v(TAG, data); // 方法(2):使用 String。 String s = ""; String line2; while ((line2 = reader.readLine()) != null) { s += line2; } // json.txt文件的内容 Log.v(TAG, s); // 情况2:将JSON数组格式的字符串 转换为 JSON数组 JSONArray ja = new JSONArray(data); // 情况3:从 JSON数组 中取出每个 JSON对象 for (int i = 0; i < ja.length(); i++) { JSONObject jsonObj = ja.getJSONObject(i); // 情况4:将 JSON对象 转换为 字符串 String name = jsonObj.getString("name"); String age = jsonObj.getString("age"); String sex = jsonObj.getString("sex"); String address = jsonObj.getString("address"); String text = String.format("%s,%s,%s,%s", name, age, sex, address); Log.v(TAG, text); } } }
二、Gson
1.概念
Gson是Google提供的用来在Java对象和JSON数据之间进行映射的Java类库。
可以将一个JSON字符串转成一个Java对象,或者反过来。
也可以通过Simple转换XML。
2.特点
(1)快速、高效
(2)代码量少、简洁
(3)面向对象
(4)数据传递和解析方便
3.jar和源码下载地址:http://code.google.com/p/google-gson/downloads/list
4.基本用法
(1)定义实体类
(2)根据需要可以将JSON生成单个实体或列表实体集合
Gson解析案例
1.将gson-2.2.2.jar包和simple-xml-2.6.9.jar包放到libs下面。
2.在java目录下创建com.android.gson目录,里面创建三个类:Book、BookList和BookService。
(1)Book.java:
package com.android.gson; import org.simpleframework.xml.Element; import org.simpleframework.xml.Root; /** * 创建1本书的pojo类。 * * * 对应的XML结构: * <Book> * <isbn> * <title> * <author> * <image> * </Book> * * * Created by XiangdongLee on 2015/9/7 */ @Root // 此处Root后面没有起名字,因此默认的根元素为:类名(Book) public class Book { @Element private String isbn; // 编号 @Element private String title; @Element private String author; @Element(required = false) // 允许没有图片 private String image; public Book() { } public Book(String isbn, String title, String author, String image) { this.isbn = isbn; this.title = title; this.author = author; this.image = image; } @Override public String toString() { return "Book [isbn=" + isbn + ", title=" + title + ", author=" + author + ", image=" + image + "]"; } public String getIsbn() { return isbn; } public void setIsbn(String isbn) { this.isbn = isbn; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } public String getImage() { return image; } public void setImage(String image) { this.image = image; } }
(2)BookList.java:
package com.android.gson; import org.simpleframework.xml.ElementList; import org.simpleframework.xml.Root; import java.util.LinkedList; /** * 创建多本书(集合)的pojo类。 * * * 对应的XML结构: * <book-list> * <Book> * <isbn> * <title> * <author> * <image> * </Book> * * <Book> * <isbn> * <title> * <author> * <image> * </Book> * </book-list> * * * Created by XiangdongLee on 2015/9/7 */ @Root(name = "book-list") // 此处Root后面根元素重新起了名字,因此根元素名字为:book-list public class BookList { @ElementList(inline = true) // 元素列表 private LinkedList<Book> list; public BookList() { list = new LinkedList<Book>(); // 构造方法中创建出集合 } public LinkedList<Book> getList() { return list; } public void setList(LinkedList<Book> list) { this.list = list; } public void addBook(Book book) { list.add(book); } public int size() { return list.size(); } public void set(int index, Book element) { list.set(index, element); } public Book get(int index) { return list.get(index); } @Override public String toString() { return "BookList [list=" + list + "]"; } }
(3)BookService.java:
package com.android.gson; /** * Created by XiangdongLee on 2015/9/7 */ public class BookService { private static BookList list = new BookList(); // 放在 static静态块中:只要应用程序不结束,就一直存在 // 这些数据相当于来自数据库的数据 static { list.addBook(new Book("9787506287081", "认识电影", "路易斯·贾内梯", "/images/1.jpg")); list.addBook(new Book("9787513300711", "失控", "凯文·凯利", "/images/2.jpg")); list.addBook(new Book("9787115293800", "算法", "Robert", "/images/3.jpg")); list.addBook(new Book("9787544704007", "悲剧的诞生", "尼采", "/images/4.jpg")); list.addBook(new Book("9787506285728", "社会学与生活", "理查德.谢弗", "/images/5.jpg")); list.addBook(new Book("9787544707206", "万有引力之虹", "托马斯·品钦", "/images/6.jpg")); list.addBook(new Book("9787229042066", "地球往事", "刘慈欣", "/images/7.jpg")); list.addBook(new Book("9787229047221", "冰与火之歌", "乔治·马丁", "/images/8.jpg")); } public static BookList getBookList() { return list; } public static void addBook(Book book) { list.addBook(book); } }
3.创建测试类:GsonTest,继承自InstrumentationTestCase类,进行单元测试。
package com.android.dataparsing; import android.test.InstrumentationTestCase; import com.android.gson.Book; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import org.simpleframework.xml.core.Persister; import java.lang.reflect.Type; import java.util.List; /** * Created by XiangdongLee on 2015/9/7. */ public class GsonTest extends InstrumentationTestCase { private static final String TAG = "MainActivity"; private Gson gson; private Type bookListType; private Persister persister; /** * 重写测试案例中的初始化方法:用来初始化 Gson * * @throws Exception */ @Override protected void setUp() throws Exception { gson = new Gson(); bookListType = new TypeToken<List<Book>>(){ }.getType(); persister = new Persister(); } }
4.Gson解析
使用Gson把集合数据转换为json格式的字符串,然后再把json格式的字符串转换为java对象。
package com.android.dataparsing; import android.test.InstrumentationTestCase; import android.util.Log; import com.android.gson.Book; import com.android.gson.BookList; import com.android.gson.BookService; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; import org.json.JSONArray; import org.json.JSONObject; import org.simpleframework.xml.core.Persister; import java.lang.reflect.Type; import java.util.List; /** * Created by XiangdongLee on 2015/9/7. */ public class GsonTest extends InstrumentationTestCase { private static final String TAG = "MainActivity"; private Gson gson; private Type bookListType; private Persister persister; /** * 重写测试案例中的初始化方法:用来初始化 Gson * * @throws Exception */ @Override protected void setUp() throws Exception { gson = new Gson(); bookListType = new TypeToken<List<Book>>(){ }.getType(); persister = new Persister(); } /** * 使用 Gson 把 集合数据 转换为 json格式的字符串, * 然后再把 json格式的字符串 转换为 java对象。 */ public void testToJsonFromList() throws Exception{ BookList list = BookService.getBookList(); Log.v(TAG, list.toString()); // 情况1:使用 Gson 把集合数据转换为 json格式的字符串 String json = gson.toJson(list.getList(), bookListType); Log.v(TAG,json); // 情况2:使用 Gson把 json格式的字符串 转换为 java对象 Book book = gson.fromJson(json, Book.class); // Book [isbn=9787506287081, title=认识电影, author=路易斯·贾内梯, image=/images/1.jpg] Log.v(TAG,book.toString()); // 情况2.1:也可以通过JSON把 json格式的字符串 转换为 json数组 JSONArray ja = new JSONArray(json); for(int i=0;i<ja.length();i++){ // 拿到 json对象中的 某一个值("title")。 JSONObject jsonObj = ja.getJSONObject(i); // Log.v(TAG,jsonObj.toString()); Log.v(TAG,jsonObj.getString("title")); } } }
三、Fast-json
1.概念
Fastjson是一个性能很好的Java语言实现的JSON解析器和生成器,来自阿里巴巴的工程师开发。它具有极快的性能,宣称超越任其他的JavaJsonparser。
2.特点
(1)快速:比其它任何基于Java的解析器和生成器更快,包括jackson。
(2)强大:支持普通JDK类包括任意JavaBeanClass、Collection、Map、Date或enum。
(3)零依赖:没有依赖其它任何类库除了JDK。
(4)支持注解、支持全类型序列化。
3.基本用法
(1)定义实体类
(2)根据需要可以将JSON生成单个实体或列表实体集合
Fast-json解析案例
以后补充