在Groovy中使用JSONBuilder排除null值



是否可以使用默认的JsonBuilder库在Groovy中创建JSON值以排除对象的所有空值?比如Jackson在Java中通过注释类来排除null值的做法。

例如:

{
   "userId": "25",
   "givenName": "John",
   "familyName": null,
   "created": 1360080426303
}

应打印为:

{
   "userId": "25",
   "givenName": "John",
   "created": 1360080426303
}

不确定它是否适合您,因为我的方法适用于具有List属性的Map

def map = [a:"a",b:"b",c:null,d:["a1","b1","c1",null,[d1:"d1",d2:null]]]
def denull(obj) {
  if(obj instanceof Map) {
    obj.collectEntries {k, v ->
      if(v) [(k): denull(v)] else [:]
    }
  } else if(obj instanceof List) {
    obj.collect { denull(it) }.findAll { it != null }
  } else {
    obj
  }
}
println map
println denull(map)

收益率:

[a:a, b:b, c:null, d:[a1, b1, c1, null, [d1:d1, d2:null]]]
[a:a, b:b, d:[a1, b1, c1, [d1:d1]]]

过滤掉null值之后,就可以将Map呈现为JSON。

如果使用Groovy>2.5.0,则可以使用JsonGenerator。以下示例取自Groovy截至2018年7月的文档。

class Person {
    String name
    String title
    int age
    String password
    Date dob
    URL favoriteUrl
}
Person person = new Person(name: 'John', title: null, age: 21, password: 'secret',
                            dob: Date.parse('yyyy-MM-dd', '1984-12-15'),
                            favoriteUrl: new URL('http://groovy-lang.org/'))
def generator = new JsonGenerator.Options()
    .excludeNulls()
    .dateFormat('yyyy@MM')
    .excludeFieldsByName('age', 'password')
    .excludeFieldsByType(URL)
    .build()
assert generator.toJson(person) == '{"dob":"1984@12","name":"John"}'

我使用Groovy元类来解决这个问题,但不确定它是否适用于所有情况。

我创建了一个类来容纳所需的元素,但忽略了可能具有null(或空)值的可选元素。

private class User {
    def id
    def username
}

然后,我将数据添加到这个类中。我的用例相当复杂,所以这是一个简化的版本,只是为了展示我所做的一个例子:

User a = new User(id: 1, username: 'john')
User b = new User(id: 2, username: 'bob')
def usersList = [a,b]
usersList.each { u ->
    if (u.id == 1)
        u.metaClass.hobbies = ['fishing','skating']
}
def jsonBuilder = new JsonBuilder([users: usersList])
println jsonBuilder.toPrettyString()

结果:

{
"users": [
    {
        "id": 1,
        "username": "john",
        "hobbies": [
            "fishing",
            "skating"
        ]
    },
    {
        "id": 2,
        "username": "bob"
    }
  ]
}

如果您不需要使用JSONBuilder,您可以使用com.fasterxml.jackson:

生成对象:

private static final ObjectMapper JSON_MAPPER = new ObjectMapper().with {
    setSerializationInclusion(JsonInclude.Include.NON_NULL)
    setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY)
    setVisibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE)
    setVisibility(PropertyAccessor.IS_GETTER, JsonAutoDetect.Visibility.NONE)
}

并显示这样的地图列表(地图内部可以有任何对象):

println(JSON_MAPPER.writeValueAsString(listOfMaps))

相关内容

  • 没有找到相关文章

最新更新