Contents

Groovy与Json

1. 简介

在本文中,我们将描述并查看有关如何在Groovy 应用程序中使用 JSON 的示例。

首先,要启动并运行本文的示例,我们需要设置pom.xml

<build>
    <plugins>
        // ...
        <plugin>
            <groupId>org.codehaus.gmavenplus</groupId>
            <artifactId>gmavenplus-plugin</artifactId>
            <version>1.6</version>
        </plugin>
    </plugins>
</build>
<dependencies>
    // ...
    <dependency>
        <groupId>org.codehaus.groovy</groupId>
        <artifactId>groovy-all</artifactId>
        <version>2.4.13</version>
    </dependency>
</dependencies>

最新的 Maven 插件可以在这里 找到,最新版本的groovy-all可以在这里 找到。

2. 将 Groovy 对象解析为 JSON

在 Groovy 中将对象转换为 JSON 非常简单,假设我们有一个Account类:

class Account {
    String id
    BigDecimal value
    Date createdAt
}

要将该类的实例转换为 JSON字符串,我们需要使用JsonOutput类并调用静态方法toJson()

Account account = new Account(
    id: '123', 
    value: 15.6,
    createdAt: new SimpleDateFormat('MM/dd/yyyy').parse('01/01/2018')
) 
println JsonOutput.toJson(account)

结果,我们将得到解析后的 JSON字符串:

{"value":15.6,"createdAt":"2018-01-01T02:00:00+0000","id":"123"}

2.1. 自定义 JSON 输出

如我们所见,日期输出不是我们想要的。为此,从 2.5 版开始,包groovy.json附带了一组专用工具。

使用JsonGenerator类,我们可以为 JSON 输出定义选项:

JsonGenerator generator = new JsonGenerator.Options()
  .dateFormat('MM/dd/yyyy')
  .excludeFieldsByName('value')
  .build()
println generator.toJson(account)

结果,我们将获得格式化的 JSON,不包含我们排除的值字段和格式化的日期:

{"createdAt":"01/01/2018","id":"123"}

2.2. 格式化 JSON 输出

通过上面的方法,我们看到 JSON 输出总是在一行中,如果必须处理更复杂的对象,它会变得混乱。

但是,我们可以使用prettyPrint方法格式化我们的输出:

String json = generator.toJson(account)
println JsonOutput.prettyPrint(json)

我们得到格式化的 JSON 波纹管:

{
    "value": 15.6,
    "createdAt": "01/01/2018",
    "id": "123"
}

3. 将 JSON 解析为 Groovy 对象

我们将使用 Groovy 类JsonSlurper将 JSON 转换为对象。

此外,对于JsonSlurper ,我们有一堆重载的解析方法和一些特定的方法,如parseTextparseFile等。

我们将使用parseTextString解析为Account 类:

def jsonSlurper = new JsonSlurper()
def account = jsonSlurper.parseText('{"id":"123", "value":15.6 }') as Account

在上面的代码中,我们有一个方法接收一个 JSON字符串并返回一个Account对象,它可以是任何 Groovy 对象。

此外,我们可以将 JSON String解析为Map,调用它而不进行任何转换,并且使用 Groovy 动态类型,我们可以拥有与对象相同的内容。

3.1. 解析 JSON 输入

JsonSlurper的默认解析器实现是JsonParserType.CHAR_BUFFER,但在某些情况下,我们需要处理解析问题。 让我们看一个例子:给定一个带有日期属性的JSON字符串,JsonSlurper将无法正确创建对象,因为它会尝试将日期解析为字符串:

def jsonSlurper = new JsonSlurper()
def account 
  = jsonSlurper.parseText('{"id":"123","createdAt":"2018-01-01T02:00:00+0000"}') as Account

因此,上面的代码将返回一个Account对象,其所有属性都包含null值。

要解决该问题,我们可以使用JsonParserType.INDEX_OVERLAY

因此,它将尽可能避免创建String或 char 数组:

def jsonSlurper = new JsonSlurper(type: JsonParserType.INDEX_OVERLAY)
def account 
  = jsonSlurper.parseText('{"id":"123","createdAt":"2018-01-01T02:00:00+0000"}') as Account

现在,上面的代码将返回一个适当创建的Account实例。

3.2. 解析器变体

此外,在JsonParserType 内部,我们还有一些其他实现:

  • JsonParserType.LAX将允许更轻松的 JSON 解析,包括注释、无引号字符串等。
  • JsonParserType.CHARACTER_SOURCE用于大文件解析。