Jackson 反序列化 "Y"/"N" 为相应的布尔值

JSON 表示布尔值标准的形式是 true  和  false,如果 Java 对应的类型是对象  Boolean,那么在 JSON 中也可以是  null。如果收到 JSON 数据是用 'Y'/'N', 或 'Yes'/'No' 来表示布尔值的,那么使用 Java 的 Jackson 库如何把它们反序列化为相应的布尔属性值呢?

如果按照 JSON 规范必须把内容中的布尔值全部转换为 true 或 false, 然而再反序列化,否则需要定制 Boolean 类型的反序列化类,可应用到全局的 boolean 类型,或指派给特定的 boolean 类型属性。

如果尝试反序列化 Y, 或 N 为 Java 的 boolean 值,会有只接受  true 或 false 的异常:

com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not deserialize value of type java.lang.Boolean from String "Y": only "true" or "false" recognized

具体步骤是: 阅读全文 >>

Jackson 序列化忽略指定类型的属性

本文准确来讲是探讨如何用 Jackson 来序列化 Apache avro 对象,因为简单用 Jackson 来序列化 Apache avro 对象会报错。原因是序列化 Schema getSchema() 时会报错,后面会讲到,需要序列化时忽略该属性。那么能不能在 getSchema() 上加上 @JsonIgnore 来忽略该属性呢?原理上是通的。不过手工修改的 avsc 生成的 Java 文件随时会因为重新编译而还原,所以不太具有实际可操作性,当然通过定制编译 avsc 用的模板文件来加入 @JsonIgnore 是另一回事。

由于不能在要忽略的字段上添加 JsonIgnore 来控制,而如果我们明确了要忽略的字段类型的话,是能够定制 Jackson 的  ObjectMapper  来屏蔽某个特定的类型。来看下面序列化 Apache avro 对象的例子:

假设我们有一个 Apache 的 Schema 文件 user.avsc, 内容如下: 阅读全文 >>

早先为 Jackson 写的 Json-Path 支持

今天才发现 Jackson 其实是支持 Json-Path 的,但以前一直不知道,关键是 Jackson 的文档也没见提到。所以很久以前是自己给 Jackson 写了一个简陋的 Json-Path 支持类,这个是为测试代码用的,所以基本够用。想要更全面的功能可使用 https://github.com/jayway/JsonPath 这个项目。对于 Jackson 中如何使用 Json-Path, 我还会进一步研究下。

我写的 RichJsonNode 类是一个 Scala 版本,最早也写过一个 Java 版本,还有一个基于 GSON 的 Java 版本的。这里只贴出 Scala 版源码。支持的基本方法及语法如下:

a/b, a/b[2], a/b[1]/c, a[1]/b, $[0]

selectNode(path), selectString(path), selectInt(path), selectDouble(path), selectBollean(path), hasField(path) 和  arrayLength(path)

源码如下: 阅读全文 >>

自定义 Jackson 注解与禁用某一特定的注解

Jackson 是 Playfrmework 2 中默认的 JSON 处理框架,先前是  GSON,JSON 是 Playframework 中的第一等公民,可见 Jackson 在 Playframewok 中的重要地位。Jackson 提供了一系列的注解可用,像 @JsonIgnore, @JsonProperty, @JsonUnwrapped, @JsonFilter 等。人的需求总是很难得到满足,所以免不了还是要定义自己的注解。比如有这样一个需求,JavaBean 中被 @MaskField(这个即将成为我第一个自定义的注解) 标记的属性或 getter 方法,总是输出为 ******, 无此标记的属性或方法输出原始值。

我尝试过 @JsonFilter  或是单纯的自定义  JsonSerializer, 并不怎么如意。本人最终的实现方式涉及到

  • @JacksonAnnotationsInside -- 用来创建自己的 @MaskField 注解
  • JsonSerializer  -- 被 @MaskField 标记的字段采用自定义的 JsonSerializer 来序列化
  • JacksonAnnotationIntrospector  -- 禁用某一特定的注解,这样可以在做任意时候启用或禁用 @MaskField 阅读全文 >>

为 Jackson 自定义序列化对象的 JSON 格式

