java gson_Java 中 Gson的使用

JSON 是一种文本形式的数据交换格式,它比XML更轻量、比二进制容易阅读和编写,调式也更加方便;解析和生成的方式很多,Java中最常用的类库有:JSON-Java、Gson、Jackson、FastJson等

一、Gson的基本用法

Gson提供了fromJson() 和toJson() 两个直接用于解析和生成的方法,前者实现反序列化,后者实现了序列化;同时每个方法都提供了重载方法

(1)基本数据类型的解析

Gson gson = new Gson();

int i = gson.fromJson("100", int.class); //100

double d = gson.fromJson("\"99.99\"", double.class); //99.99

boolean b = gson.fromJson("true", boolean.class); // true

String str = gson.fromJson("String", String.class); // String

(2)基本数据类型的生成

Gson gson = new Gson();

String jsonNumber = gson.toJson(100); // 100

String jsonBoolean = gson.toJson(false); // false

String jsonString = gson.toJson("String"); //"String"

(3)POJO类的生成与解析

public class User {

//省略其它

public String name;

public int age;

public String emailAddress;

}

生成JSON:

Gson gson = new Gson();

User user = new User("张三",24);

String jsonObject = gson.toJson(user); // {"name":"张三kidou","age":24}

解析JSON:

Gson gson = new Gson();

String jsonString = "{\"name\":\"张三\",\"age\":24}";

User user = gson.fromJson(jsonString, User.class);

二、属性重命名 @SerializedName 注解的使用

从上面POJO的生成与解析可以看出json的字段和值是的名称和类型是一一对应的,但也有一定容错机制(如第一个例子第3行将字符串的99.99转成double型),但有时候也会出现一些不和谐的情况,如:

期望的json格式:{"name":"张三","age":24,"emailAddress":"zhangsan@ceshi.com"}

实际:{"name":"张三","age":24,"email_address":"zhangsan@ceshi.com"}

Gson在序列化和反序列化时需要使用反射,一般各类库都将注解放到annotations包下,打开源码在com.google.gson包下有一个annotations,里面有一个SerializedName的注解类。对于json中email_address这个属性对应POJO的属性则变成:

@SerializedName("email_address")

public String emailAddress;

为POJO字段提供备选属性名:SerializedName注解提供了两个属性,上面用到了其中一个,别外还有一个属性alternate,接收一个String数组

注:alternate需要2.4版本

48304ba5e6f9fe08f3fa1abda7d326ab.png

@SerializedName(value = "emailAddress", alternate = {"email", "email_address"})

public String emailAddress;

//当三个属性(email_address、email、emailAddress)都中出现任意一个时均可以得到正确的结果

//当多种情况同时出时,以最后一个出现的值为准。

Gson gson = new Gson();

String json = "{\"name\":\"张三kidou\",\"age\":24,\"emailAddress\":\"zhangsan@ceshi.com\",\"email\":\"zhangsan_2@ceshi.com\",\"email_address\":\"zhangsan_3@ceshi.com\"}";

User user = gson.fromJson(json, User.class);

System.out.println(user.emailAddress); // zhangsan_3@example.com

48304ba5e6f9fe08f3fa1abda7d326ab.png

三、Gson中使用泛型

例如:JSON字符串数组:["Android","Java","PHP"]

当要通过Gson解析这个json时,一般有两种方式:使用数组,使用List;而List对于增删都是比较方便的,所以实际使用是还是List比较多

数组比较简单:

Gson gson = new Gson();

String jsonArray = "[\"Android\",\"Java\",\"PHP\"]";

String[] strings = gson.fromJson(jsonArray, String[].class);

对于List将上面的代码中的 String[].class 直接改为 List.class 是不行的,对于Java来说List 和List 这俩个的字节码文件只一个那就是List.class,这是Java泛型使用时要注意的问题 泛型擦除

为了解决的上面的问题,Gson提供了TypeToken来实现对泛型的支持,所以将以上的数据解析为List时需要这样写

Gson gson = new Gson();

String jsonArray = "[\"Android\",\"Java\",\"PHP\"]";

String[] strings = gson.fromJson(jsonArray, String[].class);

List stringList = gson.fromJson(jsonArray, new TypeToken>() {}.getType());

//TypeToken的构造方法是protected修饰的,所以上面才会写成new TypeToken>() {}.getType() 而不是 new TypeToken>().getType()

泛型解析对接口POJO的设计影响

泛型的引入可以减少无关的代码:

