2012-05-31 6 views
12

Pregunta: ¿hay alguna manera de hacer un enlace de objeto de comando automático con datos request.JSON?Grails Objeto de comando: ¿Cómo cargar request.JSON en él?

Dado este objeto simple comando en mi controlador de griales:

class ProfileCommand{ 

int id 
String companyName 

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

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

y mi controlador de método de firma de:

def update(ProfileCommand command) {...}

¿Cómo puedo obtener request.JSON datos en mi objeto de comando?

Hasta ahora, la única manera que he sido capaz de hacerlo es crear el objeto de comando manualmente dentro del método update(), pasando request.JSON como el argumento del constructor:

def command = new ProfileCommand(request.JSON) 

    log.debug "Command object contents: $command" 

La depuración por encima de comando produce:

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

Que es exactamente lo que quiero (Un gran agradecimiento a Oliver Tynes por la solución anterior). Por desgracia, llamando command.validate() después de crear el comando produce la siguiente excepción:

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

estoy usando v2.0.3, URIs producen la misma excepción w/v2.0.4.

ACTUALIZACIÓN por Ian Roberts en los griales lista de correo, es necesario agregar la anotación @Validateable a la clase de comando para obtener validate() para trabajar. Gracias, Ian!

Respuesta

7

No estoy seguro de si hay algo de configuración para hacer el enlace automático de datos de parámetros JSON; Una cosa que podría hacer es escribir un filtro para sus acciones que tome la entrada de solicitud JSON que básicamente reasigna request.JSON directamente en el mapa de parámetros raíz, que en teoría debería permitir el enlace de datos automático.

algo como:

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

A continuación, puede ampliar este filtro a través de expresiones regulares/convenciones de nombres a cualquier acción del controlador aplicables.

+0

Esto funcionaría. Lo marcaré como la respuesta a menos que alguien más tenga otra sugerencia. Gracias, Aquatoad! –

+0

Me alegra ayudar. Eliminaré también el bit que está fijado por la anotación @Validateable. – Aquatoad

+2

reemplace params.k = v con params [k] = v - de lo contrario no funcionará ... –

4

Debe utilizar parseRequest=true en UrlMappings.groovy. P.ej.:

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

entonces puede usar params JSON variable o se unen a un objeto de comando en unos argumentos del método:

def index(MyCommand command){...}

Ambos deben trabajar. Pero en algunos casos pierde cierta información de json (vinculante para los mapas).

+2

Solo para sus lectores en grails 2.3, parseRequest ahora no hace falta nada, necesita manejar JSON manualmente. –

Cuestiones relacionadas