2012-03-09 8 views
17

Uso il seguente codice per il rendering di dati in formato JSON.Rendering JSON in grails

render(contentType:"text/json") { 
    results = array { 
     db.eachRow(query) { row -> 
      def rs = row.toRowResult() 
      def a = b(rs.name,c,d) 
      aMap.put("A",a) 
      pair(aMap) 
     } 
    } 
    if (results) { 
     status = "OK" 
    } 
    else { 
     status ="Nothing present" 
    } 
} 

Il codice precedente genera JSON nel seguente formato

{ 
    "results": [ 
     {"A":"value1"}, 
     {"A":"value2"}, 
     ................... 
     {"A":"valuen"} 
    ], 
    "status":"OK" 
} 

Come u vedi sopra, i dati vengono resi come array di oggetti. Esiste un modo per rendere i dati dei risultati come una serie di elementi . Come

{ 
    "results": [ 
     "value1", 
     "value2", 
     ................... 
     "valuen" 
    ], 
    "status":"OK" 
} 

risposta

35

Il modo in cui viene costruito l'oggetto JSON è piuttosto oscuro. Quello che mi piace fare per rendere le risposte JSON in Grails è creare una mappa o un elenco in groovy e quindi utilizzare il metodo render solo per convertirlo in JSON.

Facendo la trasformazione dei 's rowResult all'interno del metodo render lo rende molto confusa, preferirei andare per qualcosa di simile

def results = db.rows(query).collect { rowResult -> 
    b(rowResult.name, c, d) 
} 
render(contentType: 'text/json') {[ 
    'results': results, 
    'status': results ? "OK" : "Nothing present" 
]} 

Penso che sia più leggibile, e ancora più breve. Questo frammento ti dà il risultato desiderato: nessun oggetto all'interno dell'array results, solo stringhe.

Nota l'uso di rows, che restituisce un elenco di RowResult, eliminando la necessità di ottenerlo dal ResultSet. L'elenco viene utilizzato per raccogliere il valore trasformato a chiamando b sul nome di ogni riga. La raccolta degli elementi non implica la creazione di una mappa (come nel JSON { "A":"value1"} che si stava ricevendo), lo stesso @ will-buck ottenuto con l'operatore << in una nuova lista vuota.

Tutto quello che facciamo con il metodo di rendering sta dichiarando il tipo di text/json contenuti e passandolo una mappa letterale contenente le chiavi results e status, che si desidera scrivere la risposta. L'operatore condizionale viene utilizzato per determinare concisamente lo stato. Potrebbe anche essere usato in questo modo, tramite il convertitore JSON @ will-buck anche citato:

def responseData = [ 
    'results': results, 
    'status': results ? "OK" : "Nothing present" 
] 
render responseData as JSON 
+1

Mi piace il tuo ultimo frammento di codice migliore del primo. Probabilmente è anche più debugger-friendly. – epidemian

+0

Sì, quel convertitore JSON è sicuramente la strada da percorrere :) –

+1

Problemi con l'ultimo frammento di codice in Grails 2.0. La risposta è resa come testo racchiuso in '{}'. – raffian

4

Solo fuori da un po ':) solo bisogno di cambiare

aMap.put("A", a) 

essere una raccolta o di un elenco, piuttosto che una mappa. quindi qualcosa come

def aList = [] 
aList << a 

Ti farà ottenere quello che vuoi!

Come sidenote, c'è un convertitore JSON in grails che eseguirà questa costruzione di stringhe per te. Guardalo dentro here

Problemi correlati