一起使用@RequestBody和@ModelAttribute?

时间:2011-02-25 16:57:45

标签: java spring spring-mvc

我正试图找到POST的主体,我希望我的方法的参数绑定到一个对象。

这可能吗?

我目前的宣言不会受到影响:

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

看起来我得到了这个例外:

- 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

2 个答案:

答案 0 :(得分:6)

为了使其正常工作,您必须确保使用AnnotationMethodHandlerAdapter。这会覆盖HandlerMethodInvoker's createHttpInputMessage(这会抛出你看到的异常)。 (它在私人课堂上这样做。)

我相信您可以在* -servlet.xml中包含以下内容

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

警告:以下答案适用于在同一处理程序方法中需要@RequestBody和@RequestParam的情况。它没有回答这个问题,但可能对某人有用。

我使用Spring 3.0.1对此进行了测试。这是可能的,但它有点不稳定。你的@RequestParam参数之前必须有你的@RequestBody方法参数。我猜这是因为HandlerMethodInvoker在检索参数时读取请求体(以及GET参数)(并且请求体只能读取一次)。

这是一个例子(警告:我在Scala中编码,所以我没有编译这个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"
}

另一种方法是使用@PathVariable。我已经证实这是有效的。

答案 1 :(得分:1)

不幸的是,这有点不可能。如果你正在使用Spring MVC的portlet版本(它看起来像是从日志中看出来的话),那么你可能对this JIRA issue感兴趣。

AnnotationMethodHandlerAdapter在内部使用PortletHandlerMethodInvoker,第二个是HandlerMethodInvoker的内部子类 - 您可以在其中配置HttpMessageConverter-s的地方。但他们被设置为null。该物业是最终的。

如果你可以替换HandlerMethodInvoker,甚至可以解决这个问题,但你不能......它是构造函数创建的;)

需要注意的一点是,Spring MVC的Servlet版本完全支持HttpMessageConverter-s,并且不会遇到这个问题。