Iterating object properties in Groovy?

I created a class that allows the resulting object to add arbitrary properties to it. The class also has some predefined properties. In the class method, I want to be able to iterate over all the properties that belong to an instance of an object.

Here is an example of a 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 want to do?

Edit: One of my goals is not to specify explicit predefined properties in the toJsonString method. I want to be able to add new predefined properties later, without thinking about updating the toJsonString method.

Edit (October 24, 2011):

The accepted answer gave me the information I needed. However, I still needed to specify properties that I do not want to include in the JSON string. Extending the answer solves this problem a bit:

 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 modifiers for your class properties. That is, String bar = "baz" in my example should be public String bar = "baz" so that it is included in the JSON string.

+6
source share
2 answers

There is this opportunity (if I have the right end of the stick); -)

 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 = Foo.declaredFields.findAll { !it.synthetic && it.name != 'props' }.collectEntries { v -> [ (v.name):this[v.name] ] } outObject << props JsonOutput.toJson(outObject) } } 

If you do not have Groovy 1.7.9+, then the lines

  def outObject = Foo.declaredFields.findAll { !it.synthetic && it.name != 'props' }.collectEntries { v -> [ (v.name):this[v.name] ] } 

Must be replaced by:

  def outObject = Foo.declaredFields.findAll { !it.synthetic && it.name != 'props' }.inject([:]) { m, v -> m << [ (v.name):this[v.name] ] } 

And I believe that he will behave the same way; i.e.: if I do this:

 def f = new Foo() f.tim = 'yates' println f.toJsonString() 

prints out:

 {"bar":"baz","myNumber":42,"tim":"yates"} 
+7
source

If you want to stick with this implementation, perhaps overriding getProperties to include your property map would be the easiest.

0
source

Source: https://habr.com/ru/post/899814/


All Articles