1. 程式人生 > >Json資料的序列化與反序列化的三種常用方法介紹

Json資料的序列化與反序列化的三種常用方法介紹

       以下內容是本作者從官網中看相應的教程後所做的demo,其體現了作者對相關知識點的個人理解。。作者才疏學淺,難免會有理解不到位的地方。。還請各位讀者批判性對待。。。

       本文主要介紹在Json資料的序列化與反序列化的過程中我經常用到的三種工具的基本使用方法,及其他們之間

的比較。。。希望能夠對讀者們有一些幫助。。。

這裡介紹到的三種解析與生成Json資料的方法分別是:標準JSON解析與生成方法、使用gson解析與生成JSON資料

、使用fastJsson解析與生成JSON資料。

首先,這些工具都可以到相應的官網中下載。以下給出我所用到的jar包的下載連結:

1)標準JSON所用到的jar包:http://download.csdn.net/detail/caihongshijie6/6701285

2)gson所用到的jar包:http://download.csdn.net/detail/caihongshijie6/7260481

3)fastjson所用到的jar包:http://download.csdn.net/detail/caihongshijie6/7260485

一、對於JSON資料的描述

       JSON是一種輕量級的資料交換格式(個人認為在很多方面上,其優於XML)。我個人將其資料形式總結如下:

{}表示一個物件,以  鍵:值  對的形式給出物件的內部成員及成員變數的值。多個內部成員之間用 逗號,來隔開。

集合和陣列都用[]來表示。

       更詳盡的關於JSON的描述請參考其官網:http://www.json.org/   (裡面也有各種各樣的解析工具)

二、使用標準JSON的解析與生成方法

 1、首先寫一個我們會用到的pojo類

public class Person {

	private int id;
	private String name;
	private String address;
	
	public Person() {
		
	}

	public Person(int id, String name, String address) {
		super();
		this.id = id;
		this.name = name;
		this.address = address;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	@Override
	public String toString() {
		return "Person [id=" + id + ", name=" + name + ", address=" + address
				+ "]";
	}
	
	
	
}

2、使用標準JSON進行生成與解析
package com.njupt.pojo;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

public class Main {