伴随着 Play1, 我们原来使用的 JSON 库是 Gson. 回忆下 Gson 是怎么自定义序列化对象的 JSON 格式,大概是这样子的

GsonBuilder()..registerTypeHierarchyAdapter(Cat.class, new Cat());

然后 Cat 需要实现 JsonSerializer 的 serialize() 方法。

来到了 Play2 中,JSON 库变成了 Jackson,那么 Jackson 该如何为对象自定义 JSON 格式呢?

例如,默认时 Jackson 对 Map 类型输出的是一个 JSON 对象

Map("key1"->"value1", "key2"->"value2")     转换成 JSON 是 {"key1":"value1", "key2":"value2"}

当为适应某些客户端,对于 LinkedHashMap 类型,我们想要输出的是一个有序的 JSON 数组: [{"key1":"value1"},{"key2":"value2"}]

我们就应该自定义某些 Map 的序列化格式,实现方法有两种,addSerializer 和 @JsonSerialize,不管哪种方式都需事先具体化 JsonSerializer 类,并实现它的 serialize 抽象方法

所以我先来实现一个能序列化 Map 的 JsonArrayMapSerializer 类 阅读全文 >>

使用 Jackson 把 Java 对象转换成 JSON 字串

原来 Java 项目中用的 JSON 组件库主要是 Gson 和 json-lib,Gson 算是很错的库,json-lib 略显寒碜。好啦,最近 Play 2.x 中弃用了 Gson 而采纳了 Jackson,所以现在就来打探一下 Jackson,踩个点吧。

Jackson 号称非常高的性能,听说比另两位兄弟 Gson 和 json-lib 高出一大截,我没有亲测,可是有心人做了,看这个链接 两款JSON类库Jackson与JSON-lib的性能对比(新增第三款测试) 中的数据。2010 年 8 月份的测试结果,不知现在随着版本的变更是否仍然保持着这种悬殊。

通常我会在把文章开头塞丰满,做足前戏,并不是因为在天涯混习惯了的缘故,况且我在天涯总是讷于言的; 在这里,自己的地盘自己作主,不会有要求码足多少字才能发表的自虐性需求,仅仅是让本文在主页上显示时的的概要不空洞而已,可以简单粗暴的称之为废话。

了了,先了解 Jacson 最贴近实际应用场景的应用,即 Jackson 怎么把一个 Java 生成对应的 JSON 字符串,看看前面的文字有这么多了,直接上一段代码吧,而后再慢慢假设与分解: 阅读全文 >>

Struts2-Json-Plugin 的使用(翻译自官方文档)

在 Struts2 中要使用 Ajax 获得 Json 数据我认为目前还是 struts2-json-plugin 了。当然你你可以用手工用像 XStreamGoogle GsonJackson 这样的工具手工把 Java 对象转换成 Json 字符串再写往 Response 去,要写的代码自然多不了,还得留心字符集与 content type。而 struts2-json-plugin 毫无疑问是与 Struts2 最亲近了,只需你配置一些属性就能得到你想的结果。

本想分几篇逐步介绍如何使用 struts2-json-plugin 的,然而就在现在发现官方的 struts2-json-plugin 指南已经很详细了,所以干脆翻译一下 http://struts.apache.org/2.2.1.1/docs/json-plugin.html,同时自己加深对它的理解。 阅读全文 >>

使用 XStream 在 JavaBean 与 XML/JSON 之间相互转换

XML 和 JSON 是当今常用的两种数据描述与传输的格式,特别是涉及到 JS 时使用 JSON 颇为频繁。自然,在 Java  的世界里少不了完成 JavaBean 与这两种格式相互转换的组件,那就是 XStream 和 JSON-lib。这里我简单记下 XStream  的用法。

其实相类似的工具早已有之。如果用过 DWR 的同志,一定有印像,DWR 进行远程方法调用时也能为你完成 JavaBean 和 JSON 格式的双向转换的,所依赖的是它的各种 Converter。再要是对 Struts1 的细节有所注意的话,Struts1 的 ActionServlet 在初始化 struts-config.xml 时是通过 commons-digester 来完成 XML 到 JavaBean 转换的。相应的 Apache 也有一个 commons-betwixt 实现了 JavaBean 到 XML 的生成。 阅读全文 >>