是否可以使用默认的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))