2011-02-25 10 views
5

Estoy tratando de llegar al cuerpo de un POST, y me gustaría que los parámetros de mi método se vinculen a un objeto.¿Usa @RequestBody y @ModelAttribute juntos?

¿Esto es posible?

Mi declaración actual no siempre recibe un golpe:

@RequestMapping(method = RequestMethod.POST) 
public void doStuff(@RequestBody byte[] bodyData, @ModelAttribute Form form, Model model) { 

Parece que me estoy haciendo esta excepción:

- 2011-02-25 16:57:30,354 - ERROR - http-8080-3 - org.springframework.web.portle 
t.DispatcherPortlet - Could not complete request 
java.lang.UnsupportedOperationException: @RequestBody not supported 
+0

¿Tiene sus anotaciones @Controller y @RequestMapping en su lugar? – GriffeyDog

+0

¿Es que estás tratando de obtener el cuerpo POST en la variable @RequestBody y los parámetros GET en la variable @ModelAttribute? –

+0

@three_cups_of_java: Sí. –

Respuesta

6

Para que esto funcione correctamente, usted tiene que estar seguro de que' re usando AnnotationMethodHandlerAdapter. Esto anula HandlerMethodInvoker'screateHttpInputMessage (que arroja la excepción que está viendo). (Esto se hace de una clase privada.)

Creo que sólo puede incluir lo siguiente en su * -servlet.xml

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/> 

ADVERTENCIA: La respuesta a continuación es para el caso de necesitar @RequestBody y @RequestParam en el mismo método de controlador. No responde a esta pregunta, pero podría ser útil para alguien.

He probado esto usando Spring 3.0.1. Esto es posible, pero es algo precario. DEBE tener su argumento de método @RequestBody antes de su argumento @RequestParam. Supongo que esto se debe a que HandlerMethodInvoker lee el cuerpo de la solicitud (junto con los parámetros GET) al recuperar parámetros (y el cuerpo de la solicitud solo se puede leer una vez).

He aquí un ejemplo (ADVERTENCIA: código que en Scala, así que no he compilado el código de Java)

@RequestMapping(value = "/test", method = RequestMethod.POST) 
public String test(
     @RequestBody String body, 
     @RequestParam("param1") String parma1, 
     Map<Object, Object> model: Map[AnyRef, AnyRef]) 
{ 
    model.put("test", test) 
    model.put("body", body) 

    return "Layout" 
} 

Una alternativa es utilizar @PathVariable. He confirmado que esto funciona.

+1

Al leer esto, noto que no agregué los puntos y comas. No voy a editar esto para mostrar cuánto me gusta no escribirlos en Scala :) –

+0

Apuesto a que no tengo esa definición en mi configuración. Voy a probar esto más tarde para confirmar. Estoy usando Groovy para una buena parte de mi código, así que también soy fan del no-punto y coma: P. No veo cómo podría funcionar en Scala y no en Java. –

1

Desafortunadamente eso es algo imposible. Si está utilizando la versión de portlet de Spring MVC (y parece de los registros), entonces podría estar interesado en this JIRA issue.

AnnotationMethodHandlerAdapter utiliza PortletHandlerMethodInvoker internamente y la segunda es una subclase interna de HandlerMethodInvoker - el lugar donde puede configurar HttpMessageConverter-s. Pero están configurados como nulos. Y la propiedad es final.

Que aún sería la de solucionar si se puede sustituir HandlerMethodInvoker, pero no se puede .. Es constructor-creado;)

Una cosa a notar es que la versión del servlet de Spring MVC es totalmente compatible con HttpMessageConverter-s y lo hace no sufrir este problema

Cuestiones relacionadas