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<Book> bookList;….getter/setter省略
}
public class Book {private String id;
private String name;
….getter/setter省略
}

程序:

@Testpublic 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 exceptionSystem.out.println(e);}}

结果是把整个Json数据映射到User对象里。

1.2.2 反序列化成Map

json数据:

{"name": "怪盗kidou","age": 24
}

程序:

@Testpublic void testStr2Map() {try {
Reader reader = new InputStreamReader(JsonToken.class.getResourceAsStream("/com/cy/vo/es1/data1.json"), "UTF-8");Gson gson = new GsonBuilder().create();Map<String, String> p = gson.fromJson(reader, Map.class);System.out.println(p);}catch (Exception e) {// TODO: handle exceptionSystem.out.println(e);}
}

结果成功映射到Map里。

1.2.3 自己控制

上面的功能感受有些限制,因为大部分工作都是Gson来做了,我们没法手动限制处理哪块数据。使用我上面介绍的JsonObject,JsonArray
比如json数据:

{ "list":[{"id":"h1","name":"历史"},{"id":"h2","name":"音乐"}]
}

由于有大括号里有个key,每个key对应一个数组,拿到大括号数据用JsonObject,拿到数组对象用JsonArray。
所以程序是这样的:

@Testpublic void testStr2List2() {try {List<Book> 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循环遍历JsonArrayfor (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 exceptionSystem.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方法。

@Testpublic 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 exceptionSystem.out.println(e);}}

结果如下:

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

2.序列化。

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


一般使用toJson(Object)和toJson(JsonElement)就够了。其它的可以参照API

3.对null的处理

程序里如下:

@Testpublic 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。如下:

@Testpublic 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.属性首字母大写。

代码:

@Testpublic 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<String, Object> 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项目使用全解析相关推荐

  1. 轻触开源(三)-Gson项目源码解析_贰

    2019独角兽企业重金招聘Python工程师标准>>> 转载请注明出处:https://my.oschina.net/u/874727/blog/750473 Q:102525062 ...

  2. 轻触开源(二)-Gson项目源码解析_壹

    2019独角兽企业重金招聘Python工程师标准>>> 上篇文章<轻触开源-Java泛型Type类型的应用和实践(一)> https://my.oschina.net/u ...

  3. 微服务电商项目技术全解析

    一.项目介绍 7d-mall-microservice 是一套微服务电商,其是在开源电商项目 mall-swarm 上进行了改造,采用了 Spring Cloud Hoxton & Aliba ...

  4. 《高楼的性能工程实战课》微服务电商项目技术全解析

    文章目录 一.项目介绍 二.整体结构 三.预备知识 1.什么是 SpringCloud ? 2.Spring .SpringBoot 和 Spring Cloud 的关系 3.Spring Cloud ...

  5. 2021年职业院校技能大赛“网络安全”项目-- 江西省比赛任务书全解析

    2021年职业院校技能大赛"网络安全"项目–江西省比赛任务书全解析 白嫖拿去! 靶场在这自取 后台私信免费共享自己写的vulnhub靶场(C模块)详细WP(一切为了学习) 靶场包括 ...

  6. STM8S全解析之系列文章1---STM8S芯片项目需求与解决方案

    STM8S全解析之系列文章1-STM8S芯片项目需求与解决方案 <STM8S全解析之系列文章1-STM8S芯片项目需求与解决方案> <STM8S全解析之系列文章2-在IAR上新建ST ...

  7. Go modules基础精进,六大核心概念全解析(下)

    Go 语言做开发时,路径是如何定义的?Go Mudules又为此带来了哪些改变?本文将会全面介绍Go Modules六大核心概念,包括了设计理念与兼容性原则等,掌握这些技术点对于管理和维护Go 模块有 ...

  8. 第四章:Spring项目文件上传两种方式(全解析)

    欢迎查看Java开发之上帝之眼系列教程,如果您正在为Java后端庞大的体系所困扰,如果您正在为各种繁出不穷的技术和各种框架所迷茫,那么本系列文章将带您窥探Java庞大的体系.本系列教程希望您能站在上帝 ...

  9. 阿里秋招面试全解析(含内推岗)

    每个技术人都有个大厂梦,我觉得这很正常,并不是饭后的谈资而是每个技术人的追求.像阿里.腾讯.美团.字节跳动.京东等等的技术氛围与技术规范度还是要明显优于一些创业型公司/小公司,如果说能够在这样的公司锻 ...

最新文章

  1. 抖音的标题写什么内容_看了这篇文章,我才真正明白什么才是英语速成之路!感恩...
  2. 学习编程能够从事哪些行业?
  3. mysql wampmysqld_wamp中mysqld占用内存大mysql5.6 | 学步园
  4. 关于华为x2中的外置SDCard的使用
  5. angular 字符串转换成数字_一文看懂Python列表、元组和字符串操作
  6. 做点RouteOS方面的备忘,关于流量监控限速的
  7. PPT - 如何在PPT里面实现数字的随机抽奖?
  8. minecraftjava版光追_我的世界:网易版终于更新狐狸生物?Java版光追技术已开始测试?...
  9. irlr7843引脚图_IRLU7843_PDF技术资料下载_货期信息(1/10)_IR - 万联芯城
  10. Android 触摸OnTouchListener没有响应问题解决
  11. 【小程序云开发】不用后端也能构建完整的微信小程序
  12. IMPERVA-WAF 设备替换方案
  13. STM32 最小系统电路简析
  14. 方大九钢携手图扑软件:数字孪生智慧钢厂之数据驾驶舱
  15. UML(Jude) | UseCase Diagram
  16. Maven基础(2):Maven详解
  17. 一拖二组装设备,一台信捷XD5-60T10-E系列PLC控制两台组装检测设备,扩展5个32点输入输出扩展模块
  18. 密码生成器怎么用 password generator密码生成器使用教程
  19. 临床输血技术规范(2000年6月1日卫生部发布)
  20. overloading和overriding,两者有什么区别和联系?

热门文章

  1. 20 JNI - c++层 操作 java 层对象
  2. 【Spring Web教程】SpringBoot 实现一应用多Tomcat容器
  3. Ubuntu下安装配置gitLab(一)
  4. BZOJ1163: [Baltic2008]Mafia
  5. java使用背景音乐_JAVA播放背景音乐
  6. SPM软件的参考资料链接
  7. Android 忆童年 DVD 待机动画
  8. Python基于Django城市PM2.5空气质量数据可视化分析
  9. python opengl 教程_OpenGL新手和弃用
  10. 使用MMX/SSE汇编指令集优化视频开发