问题
Is it possible to create JSON values in Groovy using the default JsonBuilder library to exclude all the null values of an object? Such as what Jackson does in Java by annotating classes to exclude null values.
An example would be:
{
"userId": "25",
"givenName": "John",
"familyName": null,
"created": 1360080426303
}
Which should be printed as:
{
"userId": "25",
"givenName": "John",
"created": 1360080426303
}
回答1:
Not sure if it's OK for you as my method works on a Map
with List
properties:
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)
yields:
[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]]]
After filter null
values out, you then can render the Map
as JSON.
回答2:
I used the Groovy metaClass to workaround this issue, but am not sure it would work in all cases.
I created a Class to hold the required elements, but left out the optional elements that could possibly have a null (or empty) value.
private class User {
def id
def username
}
Then, I added the data to this class. My use case was fairly complex so this is a simplified version just to show an example of what I did:
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()
Results:
{
"users": [
{
"id": 1,
"username": "john",
"hobbies": [
"fishing",
"skating"
]
},
{
"id": 2,
"username": "bob"
}
]
}
回答3:
If you do not need use JSONBuilder you can use com.fasterxml.jackson:
Make object:
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)
}
and display your list of maps like that (maps can have any Object inside):
println(JSON_MAPPER.writeValueAsString(listOfMaps))
回答4:
If you are using Groovy >2.5.0, you can use JsonGenerator
. The example below is taken from Groovy's Documentation as of July 2018.
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"}'
来源:https://stackoverflow.com/questions/14749817/exclude-null-values-using-jsonbuilder-in-groovy