Moshi

是一个现代化的JSON库针对Android和Java。它可以很容易地解析JSON成Java对象:


String json = ...;

Moshi moshi = new Moshi.Builder().build();
JsonAdapter<BlackjackHand> jsonAdapter = moshi.adapter(BlackjackHand.class); BlackjackHand blackjackHand = jsonAdapter.fromJson(json);
System.out.println(blackjackHand);

它可以很容易地Java对象序列为JSON:


BlackjackHand blackjackHand = new BlackjackHand(
new Card('6', SPADES),
Arrays.asList(new Card('4', CLUBS), new Card('A', HEARTS))); Moshi moshi = new Moshi.Builder().build();
JsonAdapter<BlackjackHand> jsonAdapter = moshi.adapter(BlackjackHand.class); String json = jsonAdapter.toJson(blackjackHand);
System.out.println(json);

内置型适配器

莫西已经内置了支持读取和写入Java的核心数据类型:

  • 原语(整型,浮点,焦炭......)及其同行盒装(整数,浮点数,字符...)。
  • 数组,集合,列表,集合和地图
  • 字符串
  • 枚举

它通过写出来场逐场支持你的模型类。在上面的莫希例子使用这些类:


class BlackjackHand {
public final Card hidden_card;
public final List<Card> visible_cards;
...
} class Card {
public final char rank;
public final Suit suit;
...
} enum Suit {
CLUBS, DIAMONDS, HEARTS, SPADES;
}

读写此JSON:


{
"hidden_card": {
"rank": "6",
"suit": "SPADES"
},
"visible_cards": [
{
"rank": "4",
"suit": "CLUBS"
},
{
"rank": "A",
"suit": "HEARTS"
}
]
}

该Javadoc中编目完整的莫西API,我们将在下面探讨。

自定义类型的适配器

随着磨石,这是特别容易定制值的转换方式,并从JSON。A型适配器是有注释的方法,任何类@ToJson@FromJson

例如,磨石的一张扑克牌的默认编码为详细:JSON的定义在不同领域的点数和花色:{“等级”:“A”,“套装”:“心”}。随着类型的适配器,我们可以改变编码的东西更紧凑:“4H”为心中的四,“JD”为钻石插孔:


class CardAdapter {
@ToJson String toJson(Card card) {
return card.rank + card.suit.name().substring(0, 1);
} @FromJson Card fromJson(String card) {
if (card.length() != 2) throw new JsonDataException("Unknown card: " + card); char rank = card.charAt(0);
switch (card.charAt(1)) {
case 'C': return new Card(rank, Suit.CLUBS);
case 'D': return new Card(rank, Suit.DIAMONDS);
case 'H': return new Card(rank, Suit.HEARTS);
case 'S': return new Card(rank, Suit.SPADES);
default: throw new JsonDataException("unknown suit: " + card);
}
}
}

注册与该类型的适配器Moshi.Builder,我们是好去。


Moshi moshi = new Moshi.Builder()
.add(new CardAdapter())
.build();

Voila:

{
"hidden_card": "6S",
"visible_cards": [
"4C",
"AH"
]
}

另一个安卓源码例子

需要注意的是带注释方法@FromJson并不需要采取一个字符串作为参数。相反,它可以采取任何类型的输入和磨石将首先解析JSON到该类型的对象,然后使用@FromJson方法以产生所需的最终值。相反,带注释的方法@ToJson没有产生一个字符串。

假设,例如,我们必须分析,其中一个事件的日期和时间被表示为两个独立的字符串一个JSON。


{
"title": "Blackjack tournament",
"begin_date": "20151010",
"begin_time": "17:04"
}

我们想这两个字段合并为一个串,以方便的时间在稍后分析。同时,我们希望有首字母大写的所有变量名。因此,事件 我们要莫希产生这样的类:


class Event {
String title;
String beginDateAndTime;
}

不用手动解析每行的JSON行(我们也可以做到),我们可以有莫希自动完成改造。我们简单地定义另一个类EventJson直接对应于JSON结构:


class EventJson {
String title;
String begin_date;
String begin_time;
}

并用适当的另一个类@FromJson@ToJson被告知莫希如何将一个转换方法EventJson一个事件和背部。现在,每当我们要求莫希分析一个JSON到一个事件,将首先将其解析到一个EventJson作为一个中间步骤。相反,序列化一个事件莫希将首先创建一个EventJson对象,然后序列化对象如常。


class EventJsonAdapter {
@FromJson Event eventFromJson(EventJson eventJson) {
Event event = new Event();
event.title = eventJson.title;
event.beginDateAndTime = eventJson.begin_date + " " + eventJson.begin_time;
return event;
} @ToJson EventJson eventToJson(Event event) {
EventJson json = new EventJson();
json.title = event.title;
json.begin_date = event.beginDateAndTime.substring(0, 8);
json.begin_time = event.beginDateAndTime.substring(9, 14);
return json;
}
}