{"code":"0","message":"success","data":{}}

{"code":"0","message":"success","data":[]}

我们真正需要的data所包含的数据,而code只使用一次,message则几乎不用,如果Gson不支持泛型或不知道Gson支持泛型的同学一定会这么定义POJO

public class UserResponse {

public int code;

public String message;

public User data;

}

当其它接口的时候又重新定义一个XXResponse将data的类型改成XX,很明显code,和message被重复定义了多次,通过泛型可以将code和message字段抽取到一个Result的类中,这样只需要编写data字段所对应的POJO即可:

public class Result {

public int code;

public String message;

public T data;

}

//对于data字段是User时则可以写为 Result ,当是个列表的时候为 Result>

四、Gson的流式反序列化

(1)自动方式

Gson提供了fromJson()和toJson() 两个直接用于解析和生成的方法,前者实现反序列化,后者实现了序列化。同时每个方法都提供了重载方法

Gson.toJson(Object);

Gson.fromJson(Reader,Class);

Gson.fromJson(String,Class);

Gson.fromJson(Reader,Type);

Gson.fromJson(String,Type);

(2)手动方式:手动的方式就是使用stream包下的JsonReader类来手动实现反序列化,和Android中使用pull解析XML是比较类似的

48304ba5e6f9fe08f3fa1abda7d326ab.png

String json = "{\"name\":\"张三\",\"age\":\"24\"}";

User user = new User();

JsonReader reader = new JsonReader(new StringReader(json));

reader.beginObject();

while (reader.hasNext()) {

String s = reader.nextName();

switch (s) {

case "name":

user.name = reader.nextString();

break;

case "age":

user.age = reader.nextInt(); //自动转换

break;

case "email":

user.email = reader.nextString();

break;

}

}

reader.endObject(); // throws IOException

System.out.println(user.name); //张三

System.out.println(user.age); // 24

System.out.println(user.email); //zhangsan@ceshi.com

48304ba5e6f9fe08f3fa1abda7d326ab.png

自动方式最终都是通过JsonReader来实现的,如果第一个参数是String类型,那么Gson会创建一个StringReader转换成流操作

fd463113dc97c6dcf2169ce5f1900d14.png

五、Gson的流式序列化

(1)自动方式

7380417118fdbbc848ee482a06358f14.png

Gson.toJson方法列表

//PrintStream(System.out) 、StringBuilder、StringBuffer和*Writer都实现了Appendable接口。

Gson gson = new Gson();

User user = new User("张三",24,"zhangsan@ceshi.com");

gson.toJson(user,System.out);

(2)手动方式

48304ba5e6f9fe08f3fa1abda7d326ab.png

JsonWriter writer = new JsonWriter(new OutputStreamWriter(System.out));

writer.beginObject() // throws IOException

.name("name").value("张三")

.name("age").value(24)

.name("email").nullValue() //演示null

.endObject(); // throws IOException

writer.flush(); // throws IOException

//{"name":"张三","age":24,"email":null}

//除了beginObject、endObject还有beginArray和endArray,两者可以相互嵌套,注意配对即可。beginArray后不可以调用name方法,同样beginObject后在调用value之前必须要调用name方法。

48304ba5e6f9fe08f3fa1abda7d326ab.png

六、 使用GsonBuilder导出null值、格式化输出、日期时间

一般情况下Gson类提供的 API已经能满足大部分的使用场景,但有时需要更多特殊、强大的功能时,这时候就引入一个新的类 GsonBuilder。

GsonBuilder从名上也能知道是用于构建Gson实例的一个类,要想改变Gson默认的设置必须使用该类配置Gson

GsonBuilder用法:

//各种配置 //生成配置好的Gson

Gson gson = new GsonBuilder().create();

(1)Gson在默认情况下是不动导出值null的键的,如:

48304ba5e6f9fe08f3fa1abda7d326ab.png

public class User {

public String name;

public int age;

//省略

public String email;

}

Gson gson = new Gson();