	public static void main(String[] args) {
		
		/**
		 * 生成JSON字串
		 * 
		 */
		//物件
		Person person = new Person(1, "haungjundong","beijing");
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("hjd", person);
//		System.out.println("--------------");
//		System.out.println(jsonObject.toString());
//		System.out.println("--------------");
		
		
		//基本資料型別
		jsonObject.put("int", 123);
//		System.out.println("--------------");
//		System.out.println(jsonObject.toString());
//		System.out.println("--------------");
		
		jsonObject.put("string", "hello world");
//		System.out.println("--------------");
//		System.out.println(jsonObject.toString());
//		System.out.println("--------------");
		
		//陣列
		int arr[] = new int[10];
		for(int i = 0 ; i < 10 ; ++i){
			arr[i] = i;
		}
		jsonObject.put("arr", arr);
//		System.out.println("--------------");
//		System.out.println(jsonObject.toString());
//		System.out.println("--------------");
		
		/**
		 * 生成集合型別資料(1)
		 * 為什麼不使用List<基本型別>來距離呢???
		 * 因為"基本型別的集合"已經有一種形式來表示了:-------->陣列
		 * 如果一定要的話,輕易List<Integer>,然後做一個demo
		 */
		List<String> strList = new ArrayList<String>();
		for(int i = 0 ; i < 10 ; ++i){
			strList.add("str" + i);
		}
		jsonObject.put("strList", strList);
//		System.out.println("--------------");
//		System.out.println(jsonObject.toString());
//		System.out.println("--------------");
		
		//生成集合型別資料(2)
		List<Person> personList = new ArrayList<Person>();
		for(int i = 0 ; i < 10 ; ++i){
			personList.add(new Person(i, "hjd" + i, "beijing" + i));
		}
		jsonObject.put("personList", personList);
//		System.out.println("--------------");
//		System.out.println(jsonObject.toString());
//		System.out.println("--------------");
		
		/**
		 * 生成集合型別資料(3)
		 * 
		 * 1)
		 * Caused by: java.lang.ClassCastException: 
		 * JSON keys must be strings.------->JSON物件中的key必須是一個String型別的(字串)
		 * 
		 * 2)對於下面,可以這樣理解(可能有一點不太準確,但是方便理解)
		 * map是一個物件,key為其內部成員,value是key的值
		 */
		List<Map> mapList = new ArrayList<Map>();
		for(int i = 0 ; i < 10 ; ++i){
			Map map = new HashMap<String, Integer>();
			map.put("" + i, 10+i);
			
			mapList.add(map);
		}
		jsonObject.put("mapList", mapList);
		System.out.println("--------------");
		System.out.println(jsonObject.toString());
		System.out.println("--------------");
		

		System.out.println("------------------->解析json字串");
		String jsonString = jsonObject.toString();//將jsonObject轉換成json字串
		
		
		JSONObject jsonObject2 = JSONObject.fromObject(jsonString);//利用json字串生成json物件
		
		//解析Person物件
		Person person2 = new Person();
		
//		JSONObject personObject = (Person) jsonObject2.get("hjd");//*****這種寫法是錯的,原生的json的解析方法並不支援將json字串自動轉成相應的物件...
		JSONObject personObject = (JSONObject) jsonObject2.get("hjd");//第一種寫法
//		JSONObject personObject = jsonObject2.getJSONObject("hjd");//第二種寫法
		person2.setId(personObject.getInt("id"));
		person2.setName(personObject.getString("name"));
		person2.setAddress(personObject.getString("address"));
		System.out.println("--------------->person2: " + person2);
		
//		System.out.println("person2.getId(): " + person2.getId() + ",person2.getAddress(): " + person2.getAddress() + ",person2.getName()" + person2.getName());

		//解析基本資料型別
		int num = jsonObject2.getInt("int");
//		System.out.println("---->num: " + num);
		
		
		//解析基本型別的陣列陣列
		JSONArray arrArray = jsonObject2.getJSONArray("arr");
		int size = arrArray.size();
		int arr2[] = new int[size];
		for(int i = 0 ; i < size ; ++i){
			arr2[i] = arrArray.getInt(i);
		}
//		System.out.println(Arrays.toString(arr2));
		
		//解析List<String>
		JSONArray strArray = jsonObject2.getJSONArray("strList");
		List<String> strList2 = new ArrayList<String>();
		int size2 = strArray.size();
		for(int i = 0 ; i < size2 ; ++i){
			strList2.add(strArray.getString(i));
		}
//		System.out.println("---------->" + strList2);
		
		
		//解析List<Person>
		JSONArray personArray = jsonObject2.getJSONArray("personList");
		List<Person> personList2 = new ArrayList<Person>();
		int size3 = personArray.size();
		for(int i = 0 ; i< size3 ; ++i){
			JSONObject jObject = personArray.getJSONObject(i);
			Person p = new Person();
			
			p.setId(jObject.getInt("id"));
			p.setName(jObject.getString("name"));
			p.setAddress(jObject.getString("address"));
			
			personList2.add(p);
		}
		
//		System.out.println("----------->" + personList2);
		
		
		//解析List<Map>
		JSONArray mapArray = jsonObject2.getJSONArray("mapList");
		List<Map> mapList2 = new ArrayList<Map>();
		int size4 = mapArray.size();
		for(int i = 0 ; i < size4 ; ++i){
			JSONObject jo = mapArray.getJSONObject(i);
			Map m = new HashMap<String, Integer>();
			m.put("" + i, jo.getInt("" + i));
			
			mapList2.add(m);
		}
		System.out.println("--------------->" + mapList2);
	}
}

小結一下:使用標準JSON進行解析時,主要用到的API如下:

生成:

Person person = new Person(1, "haungjundong","beijing");
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("hjd", person);

解析時:舉例如下

[]:jsonObject2.getJSONArray("arr");

{}:jsonObject2.getJSONObject("hjd");

基本資料型別:jsonObject2.getInt("int");

jsonObject.toString() ---->>將json物件轉換成json格式的字串

JSONObject jsonObject2 = JSONObject.fromObject(jsonString); -------->>利用json字串生成json物件

二、使用gson進行生成與解析

1、Person類的程式碼同上

2、使用gson進行生成與解析

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.google.gson.Gson;


public class Main {

