Ho dato un'occhiata ai documenti API per JSON e non sembra che esista un modo per analizzare una stringa JSON per un tipo specifico di oggetto.
Quindi devi solo scrivere il codice da solo per convertire ogni JSONObject
in un Foo
. Qualcosa del genere dovrebbe funzionare:
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 soluzione più generale potrebbe essere quella di aggiungere un nuovo metodo statico parse
come il seguente al JSON
metaclasse, che cerca di analizzare la stringa JSON a un elenco di oggetti di un particolare 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'] }
È possibile provare il codice sopra nella console Groovy. Alcuni avvertimenti
- Ho effettuato solo test molto limitato sul codice di cui sopra
- Ci sono due classi di JSON nell'ultima Grails rilasciano, sto supponendo che si sta utilizzando quello che non è deprecato
fonte
2010-04-20 08:12:53
Sarebbe possibile iniettare gli attributi di ogni directoy di jsonObj nel campo foo.properties per ogni nuova istanza di Foo? – Armand
@Ali G - No, penso che '.properties' sia scrivibile solo per gli oggetti del dominio Grails. Per gli oggetti Groovy regolari, penso che ".properties" sia di sola lettura. –
Grazie Don. L'approccio generico è molto carino. – armandino