I have created a class that allows the resulting object to have arbitrary properties added to it. The class also has some predefined properties. In a method of the class I want to be able to iterate over all properties owned by the instance of the object.
Here is an example class definition:
import groovy.json.*
class Foo {
private Map props = [:]
String bar = "baz"
def myNumber = 42
void propertyMissing(String name, Object value) {
this.props[name] = value
}
def propertyMissing(String name) {
return this.props[name]
}
def toJsonString() {
def outObject = [:]
// I want to do something like this
this.properties.each { k, v ->
if (this.isOwnProperty(k) && k != 'props') {
outObject[k] = v
}
}
outObject = outObject + this.props
return JsonOutput.toJson(outObject)
// Should return a string like:
// {"bar":"baz", "myNumber":42, "someDynamicProperty":"value"}
//
// This string should not contain the "class" and "metaClass"
// properties.
}
}
Is there a way to do what I am wanting to do?
Edit:
One of my goals is to not have to explicitly name my predefined properties in the toJsonString method. I want to be able to add new predefined properties at a later date without having to remember to update the toJsonString method.
Edit (24 October 2011):
The accepted answer gave me the information I needed. However, it still required me to name the properties I don’t want included in the JSON string. Extending the answer a little bit solves this problem:
def outObject = Foo.declaredFields.findAll {
// 'it' is a Field object returned by
// http://download.oracle.com/javase/1,5,0/docs/api/java/lang/Class.html#getDeclaredFields()
!it.synthetic &&
it.getModifiers() != java.lang.reflect.Modifier.PRIVATE
}.collectEntries { v ->
[ (v.name) : this[v.name] ]
}
For this to work, you must explicitly specify the modifiers for your class properties. That is String bar = "baz" in my example should be public String bar = "baz" in order for it to be included in the JSON string.
There’s this possibility (assuming I’ve got the right end of the stick) 😉
If you don’t have Groovy 1.7.9+, then the lines
Should be replaced with:
And I believe it will behave the same; ie: if I do this:
it prints out: