Zerknąłem na dokumenty API dla JSON i nie wydaje się, żeby można było przetworzyć łańcuch JSON na konkretny typ obiektu.
Musisz napisać kod, aby przekonwertować każdy kod JSONObject
na Foo
. Coś jak to powinno działać:
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"))
}
Bardziej ogólnie rozwiązaniem byłoby, aby dodać nową statyczną parse
metody, takie jak następujące w JSON
metaklasa, że stara się analizować łańcuch JSON do listy obiektów danego wpisz:
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'] }
Możesz wypróbować powyższy kod w konsoli groovy. Kilka ostrzeżenia
- Mam wykonywane jedynie bardzo ograniczone badania na kodzie powyżej
- Istnieją dwie klasy JSON w najnowszym Grails wydaniu, jestem przy założeniu, że używasz jednego, że nie jest nieaktualna
Czy byłoby możliwe wprowadzenie atrybutów każdego directoy jsonObj w polu foo.properties dla każdej nowej instancji Foo? – Armand
@Ali G - Nie, myślę, że '.properties' jest zapisywalny tylko dla obiektów domeny Grails. W przypadku zwykłych obiektów Groovy, myślę, że '.properties' jest tylko do odczytu. –
Dzięki Don. Ogólne podejście jest bardzo miłe. – armandino