User user = new User(张三",24);

System.out.println(gson.toJson(user)); //{"name":"张三","age":24}

//email字段是没有在json中出现的,当在调试时需要导出完整的json串时或API接中要求没有值必须用Null时,就会比较有用。

48304ba5e6f9fe08f3fa1abda7d326ab.png

使用方法:

Gson gson = new GsonBuilder().serializeNulls() .create();

User user = new User("张三", 24);

System.out.println(gson.toJson(user)); //{"name":"张三","age":24,"email":null}

格式化输出、日期时间及其它:

48304ba5e6f9fe08f3fa1abda7d326ab.png

Gson gson = new GsonBuilder()

//序列化null

.serializeNulls()

// 设置日期时间格式,另有2个重载方法

// 在序列化和反序化时均生效

.setDateFormat("yyyy-MM-dd")

// 禁此序列化内部类

.disableInnerClassSerialization()

//生成不可执行的Json(多了 )]}' 这4个字符)

.generateNonExecutableJson()

//禁止转义html标签

.disableHtmlEscaping()

//格式化输出

.setPrettyPrinting()

.create();

//:内部类(Inner Class)和嵌套类(Nested Class)的区别

48304ba5e6f9fe08f3fa1abda7d326ab.png

原文 : https://www.cnblogs.com/qinxu/p/9504412.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/529986.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

spring注入普通java类_普通java类如何取得注入spring Ioc容器的对象

[除了使用XML配置外,还可以选择使用基于注解(annotation)的配置方式,其依赖于字节码来织入组件。注解注入在XML注入之前完成,因此在XML配置中可以重载注解注入的属性。一、建一个SpringUtil类package com.ceopen.eoss.spring; import org.spr…

java web 集成dom4j_[JavaWeb基础] 031.dom4j写入xml的方法

上一篇我们讲述了dom4j读取xml的4种方法,甚是精彩,那么怎么样写入xml呢?我们直接看下源码实现。public static void main(String[] args) throws Exception {// 创建文档Document document DocumentHelper.createDocument();// 设置编码docu…

java servlet 调试日志 logger sae_java servlet 调试日志 lo

java servlet 调试日志 lo[2021-02-10 08:32:08] 简介:php去除nbsp的方法:首先创建一个PHP代码示例文件;然后通过“preg_replace("/(\s|\&nbsp\;| |\xc2\xa0)/", " ", strip_tags($val));”方法去除所有nbsp即可。推荐&#x…

java接口权限管理在哪里_java访问权限控制

为什么java要有访问权限的控制?访问权限的设置和代码的重构有关。在一个项目中,大多数的时间和金钱都投入到了代码的维护当中。维护中一定会修改已存在的不合理的代码。但是在重构的过程中,就出现了这样的问题:如何保证不影响那些使用了待修…

java8 stream index_Java8的stream用法整理

/***authorindex* date 2020/10/27**/public classTestcollectingAndThen {Testpublic voidtest(){final int NUM 14;List peopleList new ArrayList<>(NUM);String[] names {"小张", "小龙", "小牛", "小猪", "小黑&quo…

memo、 useMemo 和 useCallback语法讲解

memo、 useMemo 和 useCallback 缓存组件, 对组件浅比较 (只有组件的props, (对函数,引用要用useCallback包裹)发生变化 缓存值, 依赖项变化&#xff0c;会从新计算。 缓存函数, 依赖项变化,重新生成新函数 useMemo 语法 对返回的值缓存进行优化 const memoizedValue useMem…

java只修改变的字段_java注解之运行时修改字段的注解值操作

今天遇到需求&#xff1a;导入Excel时候列头会发生变化&#xff0c;客户是大爷要求你改代码&#xff0c;导入Excel是用easypoi做的&#xff0c;识别表头是用注解Excel(name "xxx")通过这个name来匹配那你表头要动&#xff0c;我这个注解是硬编码所以就有动态设置这个…

求java简单计算器源代码_java简单计算器源代码

简单计算器代码package calcultorthree;import java.awt.BorderLayout;//导入边界布局管理器类import java.awt.GridLayout;//导入网格布局管理器类import java.awt.TextField;//导入文本区域类import java.awt.event.ActionEvent;//导入事件类import java.awt.event.ActionLis…

java中间语言汇编语言_中间语言(IL) | 学步园

一、IL与汇编语言IL是微软.NET平台上衍生出的一门中间语言&#xff0c;.NET平台上的各种高级语言(如C#&#xff0c;VB&#xff0c;F#)的编译器会将各自的代码转化为IL。&#xff0c;其中包含了.NET平台上的各种元素&#xff0c;如“范型”&#xff0c;“类”、、“接口”、“模…

java遍历斐波纳契数列_详解循环、迭代、递归、分治(Leet Code 509 斐波那契数列),实际运用...

Multiple solutions of Fibonacci (Python or Java)本章是用英文写的&#xff0c;作为或想成为一名优秀的攻城狮&#xff0c;习惯阅读英文文档将使你受益良多。例如更好的查看最新版的官方文档、与国外友人交流、等等 其实英文的生词也并不多,其中90&#xff05;的英文都在代码…

java栈内存是先进后出吗_java堆内存与栈内存区别

栈(stack):是一个先进后出的数据结构,通常用于保存方法(函数)中的参数,局部变量. 在java中,所有基本类型和引用类型都在栈中存储.栈中数据的生存空间一般在当前scopes内(就是由{...}括起来的区域).栈的优势是&#xff0c;存取速度比堆要快&#xff0c;仅次于直接位于CPU中的寄存…

主页面功能的java_6-04-项目实战-主页面显示当前用户退出功能实现

教程列表&#xff1a;1-01-servlet学习-HTTP协议的概念作用和特点1-02-servlet学习-HTTP协议的交互流程和请求格式和请求方式1-03-servlet学习-HTTP协议的响应格式和常见状态码1-04-servlet学习-服务器介绍&tomcat服务器的安装和验证1-05-servlet学习-第一个web项目1-06-se…

java 二分查找 排序_java 冒泡排序 二分查找

下面这个程序是先定义一个整型数组&#xff0c;然后将其中的元素反序赋值&#xff0c;再用冒泡排序进行排序以后用二分查找来查找其中是否有某个数&#xff0c;返回值为-1时表示这个数可能小于这个数组的最小值或大小这个数组的最大值&#xff0c;-2表示这个数比这个数组的最小…

php 数组设置为空,PHP数组设置空值

如果没有数据存在&#xff0c;如何将数组值设置为null&#xff1f;PHP数组设置空值以下是我的PHP阵列和我JSON编码 -{"title":"Impalz-Marketing","type":"Business Details","version":"1.0","login":…

什么是写一个java类,Java什么是类?class的相关介绍

本章给大家带来Java什么是类&#xff1f;class的相关介绍&#xff0c;让大家了解关于类(class)的一些知识。有一定的参考价值&#xff0c;有需要的朋友可以参考一下&#xff0c;希望对你有所帮助。class Point{constructor(){}toString(){}}console.log(Object.keys(Point.prot…

windows php sqlite,如何在Apache 2.4(Windows 7)上为PHP 5.6.14配置SQLite3?

我在Windows 7上,在Apache 2.4上使用PHP 5.6.14版,我正在尝试访问SQLite3数据库.我正在……致命错误&#xff1a;找不到类“SQLite3”在这里你是一个简单的PHP代码…$db new SQLite3(phpdb);if ($db) {$db->query("CREATE TABLE dogbreeds (Name VARCHAR(255), MaxAge…

php 国密 签名,关于php国密SM3签名算法

推荐&#xff1a;《PHP视频教程》php国密SM3签名算法代码地址github.com/lizhichao/sm安装composer require lizhichao/one-sm使用require __DIR__ . /vendor/autoload.php; // 字符串签名 echo OneSmSm3::sign(abc) . PHP_EOL; echo OneSmSm3::sign(str_repeat("adfas哈哈…

matlab状态方程 传递函数 可控性,实验一matlab系统的传递函数和状态空间表达式的转换...

实验一 MATLAB 系统的传递函数和状态空间表达式的转换一、 实验目的1、学习多变量系统状态空间表达式的建立方法&#xff1b;2、通过编程、上机调试&#xff0c;掌握多变量系统状态空间表达式与传递函数之间相互转换的方法&#xff1b;3、掌握相应的MATLAB 函数。二、 实验原理…

php里h和h的区别吗,编码h264h和h264b有什么区别

区别如下&#xff1a;1、版本H.265是新的编码协议&#xff0c;也即是H.264的升级版。H.265标准保留H.264原来的某些技术&#xff0c;同时对一些相关的技术加以改进。新技术使用先进的技术用以改善码流、编码质量、延时和算法复杂度之间的关系&#xff0c;达到最优化设置。2、储…

mysql5.1怎么备份,MySQL 5.1升级到MySQL 5.5的步骤

mysql 5.5已经出来有一段时间&#xff0c;性能有明显提升&#xff0c;特别是对多核CPU的支持与TPS性能的提升。上周博主介绍了linux下编译安装mysql 5.5的步骤&#xff0c;安装不出意外基本没有问题。不过可能很多朋友和我一样一直用的是mysql 5.1&#xff0c;现在想把数据库升…