2012-05-31 13 views
12

Domanda: esiste un modo per eseguire l'associazione di oggetti comando automatico con request.JSON data?Oggetto comando Grails: come caricare request.JSON in esso?

Dato questo semplice oggetto Command nel mio controller graal:

class ProfileCommand{ 

int id 
String companyName 

static constraints = { 
    companyName blank: false 
    id nullable: false 
} 

@Override 
public String toString() { 
    return "ProfileCommand{id=$id, companyName='$companyName'}"; 
} 
} 

e il mio metodo di controllo della firma:

def update(ProfileCommand command) {...}

Come posso ottenere request.JSON dati nel mio oggetto di comando?

Finora, l'unico modo sono stato in grado di farlo è quello di creare l'oggetto di comando manualmente all'interno del metodo update(), passando request.JSON come argomento del costruttore:

def command = new ProfileCommand(request.JSON) 

    log.debug "Command object contents: $command" 

Quanto sopra di debug comando produce:

Command object contents: ProfileCommand{id=1, companyName='Blub Muckers'} 

che è esattamente ciò che voglio (Un grande grido-out per Oliver Tynes per la soluzione di cui sopra). Purtroppo, chiamando command.validate() dopo creo il comando produce la seguente eccezione:

Class org.codehaus.groovy.grails.web.taglib.exceptions.GrailsTagException 
Message Tag [validate] is missing required attribute [form] 

sto usando v2.0.3, URI hanno prodotto la stessa eccezione w/v2.0.4.

UPDATE Per Ian Roberts sulle graal mailing list, è necessario aggiungere il @Validateable annotazioni alla classe comando per ottenere validate() al lavoro. Grazie, Ian!

risposta

7

Non sono sicuro che ci sia qualcosa in termini di configurazione per eseguire il binding automatico dei dati dei parametri JSON; una cosa che potresti essere in grado di fare è scrivere un filtro per le tue azioni che richiedono l'input della richiesta JSON che rimappa sostanzialmente request.JSON direttamente sulla mappa dei parametri root, che in teoria dovrebbe consentire l'esecuzione automatica del binding dei dati.

qualcosa di simile:

class JSONParamMapFilters { 
    def filters = { 
    before = { 
     remapFilter(controller:'yourController', action:'update') { 
      request.JSON.each { k,v -> 
       params[k] = v 
      } 
     } 
    } 
    } 
} 

È quindi possibile estendere questo filtro tramite regex/convenzioni di denominazione per eventuali azioni di controllo applicabili.

+0

Questo funzionerebbe. La contrassegnerò come la risposta a meno che nessun altro abbia un altro suggerimento. Grazie, Aquatoad! –

+0

Felice di aiutare. Rimuoverò anche il bit corretto dall'annotazione @Validateable. – Aquatoad

+2

sostituisce params.k = v con params [k] = v - altrimenti non funzionerà ... –

4

Si dovrebbe usare parseRequest=true in UrlMappings.groovy. Per esempio.:

"/user/$id/$action?"(controller: "userProfile", parseRequest: true) { 
    constraints { 
     id matches: /^[0-9]+$/ 
    } 
} 

allora si può utilizzare JSON params variabile o si legano a un oggetto di comando in un metodo argomenti:

def index(MyCommand command){...}

Entrambi dovrebbero funzionare. Ma in alcuni casi perde alcune informazioni da json (vincolante per le mappe).

+2

Solo per FYI per lettori su grails 2.3, parseRequest ora non ha niente, devi gestire manualmente JSON. –