Reputation: 1542
Running Grails 2.4.2 I cannot get enum binded from JSON string. I thought declaring a constructor that takes in value would solve the problem but it did not. I also tried passing JSON with name: "GENERIC", which did not bind either.
It is possible to bind to Enum if the value submitted as STRING. But that mean changing how JSON for enums inputed for binding vs rendered by default. Example, this works:
{"id":null,"templateCode": "GENERIC"}
What is the right/best way of getting enum binded from JSON?
class EmailTemplate {
TemplateCode templateCode
}
public enum TemplateCode {
GENERIC('Generic template'),
CUSTOM('Custom template')
final String value
EmailTemplateCode(String value) {
this.value = value
}
String getKey() {
name()
}
String toString() {
value
}
}
In Bootstrap.groovy
JSON.registerObjectMarshaller(Template) {
def map = [:]
map['templateCode'] = it.templateCode
return map
}
JSON.registerObjectMarshaller(TemplateCode) {
def map = [:]
map['name'] = it.name
map['value'] = it.value
return map
}
JSON being sent is
{"id":null,"templateCode":{"key":"GENERIC","value":"Generic template"}}
Edit: Simplified version
If we will use enum at its basic, making :
public enum TemplateCode {
GENERIC,CUSTOM
}
Grails will render it to JSON as:
templateCode: { enumType: com.EmailTemplateCode, name: GENERIC}
However, posting the same JSON string, will give an error and not bind to enum. The only way to do it, as mentioned above is by sending templatecode as a String:
templateCode: GENERIC
Upvotes: 2
Views: 1103
Reputation: 14640
Well, this will do what you want, but there's probably a better way to make ALL enums render in this fashion. In the bootstrap, use:
JSON.registerObjectMarshaller(TemplateCode) {
return it.toString()
}
This will properly render the EmailTemplate like:
{"templateCode":"CUSTOM"}
Upvotes: 2