He echado un vistazo a los documentos API para JSON y no parece haber ninguna forma de analizar una cadena JSON para un tipo específico de objeto.
Así que solo tendrá que escribir el código usted mismo para convertir cada JSONObject
en Foo
. Algo como esto debería funcionar:
import grails.converters.JSON
import org.codehaus.groovy.grails.web.json.*
class Foo {
def name
Foo(name) {
this.name = name
}
String toString() {
name
}
}
List list = [new Foo("first"), new Foo("second")]
def jsonString = (list as JSON).toString()
List parsedList = JSON.parse(jsonString)
// Convert from a list of JSONObject to a list of Foo
def foos = parsedList.collect {JSONObject jsonObject ->
new Foo(name: jsonObject.get("name"))
}
Una solución más general sería añadir un nuevo método estático parse
como la siguiente a la JSON
MetaClass, que trata de analizar la cadena JSON a una lista de objetos de una determinada tipo:
import grails.converters.JSON
import org.codehaus.groovy.grails.web.json.*
class Foo {
def name
Foo(name) {
this.name = name
}
String toString() {
name
}
}
List list = [new Foo("first"), new Foo("second")]
def jsonString = (list as JSON).toString()
List parsedList = JSON.parse(jsonString)
// Define the new method
JSON.metaClass.static.parse = {String json, Class clazz ->
List jsonObjs = JSON.parse(json)
jsonObjs.collect {JSONObject jsonObj ->
// If the user hasn't provided a targetClass read the 'class' proprerty in the JSON to figure out which type to convert to
def targetClass = clazz ?: jsonObj.get('class') as Class
def targetInstance = targetClass.newInstance()
// Set the properties of targetInstance
jsonObj.entrySet().each {entry ->
if (entry.key != "class") {
targetInstance."$entry.key" = entry.value
}
}
targetInstance
}
}
// Try the new parse method
List<Foo> foos = JSON.parse(jsonString, Foo)
// Confirm it worked
assert foos.every {Foo foo -> foo.class == Foo && foo.name in ['first', 'second'] }
Puede probar el código anterior en la consola groovy. Unas pocas advertencias
- sólo han llevado a cabo pruebas muy limitado en el código anterior
- Hay dos clases de JSON en la última Griales liberan, estoy asumiendo que usted está usando el que no está en desuso
¿Sería posible inyectar los atributos de cada directorio jsonObj en el campo foo.properties para cada nueva instancia de Foo? – Armand
@Ali G - No, creo que '.properties' solo se puede escribir en objetos de dominio de Grails. Para los objetos normales de Groovy, creo que '.properties' es de solo lectura. –
Gracias Don. El enfoque genérico es muy agradable. – armandino