Java基础知识强化103:JSON解析框架汇总

1、Gson

  Gson是Google提供的一个能够将Java对象转换成相应JSON表达形式的一个开源Java类库,当然用Gson也能将JSON字符串转换成与之等价的Java对象。Gson对于任何Java对象都有效,包括那些预先存在没有源代码的对象。

  现在已经有一些能将Java对象转换成JSON的开源项目了。但是大多数项目都要求你在类文件中加入Java注解,而当你无法改动源代码的时候这是无法做到的。并且它们也不支持Java泛型。但是Gson却将这两点作为自己非常重要的设计目标。

目标

  • 使用toJson()和fromJson()方法,就可以非常容易的完成Java对象到JSON的相互转换。
  • 能将预先存在的无法修改的对象与JSON互相转换。
  • 支持Java泛型的使用。
  • 允许对象的个性化表达形式(representation)。
  • 支持各种复杂(拥有深继承层次结构和大量使用泛型类型)的对象。

官方网站:https://github.com/google/gson
开源地址:https://github.com/google/gson

2、Jackson

  Jackson相对来说比较高效,在项目中主要使用Jackson进行JSON和Java对象转换, Jackson库,是基于Java语言的开源JSON格式解析工具,整个库(使用最新的2.2版本)包含3个jar包:

  • jackson-core.jar——核心包(必须),提供基于“流模式”解析的API。
  • jackson-databind——数据绑定包(可选),提供基于“对象绑定”和“树模型”相关API。jackson-annotations——注解包(可选),提供注解功能。

Jackson的优点
  相对于Java JSON解析的其他库,诸如json-lib、gson包,Jackson具有以下优点:

