欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【攻克Android (40)】JSON解析

程序员文章站 2024-01-19 10:10:34
...
本文围绕以下三个部分展开:

一、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类,用于单元测试。

【攻克Android (40)】JSON解析
            
    
    博客分类: 攻克Android系列 AndroidJSON解析Gson解析Fast-json解析数据解析 


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());
    }
}


【攻克Android (40)】JSON解析
            
    
    博客分类: 攻克Android系列 AndroidJSON解析Gson解析Fast-json解析数据解析 



        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);
    }
}


【攻克Android (40)】JSON解析
            
    
    博客分类: 攻克Android系列 AndroidJSON解析Gson解析Fast-json解析数据解析 



        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);
        }
    }
}


【攻克Android (40)】JSON解析
            
    
    博客分类: 攻克Android系列 AndroidJSON解析Gson解析Fast-json解析数据解析 



        4. 读取 JSON 格式的文本文件,并进行解析。

        (1)先创建/导入 json.txt/json.json(是一个json格式 文本文件) 到 java目录下面。

【攻克Android (40)】JSON解析
            
    
    博客分类: 攻克Android系列 AndroidJSON解析Gson解析Fast-json解析数据解析 


[
 {"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目录下,这样才能读取。

【攻克Android (40)】JSON解析
            
    
    博客分类: 攻克Android系列 AndroidJSON解析Gson解析Fast-json解析数据解析 


        (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);
        }
    }
}


【攻克Android (40)】JSON解析
            
    
    博客分类: 攻克Android系列 AndroidJSON解析Gson解析Fast-json解析数据解析 




二、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下面。

【攻克Android (40)】JSON解析
            
    
    博客分类: 攻克Android系列 AndroidJSON解析Gson解析Fast-json解析数据解析 



        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解析案例

        以后补充