Reputation: 1192
I would like to change the way enums are marshalled to JSON. I am currently using default grails.converters.JSON ( as JSON) and for example in controller I use:
FilmKind.values() as JSON
The output of this is:
"kind":[{"enumType":"FilmKind","name":"DRAMA"},{"enumType":"FilmKind","name":"ACTION"}]
I would like to remove "enumType" and just return:
"kind":["DRAMA","ACTION"]
I am looking for a solution which would still allow me to use
as JSON
because I don't want to marshall each enumeration individually.
Upvotes: 5
Views: 4148
Reputation: 335
In case anyone is wandering how to convert all enum values to plain String values in a generic way:
class EnumTypeHidingJSONMarshaller {
void register() {
JSON.registerObjectMarshaller(Enum) { Enum someEnum ->
someEnum.toString()
}
}
}
Upvotes: 17
Reputation:
How about:
def display = [kind:[]]
FilmKind.values().each { val ->
display.kind.add(val.value)
}
render display as JSON
Upvotes: 1
Reputation: 35864
because I don't want to marshall each enumeration individually.
Well, unless you want to write your own JSON converter, marshalling is the best approach here. Reason is because the only real other way is to do what Sergio is suggesting and you'll have to call that code everywhere you need it. And if FilmKind is a property of another class then his solution won't work at all really.
I would suggest Marshallers and here is how I would do it. Create a class called FilmKindMarsaller:
class FilmKindMarshaller {
void register() {
JSON.registerObjectMarshaller(FilmKind) { FilmKind filmKind ->
[
name: filmKind.toString()
]
}
}
}
Then add the following to your Bootstrap:
[ new FilmKindMarshaller() ].each { it.register() }
The above is so that you can just keep adding instances of each Marshaller you need.
Now, anytime FilmKind is JSON'ified, be that on its own or part of a parent class, you get the JSON you want, sans enumType.
Upvotes: 12
Reputation: 19682
You can register a custom object marshaller for your domain class to allow as JSON
. In your Bootstrap.groovy
, you can do something like this:
JSON.registerObjectMarshaller(FilmKind) {
def result = [:]
def props = ['name']
props.each { prop ->
result[prop] = it."$prop"
}
result
}
Upvotes: 3