Gson项目使用全解析

Gson项目使用全解析

概述

json的解析jar包很多,有gson,fastjson,net.sf.json,org.json等等,做为开发人员只要了解一种或2种工具即可,人推荐gson和fastjson,因为gson稳定,容错率好,是goole出的,而且fastjson号称最快,也是不错的选择。

开始之前,先介绍一下json的数据格式,相信大家都见过json格式数据,它的语法是:

1.数据在名称/值对中

2.数据由逗号分隔

3.花括号保存对象

4.方括号保存数组

但现在比如:

{

   [{

            "id": "h1",

            "name": "历史"

   },

   {

            "id": "h2",

            "name": "音乐"

   }]

}

是不是json格式数据呢??

Gson是把json格式字符串与Java对象转化的,注意,是序列化和反序列化的,命中注定在java里会有一个对象与json数据对应的。可能是基本类型int,boolean等或者是Map,List又或者是自定义类型。


1 反序列化

1.1先介绍一些概念

1.1.1  JsonParse

json数据解析,Gson框架里的“Json”的意思都是“json数据或者叫json格式字符串”,比如fromJson()是从Json字符串里解析出对象,toJson()是把对象转成Json字符串,同理JsonParse意思也一样,是Json字符串解析。通过 getAsJsonObject 和 getAsJsonArray 解析成 JsonObject 和 JsonArray。

1.1.2  JsonElement

抽象出来的类,是框架里除了基本类型外的可操作的类型,可能是JsonObject,JsonArray或其它。如果看源码会发现比如JsonObject的add方法可添加的对象就是JsonElemet子类,所以,大家别想把自定义对象添加到JsonObject或JsonArray对象里,除非你把对象先序列化一样,再把序列化后的数据转成JsonObject.

1.1.3 JsonObject

即json数据里大括号的引用,在反序列化时使用

1.1.4   JsonArray

即json数据里中括号的引用,在反序列化时使用


1.2 各种不同情况数据的解析。(以下我把json数据放到文本文件里,避免在java里使用过来的转义符)

1.2.1 反序列化成自定义对象,同时也介绍映射到了List里

比如如下数据:
{
	"name": "陈陈",
	"age": 24,
	"emailAddress": null,
	"bookes": ["化学","物理"],
	"bookList":[
		{"id":"h1","name":"历史"},{"id":"h2","name":"音乐"}
	]
}


定义一个对象,能包裹整个json数据:
public class User {
	private String name;
	private int age;
	private String emailAddress;
	private String[] bookes = {"化学", "物理"};
	private List bookList;
	….getter/setter省略
}


public class Book {
	private String id;
private String name;
….getter/setter省略
}


程序:
@Test
	public void testGson() {
		try {
Reader reader = new InputStreamReader(JsonToken.class.getResourceAsStream("/com/cy/vo/es1/data.json"), "UTF-8");
			Gson gson = new GsonBuilder().create();
			User p = gson.fromJson(reader, User.class);
			System.out.println(p);
		}catch (Exception e) {
			// TODO: handle exception
			System.out.println(e);
		}
	}
结果是把整个Json数据映射到User对象里。


1.2.2 反序列化成Map

json数据:
{
			"name": "怪盗kidou",
			"age": 24
}


程序:
@Test
	public void testStr2Map() {
		try {
Reader reader = new InputStreamReader(JsonToken.class.getResourceAsStream("/com/cy/vo/es1/data1.json"), "UTF-8");
			Gson gson = new GsonBuilder().create();
			Map p = gson.fromJson(reader, Map.class);
			System.out.println(p);
		}catch (Exception e) {
			// TODO: handle exception
			System.out.println(e);
		}
}
结果成功映射到Map里。


1.2.3 自己控制

上面的功能感受有些限制,因为大部分工作都是Gson来做了,我们没法手动限制处理哪块数据。使用我上面介绍的JsonObject,JsonArray
比如json数据:
{ "list":
		[
			{"id":"h1","name":"历史"},{"id":"h2","name":"音乐"}
		]
}


由于有大括号里有个key,每个key对应一个数组,拿到大括号数据用JsonObject,拿到数组对象用JsonArray。
所以程序是这样的:
@Test
	public void testStr2List2() {
		try {
			List result = new ArrayList<>();
			Reader reader = new InputStreamReader(JsonToken.class.getResourceAsStream("/com/cy/vo/es1/data2.json"), "UTF-8");
			Gson gson = new GsonBuilder().create();
			//Json的解析类对象
		    JsonParser parser = new JsonParser();
//获得大括号的引用
		    JsonObject jsonObject = parser.parse(reader).getAsJsonObject();
//获得中括号的引用		    
JsonArray jsonArray = jsonObject.getAsJsonArray("list");
		  //加强for循环遍历JsonArray
		    for (JsonElement user : jsonArray) {
		        //使用GSON,直接转成Bean对象
		        Book book = gson.fromJson(user, Book.class);
//或者用这样形势Book book = gson.fromJson(user, new TypeToken< Book >() {}.getType());
		        result.add(book);
		    }
			System.out.println(result);
		}catch (Exception e) {
			// TODO: handle exception
			System.out.println(e);
		}
	}


通过jsonObject的getAsJsonArray方法拿到数组引用,或用getAsJsonObject()方法拿到JsonObject引用,这样我们就能控制哪些可操作。


对于开头的数据怎么处理呢?
直接拿数组,然后按上面的方式处理:
把JsonObject jsonObject = parser.parse(reader).getAsJsonObject();换成
JsonArray jsonArray =  parser.parse(reader).getAsJsonArray()