1. 多处理模式,且可很好协作 。从基本用法开始,有多种方法来使用和生产JSON数据,尽管多数JSON包仅提供单一的处理方式,但却有三种互补的JSON处理方式:

  • 增量解析及生成(流模式)。高性能,低开销的顺序访问。这是最低级的处理方法,相当于用于处理XML的SAX和StAX API。所有包装内部必须有这样的分析器,但并非所有都公开。
  • 基于树的数据模式(JSON DOM)。 树是一种描述JSON内容的自然的概念模型,因此许多软件包提供将JSON作为逻辑树处理的功能。这是一个灵活的模式,可很好适用某类任务,原型处理或即席访问也相当杰出。
  • 数据绑定(JSON 与POJO相互转换。极为方便,通常较树状模式更高的存取效率,也是适于Java开发人员通用的自然的数据绑定方式。常用于大多数Java REST框架,诸如JAX-RS。

2. 可使用任何构造及工厂方法(不只是默的零参方法)

  • 大多数数据(对JSON和XML)绑定工具需要一个定义和无参数的构造函数,实例化Java对象,并通过setter设置属性或直接访问字段。 不幸的是它使人们难以利用用“不可变对象”模式,也不同于正常代码中的访问模式。

3.不仅是注解,可以混合式注解!

  • 虽然有很多好处,利用Java注解定义元数据(如类型安全、编译时检查,消除单独的XML配置,DTY原则等),但也有缺点:如明显的是,添加注解须能修改类。 而你通常不能(也不应该)修改第三方库的代码,至少不只是JSON序列化配置方面。 但是,如果你只可以松散动态关联注释,而不是嵌入在代码中?我认为这是个了不起的想法,不管你对Jackson的混合式注解了解多少:您可以将注释与目标类关联(声明为代理接口或类的一部分)目标类的处理方式如同目标类本身声明的注解一样。

4. 完全支持泛型类型

  • 现在泛型是Java开发的完整组成部分,然而,并非所有的JSON库支持泛型,甚至在处理非常复杂的数据类型时会出错。
  • 以下列泛型为例:
  • public class Wrapper<T> { public T value; } public class ListWrapper<E> extends Wrapper<List<E>> { }
  • 若需反序列化这些类型的数据,代码如下:
  • ListWrapper<Integer> w = objectMapper.readValue(“[{"value":13},{"value":7}]“, new TypeReference<ListWrapper<Integer>>() { } );
  • Jackson在弄清必要的东西及生成期望的值方面有点小麻烦,但却是支持泛型(或更多)的仅有的Java包。

5.多态类型

  • 下面是另一个factoid:继承和多态类型可用于面向对象开发的很好方法,但也是任意实现数据绑定功能的系统的PITA。
  • ORM(如Hibernate)大部分的复杂性是由于沿继承层次结构扁平化和非扁平化数据功能的需要,同样适用于像JAXB的数据序列化包。这也就难怪,当时,只有极少数的Java包支持多态类型的JSON反序列化,大多数需要用户建立应用代码显式进行类型解析。

6.物化接口 (even less monkey code to write!)

  • 尽管支持多态类型是强大的功能 — 但却存在固有的充足的复杂性 — 这里是简化事情的方式:物化接口(或抽象类)。
  • 给定接口如下:
  • public interface Bean { public int getX(); public void setX(int value); }
  • 你可能想跳过这一步“Bean接口实现,包含两倍代码的类”,而直接处理:
  • Bean bean = objectMapper.readValue(json, Bean.class);
  • 只有一行配置,便可实现这神奇的功能(又称“Bean先生”)。

7. 支持父/子引用(一对多,ORM)

  • 经过前面的通用功能集,我们总结的东西更为具体:能够干净地处理循环类型的某些子集,成为父/子链接。 这些都是互相紧密耦合的引用,其中两个对象以层次结构的方式交叉引用,如父/子树节点的关联, 或更常见的,ORM采用的表间连接(join)的描述。
  • 对引用问题(或更普遍的,循环引用),JSON没有处理它们的自然方法。,不像Java对象,没有标识信息可用。 常用的解决方法是只标记一个被忽略的引用(Jackson可通过使用@ JsonIgnore注解实现),但其缺点是反序列化时会丢失实际的耦合目标。 Jackson 有简单的基于注解的解决该问题的方案:两个引用需要一个注解(对“子”连接作@JsonManagedReference注解,对“父”或“返回”连接作 @JsonBackReference注解),并在此基础,Jackson知道要省略反向引用的序列化,但反序列化对象时要恢复它。此方式适用于典型的 ORM用例。
  • 重要API
  • 核心包:JsonPaser(json流读取),JsonGenerator(json流输出)。
  • 数据绑定包:ObjectMapper(构建树模式和对象绑定模式),JsonNode(树节点)。

官方网站:http://wiki.fasterxml.com/JacksonHome
开源地址:https://github.com/FasterXML/jackson

3、Genson

Genson是一个完全的Java和JSON转换的类库,提供了全面的数据绑定、流操作等。基于Apache 2.0协议发布。

特性

  • 易于使用、快速、高度可配置,轻量级的小jar包。
  • 支持全面的数据绑定和流的高效读写。
  • 支持多态类型(能够序列化一个未知类型)。
  • 不需要默认的无参构造方法和传参不仅是null,鼓励不变性。它可以通过用工厂方法来代替构造函数。
  • 全面支持Java泛型。
  • 易于过滤和扩展文件属性,不需要通过注释和混合。
  • Genson提供了JSR353的完整实现。
  • 从Genson 0.95JAXB开始对注解和类型都提供支持。
  • 在JAX-RS中对JSON实现自动支持。
  • 用复杂的键构造序列化和反序列化map集合。

目标

  • 允许用户通过使用整洁,简单的方式尽可能多的扩展实现新的功能。
  • 提供易于使用的API。
  • 尝试成为快速、可扩展,甚至超过最高性能的库。
  • 完全支持泛型。
  • 支持没有源码的类。
  • 提供高效的流式API。

 

POJO数据绑定
Genson库的主要切入点就是Genson类,它提供了从Java对象序列化成JSON对象和从JSON流中解序列化成Java对象。Genson实例是不可变、线程安全的,可以重用。一般来说,推荐的方法是每个配置类型都有一个单独的实例。
常用的使用方式就是用Genson去读JSON和一些POJO匹配。反之也可以,读POJO写JSON。

Java集合
你也可以用标准的Java集合像Map和List。如果你不告诉Genson你使用的类型,Genson将把JSON数组反序列化为Java中的List,JSON对象反序列化为Map,对象中的属性为long或double型。

反序列化通用类型
可以反序列化成通用的类型,例如POJO数组。

定制Genson
如果Genson提供的默认的配置不满足你的需求,你可以通过GensonBuilder来定制。例如,能够实现输出缩进,用他们运行时的类型序列化所有的对象,反序列化的类没有提供一个默认的无参构造方法,就可以通过下面的配置实现。

官方网站:http://wiki.fasterxml.com/JacksonHome
开源地址:https://github.com/FasterXML/jackson

时间: 2024-10-26 03:07:58

Java基础知识强化103:JSON解析框架汇总的相关文章

Java基础知识强化(用于自我巩固)以及审查

1. Java 和 JDK 的关系 JDK(Java Development Kit)Java 开发工具包,它包括:编译器.Java 运行环境(JRE,Java Runtime Environment).JVM(Java 虚拟机)监控和诊断工具等 Java 则表示一种开发语言. 2. Java 程序是怎么执行的? 日常工作中使用的开发工具(IntelliJ IDEA 或 Eclipse 等)可以很方便的调试程序,或者是通过打包工具把项目打包成 jar 包或者 war 包,放入 Tomcat 等

Java基础知识强化之多线程笔记01:多线程基础知识(详见Android(java)笔记61~76)

1. 基础知识: Android(java)学习笔记61:多线程程序的引入    ~    Android(java)学习笔记76:多线程-定时器概述和使用 

Java基础知识强化105:打印数组的方法总结

1. 使用for循环打印数组. 2. 使用Arrays工具类,将数组转化为有序的List打印出来. 3. 使用Arrays工具类,使用Arrays.toString()输出数组内容. 上面三种方法打印数组的示例代码如下: package com.himi.printarray; import java.util.Arrays; public class AnormalArray { public static void main(String[] args) { /** * 使用for循环打印数

java基础知识强化52:Java程序员面试失败的5大原因

下面是Java程序员面试失败最有可能的5大原因,当然也许这5点原因适用于所有的程序员,所以,如果你是程序员,请认真阅读以下内容. 1 说得太少 尤其是那些开放式的问题,如“请介绍下你自己”或“请讲一下你曾经解决过的复杂问题”.面试官会通过你对这些技术和非技术问题的回答来评估你的激情.他们也会通过模拟团队氛围和与你的交流互动来判断你的经验和能力. 所以,仅仅只用两三句话来回答不但不能显示出你对这个专业的兴趣,还会让整个面试过程显得非常无聊.如果你不能很好地说明你的经验.成就和技能可以给企业带来的价

Java基础知识强化之集合框架笔记11:Collection集合之迭代器的原理及源码解析

1. 迭代器为什么不定义成一个类,而是定义为一个接口 ?  答:假设迭代器定义的是一个类,这样我们就可以创建该类的对象,调用该类的方法来实现集合的遍历.但是呢? 我们想想,Java中提供了很多的集合类,而这些集合类的数据结构是不同的,所以,存储的方式和遍历的方式应该是不同的.进而它们的遍历方式也应该不是一样的,最终,就没有定义迭代器类.        而无论你是哪种集合,你都应该具备获取元素的操作,而且,最好在辅助于判断功能,这样,在获取前,先判断.这样的话就不容易出错.也就是说,判断功能和获取

Java基础知识强化之集合框架笔记04:Collection集合的基本功能测试

1. Collection集合的基本功能测试: 1 package cn.itcast_01; 2 3 import java.util.ArrayList; 4 import java.util.Collection; 5 6 /* 7 * 集合的由来: 8 * 我们学习的是面向对象语言,而面向对象语言对事物的描述是通过对象体现的,为了方便对多个对象进行操作,我们就必须把这多个对象进行存储. 9 * 而要想存储多个对象,就不能是一个基本的变量,而应该是一个容器类型的变量,在我们目前所学过的知识

Java基础知识强化之集合框架笔记43:Set集合之TreeSet存储Integer类型的元素并遍历

1. TreeSet类概述: • 能够对元素按照某种规则进行排序. • 或者根据创建set时提供的Comparator进行排序 • 具体取决于使用的构造方法 2. 代码示例: 1 package cn.itcast_05; 2 3 import java.util.TreeSet; 4 5 /* 6 * TreeSet:能够对元素按照某种规则进行排序. 7 * 排序有两种方式 8 * A:自然排序 9 * B:比较器排序 10 * 11 * TreeSet集合的特点:排序和唯一 12 * 13

Java基础知识强化之集合框架笔记29:使用LinkedList实现栈数据结构的集合代码(面试题)

1. 请用LinkedList模拟栈数据结构的集合,并测试:  题目的意思是:     你自己的定义一个集合类,在这个集合类内部可以使用LinkedList模拟,使用LinkedList功能方法封装成自己的方法. 2. 代码解析: (1)定义自己集合类MyStack,模拟栈数据结构( 先进后出 ) 1 package cn.itcast_05; 2 3 import java.util.LinkedList; 4 5 /** 6 * 自定义的栈集合 7 * 8 * @author Mr He 9

Java基础知识强化之集合框架笔记01:集合的由来与数组的区别

1. 集合的由来: 我们学习的是面向对象语言,而面向对象语言对事物的描述是通过对象体现的,为了方便对多个对象进行操作,我们就必须把这多个对象进行存储.而要想存储多个对象,就不能是一个基本的变量,而应该是一个容器类型的变量,在我们目前所学过的知识里面,有哪些是容器类型的呢?数组和StringBuffer.但是呢?StringBuffer的结果是一个字符串,不一定满足我们的要求,所以我们只能选择数组,这就是对象数组.而对象数组又不能适应变化的需求,因为数组的长度是固定的,这个时候,为了适应变化的需求