	public static void main(String[] args) {
		
		/**
		 * 使用gson來生成JSON字串
		 */
		//物件
		Person person = new Person(1, "haungjundong","beijing");
		
		Gson gson = new Gson();
		String personStr = gson.toJson(person);
//		System.out.println( "----------->" + personStr);
		
		Person person2 = gson.fromJson(personStr, Person.class);
//		System.out.println("------>person2: " + person2);
		
		//陣列
		int arr[] = new int[10];
		for(int i = 0 ; i < 10 ; ++i){
			arr[i] = i;
		}
		String arrStr = gson.toJson(arr);
//		System.out.println(arrStr);
		
		int arr2[] = gson.fromJson(arrStr,int[].class);//****這是要注意的地方之一..
//	    System.out.println(Arrays.toString(arr2));
		
		
		/**
		 * 生成集合型別資料(1)
		 * 
		 * 無論是List<String>還是List<Person>還是List<Map>
		 * 其利用json字串生成物件的時候,其型別都是List.class
		 */
		List<String> strList = new ArrayList<String>();
		for(int i = 0 ; i < 10 ; ++i){
			strList.add("str" + i);
		}
		String strListStr = gson.toJson(strList);
//		System.out.println("----------->" + strListStr);
		
		List<String> strList2 = gson.fromJson(strListStr, List.class);
//		System.out.println(strList2);
		
		//生成集合型別資料(2)
		List<Person> personList = new ArrayList<Person>();
		for(int i = 0 ; i < 10 ; ++i){
			personList.add(new Person(i, "hjd" + i, "beijing" + i));
		}
		String personListJsonStr = gson.toJson(personList);
//		System.out.println(personListJsonStr);
		
		List<Person> personList2 = gson.fromJson(personListJsonStr, List.class);
		/**
		 * [{id=0.0, name=hjd0, address=beijing0}, {id=1.0, name=hjd1, address=beijing1}, {id=2.0, name=hjd2, address=beijing2}, {id=3.0, name=hjd3, address=beijing3}, {id=4.0, name=hjd4, address=beijing4}, {id=5.0, name=hjd5, address=beijing5}, {id=6.0, name=hjd6, address=beijing6}, {id=7.0, name=hjd7, address=beijing7}, {id=8.0, name=hjd8, address=beijing8}, {id=9.0, name=hjd9, address=beijing9}]
		 */
//		System.out.println(personList2);
		
		/**
		 * 生成集合型別資料(3)
		 * 
		 * 1)
		 * Caused by: java.lang.ClassCastException: 
		 * JSON keys must be strings.------->JSON物件中的key必須是一個String型別的(字串)
		 * 
		 * 2)對於下面,可以這樣理解(可能有一點不太準確,但是方便理解)
		 * map是一個物件,key為其內部成員,value是key的值
		 */
		List<Map> mapList = new ArrayList<Map>();
		for(int i = 0 ; i < 10 ; ++i){
			Map map = new HashMap<String, Integer>();
			map.put("" + i, 10+i);
			
			mapList.add(map);
		}
		String mapListJsonStr = gson.toJson(mapList);
//		System.out.println(mapListJsonStr);
	
		List<Map> mapList2 = gson.fromJson(mapListJsonStr, List.class);
//		System.out.println(mapList2);
	}
}


小結:

1)生成JSON資料:舉例

Gson gson = new Gson();
String personStr = gson.toJson(person);
2)解析JSON資料:舉例
Person person2 = gson.fromJson(personStr, Person.class);
Person person2 = gson.fromJson(personStr, Person.class);

特別需要注意的是:

基本型別資料的解析方式: int[].class

List型別資料的解析方式: List.class  (無論是List<String>還是List<Map>還是,List<Person>都是用的是這個)

其實大家可以發現,我們在生成與解析的時候只是調一下gson這個物件的方法而已。除此之外,專門生成一個

gson物件似乎沒有什麼用。。。

是的,我是這麼認為的。我想阿里巴巴的那幫哥們也是這麼想的。所以在對效能進行進一步優化的同時,他們

把解析的方法對做成靜態的了。。。這樣就不需要專門生成一個物件才能使用相應的方法

三、使用fastjson進行生成與解析、

特別提醒:使用fastjson將json字串轉成List<javabean>物件時,儘量使用以下方式

List<Person> persons2 = JSON.parseArray(jsonString,Person.class);

1、Person類的程式碼是一樣的

2、

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSON;



public class Main {