我们再次注册莫希适配器。


Moshi moshi = new Moshi.Builder()
.add(new EventJsonAdapter())
.build();

现在我们可以用磨石直接解析JSON到一个事件


JsonAdapter<Event> jsonAdapter = moshi.adapter(Event.class);
Event event = jsonAdapter.fromJson(json);

优雅地失败

自动数据绑定几乎感觉像魔术。但不同的是黑魔法,通常伴随着反射,磨石旨在帮助你当事情出错。


JsonDataException: Expected one of [CLUBS, DIAMONDS, HEARTS, SPADES] but was ANCHOR at path $.visible_cards[2].suit
at com.squareup.moshi.JsonAdapters$11.fromJson(JsonAdapters.java:188)
at com.squareup.moshi.JsonAdapters$11.fromJson(JsonAdapters.java:180)
...

莫希总是抛出一个标准的java.io.IOException异常,如果有一个错误读取JSON文档,或者如果它是畸形的。它抛出一个JsonDataException如果JSON文件是良好的,但不符合预期的格式。

建立在奥基奥

莫希使用奥基奥简单而功能强大的I / O。这是一个很好的补充,OkHttp,它可以共享缓冲段的最大效率。

从GSON借用

莫希使用相同的流媒体和约束机制为GSON。如果你是一个GSON用户,你会发现莫希工作方式类似。如果您尝试莫希和不爱它,你甚至可以迁移到GSON没有太多的暴力!

但是,这两个库有几个重要的区别:

  • 莫希具有较少的内置类型的适配器。例如,您需要配置自己的日期适配器。大多数绑定库将编码不管你扔他们。莫希拒绝序列化的平台类型(java中。*使用javax。*,和Android系统。*)无用户提供类型的适配器。这是为了防止意外锁定自己特定的JDK或Android版 本。
  • 莫希较少配置的。有没有现场的命名策略,版本控制,例如创作者,或长系列化策略。相反,命名字段visibleCards和使用策略类将其转换成visible_cards,磨石要你只是名称的字段visible_cards,因为它出现在JSON。
  • 莫希没有一个JsonElement模式。相反,它只是使用内置的类型,如列表和 地图
  • 没有HTML安全转义。 GSON编码=\ u003d默认情况下,以便它可以在HTML中被安全编码,无需额外转义。莫希自然编码它(如=),并假定HTML编码器-如果有的话-会做自己的工作。

与@Json自定义字段名称

莫希最适合当你的JSON对象和Java对象具有相同的结构。但是,当他们不这样做,磨石有注释定制数据绑定。

使用@Json指定的Java如何字段映射到JSON的名字。这是必要的,当JSON名称包含空格或者未在Java字段名称中不允许其他字符。例如,这个JSON有包含空格的字段名称:


{
"username": "jesse",
"lucky number": 32
}

随着@Json其相应的Java类很简单:


class Player {
String username;
@Json(name = "lucky number") int luckyNumber; ...
}

由于JSON字段名始终与他们的Java领域的定义,磨石使得Java和JSON之间航行时很容易找到的字段。

与@JsonQualifier交替类型的适配器

使用@JsonQualifier自定义类型是如何编码的某些字段,而不无处不在改变其编码。这种工作方式类似于在预选赛中的注释依赖注入工具,如匕首和吉斯。

下面是两个整数和颜色的JSON消息:


{
"width": 1024,
"height": 768,
"color": "#ff0000"
}

按照惯例,Android的程序也使用INT的颜色:


class Rectangle {
int width;
int height;
int color;
}

但是,如果我们编码上面的Java类JSON,颜色不正确编码!


{
"width": 1024,
"height": 768,
"color": 16711680
}

解决方法是定义一个限定注解,注解本身@JsonQualifier


@Retention(RUNTIME)
@JsonQualifier
public @interface HexColor {
}

下一步将此@HexColor注释相应字段:


class Rectangle {
int width;
int height;
@HexColor int color;
}

最后定义一个类型的适配器来处理它:


/** Converts strings like #ff0000 to the corresponding color ints. */
class ColorAdapter {
@ToJson String toJson(@HexColor int rgb) {
return String.format("#%06x", rgb);
} @FromJson @HexColor int fromJson(String rgb) {
return Integer.parseInt(rgb.substring(1), 16);
}
}

使用@JsonQualifier当您需要为同一型号不同JSON编码。大部分程序不应该需要这个@JsonQualifier,但它是为那些确实非常方便。

下载

下载最新的JAR或通过Maven的依赖:


<dependency>
<groupId>com.squareup.moshi</groupId>
<artifactId>moshi</artifactId>
<version>1.1.0</version>
</dependency>

or Gradle:

compile 'com.squareup.moshi:moshi:1.1.0'

下载地址https://github.com/square/moshi/archive/master.zip

一个现代化的JSON库Moshi针对Android和Java的更多相关文章

  1. 推荐一个golang的json库

    生成json的库 https://github.com/bennyscetbun/jsongo https://github.com/donnie4w/json4g

  2. <Android开源库 ~ 1> GitHub Android Libraries Top 100 简介

    转载自GitHub Android Libraries Top 100 简介 本项目主要对目前 GitHub 上排名前 100 的 Android 开源库进行简单的介绍, 至于排名完全是根据 GitH ...

  3. 1. 初识Jackson -- 世界上最好的JSON库

    要想人前显贵,必须背后受罪.关注公众号[BAT的乌托邦]开启专栏式学习,拒绝浅尝辄止.本文 https://www.yourbatman.cn 已收录,里面一并有Spring技术栈.MyBatis.中 ...

  4. Java几种常用JSON库性能比较

    本篇通过JMH来测试一下Java中几种常见的JSON解析库的性能. 每次都在网上看到别人说什么某某库性能是如何如何的好,碾压其他的库.但是百闻不如一见,只有自己亲手测试过的才是最值得相信的. JSON ...

  5. JSON库的使用研究(一)

    最近用到JSON,收集了一些资料,整理如下: 选择一个合适的JSON库要从多个方面进行考虑: 字符串解析成JSON性能 字符串解析成Java Object性能 Java Object转JSON性能 集 ...

  6. Java常用的几个Json库,性能强势对比!

    作者:飞污熊 https://xncoding.com/2018/01/09/java/jsons.html 本篇通过JMH来测试一下Java中几种常见的JSON解析库的性能.每次都在网上看到别人说什 ...

  7. 一个可以将 json 字符串 直接绑定到 view 上的Android库

    android-data-binding 这是一个可以将 json 字符串 直接绑定到 view 上的库, 不用先将 json 转换为 model 类. 传送门(https://github.com/ ...

  8. Fastjson是一个Java语言编写的高性能功能完善的JSON库。

    简介 Fastjson是一个Java语言编写的高性能功能完善的JSON库. 高性能 fastjson采用独创的算法,将parse的速度提升到极致,超过所有json库,包括曾经号称最快的jackson. ...

  9. 极力推荐一个简单好用的C++JSON库

      极力推荐一个简单好用的C++JSON库CJsonObject,让使用json如使用C++原生的结构体那般方便,随心所欲.CJsonObject是个优秀的C++JSON库,也许会是你见过的最为简单易 ...

随机推荐

  1. Linq的延迟

    书名:LINQ: The Future of Data Access in C# 3.0 Learn LINQ and the C# 3.0 Features That Support It http ...

  2. c#执行Dos命令

    一个执行Dos命令的窗口程序,与各位分享.   效果图:     具体实现在代码中有详细的注释,请看代码.   实现执行CMD命令的核心代码(Cmd.cs):   [csharp]   using S ...

  3. T型架构观点学习

    一.成为T型人才 眼界格局思维要尽可能的开阔,并不断横向开阔,专业能力要尽可能专注,并且纵向上不断加深: 互联网的快速迭代开发和扁平化管理,使单纯管理人才的作用越来越小,除了分配任务和项目管理,在其他 ...

  4. js正则表达式及代码

    //校验是否全由数字组成function isDigit(s){var patrn=/^[0-9]{1,20}$/;if (!patrn.exec(s)) return falsereturn tru ...

  5. [转]优化数据库大幅度提高Oracle的性能

    几个简单的步骤大幅提高Oracle性能--我优化数据库的三板斧. 数据库优化的讨论可以说是一个永恒的主题.资深的Oracle优化人员通常会要求提出性能问题的人对数据库做一个statspack,贴出数据 ...

  6. [Buffalo] 一些SQL函数

    取得当前时间的函数:GETDATE() 计算时间的函数:DATEADD(datepart,number,date) 计算两个时间差额:DATEDIFF(datepart,startdate,endda ...

  7. 解决Mac下Sequel Pro 1.1 连接 Homebrew安装Mysql5.7.8的问题 Sequel Pro 1.1 encountered an unexpected error

    解决Mac下Sequel Pro 1.1 连接 Homebrew安装Mysql5.7.8的问题 Sequel Pro encountered an unexpected error Sequel Pr ...

  8. Storm系列(十八)事务介绍

    功能:将多个tuple组合成为一个批次,并保障每个批次的tuple被且仅被处理一次. storm事务处理中,把一个批次的tuple的处理分为两个阶段processing和commit阶段. proce ...

  9. 【Java基础】static关键字的理解

    修饰范围: 可以修饰成员变量和成员方法.静态的特点: A:随着类的加载而加载 B:优先于对象存在 C:被类的所有对象共享 这其实也是我们判断该不该使用静态的依据. 举例:饮水机和水杯的问题思考可通过类 ...

  10. SQL2005以上行变行简单实现

    用语法PIVOT参照:http://technet.microsoft.com/zh-cn/library/ms177410(v=sql.105).aspx