注意。

这个操控性能很大。我可以不用创建对应的javabean即可拿到某个数据。

比如json数据:
{"status":"200","data":{"token":"xd-adm-f6c39fbb-abab-4d17-95f6-243d90d43590","userInfo":{"acctPk":10,"ipAcctLoginName":"adm","ipPk":9,"ipNmCn":"adm","ipNmEn":"","ipCatCd":"","ipCatNmCn":"","apps":["app1","adm","front"],"roles":["super_admin"],"attrMap":null}}}


我想拿到token的值但我只要拿到token值没必需创建一个javabean接收整个json数据,代码如下:
jsonD=“上面json数据”;
JsonParser jsonParser = new JsonParser();
				JsonObject jsonObject = jsonParser.parse(jsonD).getAsJsonObject();
				String str = jsonObject.getAsJsonObject("data").get("token").getAsString();
				xd_token = str;

成功拿到token的值。


1.2.4 json合并

比如我想把:
{
	"name": "陈二",
	"age": 24
}
{ "list":
	[
		{"id":"h1","name":"历史"},{"id":"h2","name":"音乐"}
	]
}


合并成一个json,怎么写呢,对,就是JsonObject.add方法。
@Test
	public void merge() {
		try {
Reader reader = new InputStreamReader(JsonToken.class.getResourceAsStream("/com/cy/vo/es1/data2.json"), "UTF-8");
			Gson gson = new GsonBuilder().create();
			//Json的解析类对象
		    JsonParser parser = new JsonParser();
		    JsonObject jsonObject = parser.parse(reader).getAsJsonObject();
		    JsonArray jsonArray = jsonObject.getAsJsonArray("list");
		    
		    Reader reader1 = new InputStreamReader(JsonToken.class.getResourceAsStream("/com/cy/vo/es1/data1.json"), "UTF-8");
		    JsonObject jsonObject1 = parser.parse(reader1).getAsJsonObject();
		    jsonObject1.add("newJ", jsonArray);
		    
		    String str = gson.toJson(jsonObject1);
			System.out.println("merge:" + str);
		}catch (Exception e) {
			// TODO: handle exception
			System.out.println(e);
		}
	}


结果如下:
merge: {
	"name": "陈二",
	"age": 24,
	"newJ": [{
		"id": "h1",
		"name": "历史"
	},
	{
		"id": "h2",
		"name": "音乐"
	}]
}


2.序列化。

序列化只有一类方法toJson();
重写了很大方法:

Gson项目使用全解析_第1张图片
一般使用toJson(Object)和toJson(JsonElement)就够了。其它的可以参照API


3.对null的处理

程序里如下:
@Test
	public void testGson() {
		Gson gson = new Gson();
		User user = new User("陈三",24);
		String jsonObject = gson.toJson(user);
		System.out.println("gson:" + jsonObject.toString());
	}


我们故意没设置emailAddress,结果如下:
gson:{"name":"陈三","age":24}
是不是少了emailAddress,gson默认是对null值不序列化的,想要序列化需要设置gson。如下:
@Test
	public void testGson() {
		Gson gson = new GsonBuilder().serializeNulls().create();
		User user = new User("陈三",24);
		String jsonObject = gson.toJson(user);
		System.out.println("gson:" + jsonObject.toString());
	}


结果如下:
gson:{"name":"陈三","age":24,"emailAddress":null}




4.对日期的处理

默认是如下格式:May 11, 2017 1:25:04 PM
想输出2017-05-11 13:25:04则需要设置:

Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm:ss").create();


 

5.属性首字母大写。

代码:
@Test
	public void testGson() {
		Gson gson = new GsonBuilder().serializeNulls().setFieldNamingStrategy(FieldNamingPolicy.UPPER_CAMEL_CASE).create();
		User user = new User("陈三",24);
		String jsonObject = gson.toJson(user);
		System.out.println("gson:" + jsonObject.toString());
	}


结果如下:
gson:{"Name":"陈三","Age":24,"EmailAddress":null,"Bookes":["化学","物理"],"BookList":null}


附Gson的工具类

/**
 * Class: StringUtils
 * Description:String方法类
 * Version: 1.0
 * Author: Vinda
 * Creation date: 2013-6-27
 * (C) Copyright 2010-2015 SmarterLogistics.com Corporation Limited.
 * All rights reserved.
 */

package yui.comn.util;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;

import net.sf.json.JSONNull;

public class GsonUtils {
	public static String getJson(Object data) {
		// Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd
		// HH:mm:ss.fff").serializeNulls().create();
		Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").serializeNulls().create();
		return gson.toJson(data);
	}

	public static String getDataByKey(Object data, String key) {
		Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").serializeNulls().create();
		JsonParser jsonParser = new JsonParser();
		String str = "";
		if (data instanceof String) {
			str = (String) data;
		} else {
			str = gson.toJson(data);
		}
		JsonObject jsonObject = jsonParser.parse(str).getAsJsonObject();
		JsonElement jsonElement = jsonObject.get(key);
		if (null == jsonElement || StringUtils.equals(jsonElement.toString(), "null")) {
			return "";
		}
		String value = (String) jsonElement.getAsString();
		return value;
	}

	public static void main(String[] args) {
		Map data = new HashMap<>();
		data.put("name", "cy");
		data.put("age", null);

		String json = getJson(data);
		System.out.println(json);

		System.out.println("name:" + getDataByKey(json, "name"));
		System.out.println("age:" + getDataByKey(json, "age"));

	}
}



你可能感兴趣的:(技术工具,gson)