	public static void main(String[] args) {
		
		/**
		 * 使用gson來生成JSON字串
		 */
		//物件
		Person person = new Person(1, "haungjundong","beijing");
		String personStr = JSON.toJSONString(person);//利用物件生成JSON字串
//		System.out.println(personStr);
		Person person2 = JSON.parseObject(personStr, Person.class);//利用JSON字串生成Person物件
//		System.out.println(person2);
		
		
		//陣列
		int arr[] = new int[10];
		for(int i = 0 ; i < 10 ; ++i){
			arr[i] = i;
		}
		String arrStr = JSON.toJSONString(arr);
//		System.out.println(arrStr);
		int arr2[] = JSON.parseObject(arrStr, int[].class);
//		System.out.println(Arrays.toString(arr2));
		
		/**
		 * 生成集合型別資料(1)
		 * 
		 * 無論是List<String>還是List<Person>還是List<Map>
		 * 其利用json字串生成物件的時候,其型別都是List.class
		 */
		List<String> strList = new ArrayList<String>();
		for(int i = 0 ; i < 10 ; ++i){
			strList.add("str" + i);
		}
		String strListJSONStr = JSON.toJSONString(strList);
//		System.out.println(strListJSONStr);
		List<String> strList2 = JSON.parseObject(strListJSONStr, List.class);
//		System.out.println(strList2);
		
		//生成集合型別資料(2)
		List<Person> personList = new ArrayList<Person>();
		for(int i = 0 ; i < 10 ; ++i){
			personList.add(new Person(i, "hjd" + i, "beijing" + i));
		}
		String personListJSONStr = JSON.toJSONString(personList);
		/**
		 * 以下語句的列印結果
		 * [{"address":"beijing0","id":0,"name":"hjd0"},{"address":"beijing1","id":1,"name":"hjd1"},{"address":"beijing2","id":2,"name":"hjd2"},{"address":"beijing3","id":3,"name":"hjd3"},{"address":"beijing4","id":4,"name":"hjd4"},{"address":"beijing5","id":5,"name":"hjd5"},{"address":"beijing6","id":6,"name":"hjd6"},{"address":"beijing7","id":7,"name":"hjd7"},{"address":"beijing8","id":8,"name":"hjd8"},{"address":"beijing9","id":9,"name":"hjd9"}]
		 */
//		System.out.println(personListJSONStr);
		List<Person> personList2 = JSON.parseObject(personListJSONStr, List.class);
		/**
		 * 以下語句的列印結果
		 * [Person [id=0, name=hjd0, address=beijing0], Person [id=1, name=hjd1, address=beijing1], Person [id=2, name=hjd2, address=beijing2], Person [id=3, name=hjd3, address=beijing3], Person [id=4, name=hjd4, address=beijing4], Person [id=5, name=hjd5, address=beijing5], Person [id=6, name=hjd6, address=beijing6], Person [id=7, name=hjd7, address=beijing7], Person [id=8, name=hjd8, address=beijing8], Person [id=9, name=hjd9, address=beijing9]]
		 */
//		System.out.println(personList);
		
		/**
		 * 生成集合型別資料(3)
		 * 
		 * 1)
		 * Caused by: java.lang.ClassCastException: 
		 * JSON keys must be strings.------->JSON物件中的key必須是一個String型別的(字串)
		 * 
		 * 2)對於下面,可以這樣理解(可能有一點不太準確,但是方便理解)
		 * map是一個物件,key為其內部成員,value是key的值
		 */
		List<Map> mapList = new ArrayList<Map>();
		for(int i = 0 ; i < 10 ; ++i){
			Map map = new HashMap<String, Integer>();
			map.put("" + i, 10+i);
			
			mapList.add(map);
		}
		String mapListJSONStr = JSON.toJSONString(mapList);
//		System.out.println(mapListJSONStr);
		List<Map> mapList2 = JSON.parseObject(mapListJSONStr, List.class);
//		System.out.println(mapList2);
		
	}
}

小結:

1)生成JSON格式的資料

JSON.toJSONString(person);//利用物件生成JSON字串

2)解析JSON格式的資料

JSON.parseObject(arrStr, int[].class);

注意:

fastjson與gson的使用方式很像。但是在一些細節方面上還是用有區別的。這些細節上的差別在伺服器與客戶端的資料進行互動的時候可能產生的影響是很大的。還請各位讀者認真思考在使用。個人比較傾向於使用fastjson,個人認為他在一些細節方面處理得要比google的gson處理得好。。。

四、三者之間的比較

標準JSON的生成與解析方法與gson、fastjson之間最大的區別就在於:標準JSON的生成與解析方法無法利用JSON

資料自動生成相應的物件和資料。使用標準JSON進行生成相應的物件時,只能是一個一個的獲取器成員變數的資料,然後一個一個地set()。。

五、寫在最後

更多的只是還請各位讀者到相應的官網去查詢相應的教程。。如果有錯誤還請多多包涵並且批評指出(不要吐槽的太厲害哈~~~~吐舌頭)

六、原始碼下載

http://download.csdn.net/detail/caihongshijie6/7260637