Grails массив JSON

Я преобразовываю список объектов Foo к строке JSON. Я должен проанализировать строку JSON назад в список Foos. Однако в следующем примере, парсинг дает мне список JSONObjects вместо Foos.

Пример

List list = [new Foo("first"), new Foo("second")]
def jsonString = (list as JSON).toString()

List parsedList = JSON.parse(jsonString) as List
println parsedList[0].getClass() // org.codehaus.groovy.grails.web.json.JSONObject

Как я могу проанализировать его в Foos вместо этого?Заранее спасибо.

11
задан armandino 20 April 2010 в 00:06
поделиться

2 ответа

Я просмотрел документацию API для JSON, и, похоже, нет никакого способа выполнить синтаксический анализ строки JSON для определенного типа объекта.

Таким образом, вам просто нужно написать код самостоятельно, чтобы преобразовать каждый JSONObject в Foo . Примерно так должно работать:

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"))
}

Более общим решением было бы добавить новый статический метод parse , например, следующий к метаклассу JSON , который пытается проанализировать строку JSON. в Список объектов определенного типа:

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'] }

Вы можете попробовать приведенный выше код в Groovy-консоли. Несколько предупреждений

  • Я провел очень ограниченное тестирование кода выше
  • В последней версии Grails есть два класса JSON, я предполагаю, что вы используете тот, который не является устаревшим
13
ответ дан 3 December 2019 в 05:33
поделиться

Если вы делаете это в контроллере Grails, а Foo действительно ЯВЛЯЕТСЯ объектом домена, не забывайте, что вооружившись картой JSON, вы также можете сделать:

List list = [new Foo("first"), new Foo("second")]
def jsonString = (list as JSON).toString()

List parsedList = JSON.parse(jsonString) as List
Foo foo = new Foo()
bindData(foo, parsedList[0]);
4
ответ дан 3 December 2019 в 05:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: