2013-05-25 6 views
5

Came attraverso questo strano risultato oggi cercando di rendere un elenco di oggetti come JSON in Grails 2.0.4 ... (so che mi pentirò di chiedere questo a causa di qualcosa proprio sotto il mio naso ... aggiornato 5/26, la mia previsione era corretta, vedi sotto :-))Rendering 'as JSON' in Grails con operatore condizionale non renderizzato correttamente

Questo funziona bene; il JSON rende correttamente nel browser ...

def products = [] //ArrayList of Product objects from service  
def model = (products) ? [products:products] : [products:"No products found"] 
render model as JSON 

..quindi perchè non lo fa questa versione più breve, senza model lavoro?

def products = []  
render ((products) ? [products:products] : [products:"No products found"]) as JSON 

Il JSON risultante dal codice di cui sopra è uscita come una singola riga di testo, così ho il sospetto che non è raccogliendo as JSON, ma è tra parentesi correttamente, quindi qual è il problema?

[ 'prodotti': [com.test.domain.Product: null, com.test.domain.Product ...]

risposta

8

Questo è un comportamento normale di render. Quando si forniscono argomenti per render senza bretelle come

render model as JSON

Si fa una impostazione del content-type-text/json regolazione implicita. Ma nel caso in seguito, si è inconsapevolmente fatto il render di utilizzare le parentesi come [segno nella prima parentesi dopo render fa rendere l'uso della normale render()]

render ((products) ? [products:products] : [products:"No products found"]) as JSON.

Nel caso di cui sopra, si deve passare nei parametri denominati per render menzionare la contentType, text o model, status ecc Quindi, al fine di rendere la logica di controllo in linea come JSON browser/visualizzare quello che dovete fare come qui di seguito:

render(contentType: "application/json", text: [products: (products ?: "No products found")] as JSON) 

È inoltre possibile utilizzare content-type come text/json. Preferisco application/json.

UPDATE
alternativa Modo più semplice:
render([products: (products ?: "No products found")] as JSON)

+0

Dannazione, sto invocando 'render()' senza nemmeno rendersene conto, thx, ho finito per andare con questo utilizzando gli elementi della soluzione, è un poco più breve ed evita di specificare il tipo di contenuto due volte: 'render (contentType:" text/json ") {[prodotti: (prodotti?:" Nessun prodotto trovato ")]} – raffian

+4

Funzionerebbe anche:' render ((prodotti ? [prodotti: prodotti]: [prodotti: "Nessun prodotto trovato"]) come JSON) ' –

+0

@JamesKleeh Ace nella buca, bello! .. ed esattamente quello che stavo cercando! – raffian

1

Non si conosce la ragione. Provare a usare in questo modo:

render(contentType: 'text/json') {[ 
    'products': products ? : "No products found" 
]} 
1

Quello che sta chiamando rendering con i parametri in(), e quindi l'applicazione "come JSON" per il risultato!

Non dimenticare che lasciare le parentesi è solo una scorciatoia per una chiamata al metodo, ma le stesse regole si applicano ancora.

3

L'essenza del problema qui è che il compilatore Groovy interpreta

render x as JSON 

a significare

render (x as JSON) 

ma interpreta

render (x) as JSON 

a significare

(render x) as JSON 

Se un nome di metodo (in questo caso render) viene seguito immediatamente da una parentesi di apertura, solo il codice fino alla parentesi di chiusura corrispondente viene considerato come l'elenco di argomenti. Questo è il motivo per cui è necessario un ulteriore set di parentesi per dire

render ((x) as JSON) 
Problemi correlati