`
XiangdongLee
  • 浏览: 86946 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

【攻克Android (40)】JSON解析

阅读更多
本文围绕以下三个部分展开:

一、JSON解析
二、Gson
三、Fast-json





一、JSON解析

        1. 基本概念

        JSON: JavaScript Object Notation,是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。

        它基于JavaScript Programming Language, Standard ECMA-262 3rd Edition - December 1999的一个子集。

        JSON采用完全独立于语言的文本格式,但是也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等)。它通用于C, C++, C#, Java, JavaScript, Perl, Python, PHP等编程语言的数据交换传输。


        2. JSON基本结构

        (1)对象

        名值对的集合(A collection of name/value pairs)。

        一个对象以“{”(左括号)开始,“}”(右括号)结束。每个“名称”后跟一个“:”(冒号)。名值对之间使用“,”(逗号)分隔。

var myobj ={"name":"Tom","age":20};


        (2)数组

        值的有序列表(An ordered list of values)。


        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 解析器和生成器,来自阿里巴巴的工程师开发。它具有极快的性能,宣称超越任其他的Java Json parser。


        2. 特点

        (1)快速:比其它任何基于Java的解析器和生成器更快,包括jackson。

        (2)强大:支持普通JDK类包括任意Java Bean Class、Collection、Map、Date或enum。

        (3)零依赖:没有依赖其它任何类库除了JDK。

        (4)支持注解、支持全类型序列化。


        3. 基本用法

        (1)定义实体类

        (2)根据需要可以将JSON生成单个实体或列表实体集合


Fast-json解析案例

        以后补充

0
1
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics