一个现代化的JSON库Moshi针对Android和Java
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的更多相关文章
- 推荐一个golang的json库
生成json的库 https://github.com/bennyscetbun/jsongo https://github.com/donnie4w/json4g
- <Android开源库 ~ 1> GitHub Android Libraries Top 100 简介
转载自GitHub Android Libraries Top 100 简介 本项目主要对目前 GitHub 上排名前 100 的 Android 开源库进行简单的介绍, 至于排名完全是根据 GitH ...
- 1. 初识Jackson -- 世界上最好的JSON库
要想人前显贵,必须背后受罪.关注公众号[BAT的乌托邦]开启专栏式学习,拒绝浅尝辄止.本文 https://www.yourbatman.cn 已收录,里面一并有Spring技术栈.MyBatis.中 ...
- Java几种常用JSON库性能比较
本篇通过JMH来测试一下Java中几种常见的JSON解析库的性能. 每次都在网上看到别人说什么某某库性能是如何如何的好,碾压其他的库.但是百闻不如一见,只有自己亲手测试过的才是最值得相信的. JSON ...
- JSON库的使用研究(一)
最近用到JSON,收集了一些资料,整理如下: 选择一个合适的JSON库要从多个方面进行考虑: 字符串解析成JSON性能 字符串解析成Java Object性能 Java Object转JSON性能 集 ...
- Java常用的几个Json库,性能强势对比!
作者:飞污熊 https://xncoding.com/2018/01/09/java/jsons.html 本篇通过JMH来测试一下Java中几种常见的JSON解析库的性能.每次都在网上看到别人说什 ...
- 一个可以将 json 字符串 直接绑定到 view 上的Android库
android-data-binding 这是一个可以将 json 字符串 直接绑定到 view 上的库, 不用先将 json 转换为 model 类. 传送门(https://github.com/ ...
- Fastjson是一个Java语言编写的高性能功能完善的JSON库。
简介 Fastjson是一个Java语言编写的高性能功能完善的JSON库. 高性能 fastjson采用独创的算法,将parse的速度提升到极致,超过所有json库,包括曾经号称最快的jackson. ...
- 极力推荐一个简单好用的C++JSON库
极力推荐一个简单好用的C++JSON库CJsonObject,让使用json如使用C++原生的结构体那般方便,随心所欲.CJsonObject是个优秀的C++JSON库,也许会是你见过的最为简单易 ...
随机推荐
- 7 个面向Web开发者的实用CSS3教程推荐
通过CSS来创建精细.复杂的效果,成为了Web前端开发的未来趋势.世界各地的设计师认为CSS3是一项非常具有潜力的技术,未来将会创造更多不可思议的美妙设计. 本文为Web开发者带来了一些与CSS3相关 ...
- Memcached‘do_item_get’函数安全漏洞
漏洞名称: Memcached‘do_item_get’函数安全漏洞 CNNVD编号: CNNVD-201401-175 发布时间: 2014-01-15 更新时间: 2014-01-15 危害等级: ...
- windows下nginx安装、配置与使用
目前国内各大门户网站已经部署了Nginx,如新浪.网易.腾讯等:国内几个重要的视频分享网站也部署了Nginx,如六房间.酷6等.新近发现Nginx 技术在国内日趋火热,越来越多的网站开始部署Nginx ...
- 事件流处理框架NEsper for .NET z
复合事件处理(Complex Event Processing)介绍提到了开源的Esper,NEsper 是一个事件流处理(Event Stream Processing,ESP)和复杂事件处理(Co ...
- Loadrunner执行Java脚本
1. Eclipse中调试Java脚本,脚本调试通过后,打成jar包: 2. 新建lr脚本,选择Java vuser协议: 3. Run-time Settings中Classpath设置jar包,没 ...
- Hacking Secret Ciphers with Python翻译序言
马上就要下班,一直想做点什么,学点什么,但是似乎从未着手. 是的,我想学习Hacking,或许很多人都想学,但是诸多的大牛说,这个得有基础,万丈高楼平地起,我做过那么一点点的密码分析,加上某些地方有小 ...
- 关于Spring的Controller及Struts的Action的多线程的注意
struts是线程安全,并不是指多线程,而是指单态,当多个用户访问一个请求的时候,服务器内存中只有一个与之对应的action类对象,execute方法加上了同步关键字,如果你在action里加上一个全 ...
- 电脑IP改变后oracle em无法登陆的解决办法(亲测)
以下方法为本人亲测 情况:假设电脑初次安装oracle时的ip是192.168.133.110 那么进入em的地址就是http://192.168.133.110:1158/em/console/lo ...
- 伪分布配置完成启动jobtracker和tasktracker没有启动
检查logs目录下的hadoop-root-jobtracker日志文件 2014-02-26 19:56:06,782 FATAL org.apache.hadoop.mapred.JobTrack ...
- ABAP SY标签一览 .
Description: SY-SUBRC:语句执行后的返回值,0表示成功SY-DATUM:当前服务器日期SY-UZEIT:当前服务器时间SY-ULINE:255长度的水平线SY-VLINE:垂直线S ...