@RequestBody 或 @ModelAttribute 与 Spring+REST Web 服务

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13229584/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 05:29:36  来源:igfitidea点击:

@RequestBody or @ModelAttribute with Spring+REST web services

springrestspring-mvc

提问by Arun Kumar

I am creating a Restful website and Web services for iPhone and android apps with Spring 3.1. In my application, i am using Spring Message Convertors (org.springframework.http.converter.json.MappingHymansonHttpMessageConverter) to converting JSON into Java object and vice-versa.

我正在使用Spring 3.1为 iPhone 和 android 应用程序创建一个 Restful 网站和 Web 服务。在我的应用程序中,我使用 Spring Message Converters ( org.springframework.http.converter.json.MappingHymansonHttpMessageConverter) 将 JSON 转换为 Java 对象,反之亦然。

My objective is that there should be only single controller method(same URL) that should be used by JSP page, Iphone/Andois app.

我的目标是 JSP 页面、Iphone/Andois 应用程序应该只使用单个控制器方法(相同的 URL)。

I am using Spring form tagfor object binding from JSP to controller with the help of @ModelAttributelike below.

我在下面的帮助下使用Spring 表单标记将对象从 JSP 绑定到控制器@ModelAttribute

@RequestMapping(value = "reset-password", method = RequestMethod.POST)
public ModelAndView resetPassword(@ModelAttributeForgot forgotPassword,
     HttpServletRequest request) { 

     System.out.println("data recived=="+forgotPassword.getNewPassword());
 }

But the same is NOT working in the case if the data is being posted from iPhone/Android app and the result is:

但是,如果数据是从 iPhone/Android 应用程序发布并且结果是:

data recived==null;

数据接收==空;

So to overcome this problem i have used @RequestBodyannotation at place of @ModelAttribute.

所以为了克服这个问题,我@RequestBody@ModelAttribute.

So my controller looks like below:

所以我的控制器如下所示:

@RequestMapping(value = "reset-password", method = RequestMethod.POST)
public ModelAndView resetPassword(@RequestBody Forgot forgotPassword,
    HttpServletRequest request) { 

    System.out.println("data recived=="+forgotPassword.getNewPassword());
}

It works then and the result i got is:

然后它起作用了,我得到的结果是:

data recived==somedata;

收到的数据==一些数据;

But @RequestBody then doesn't work with spring form on JSP page and the data doesn't get converted into object and i got nullvalues.

但是@RequestBody 然后不适用于 JSP 页面上的 spring 表单,并且数据不会转换为对象,并且我得到了null值。

  1. Can't i use @RequestBodyannotation to post data in form of JSON with spring form tag from JSP page??
  2. Is there any way by using which i can post data from my JSP form as well as from I phone App by using only a single controller method(either @ModelAttribute or @RequestBody).
  1. 我不能使用@RequestBody注解从 JSP 页面以带有 spring 表单标签的 JSON 形式发布数据吗??
  2. 有什么方法可以通过使用它来从我的 JSP 表单以及我的手机应用程序中发布数据,只使用一个控制器方法(@ModelAttribute 或 @RequestBody)。

EDIT:

编辑:

While writing Stringin place of Bean class, i am able to get the content in form of plain text, as below:

String在代替 Bean 类编写时,我能够以纯文本形式获取内容,如下所示:

@RequestMapping(value = "reset-password", method = RequestMethod.POST)
public ModelAndView resetPassword(@RequestBody String string,
     HttpServletRequest request) { }

Result from web page call:

网页调用结果:

uid=11&confirmPassword=somepassword&newPassword=somepassword

uid=11&confirmPassword=somepassword&newPassword=somepassword

Result from iPhone using web service call(in **JSON)**

iPhone 使用网络服务调用的结果(在 **JSON 中)**

{"newPassword":"somepassword","confirmPassword":"somepassword","uid":"11"}

But problem is that using this approach i have to parse the JSON string into Java object manually. And in web page content i have to find the values manually that i don't want.

但问题是使用这种方法我必须手动将 JSON 字符串解析为 Java 对象。在网页内容中,我必须手动找到我不想要的值。

Please help.

请帮忙。

Regards,

问候,

Arun Kumar

阿伦·库马尔

回答by Kevin Schmidt

Sorry, but I don't believe there is a way, because @ModelAttribute is bound from form post parameters and @RequestBody passes the body straight to the Json converter. You could replace the spring form tag with a simple json post, but that is probably less convenient than having two @RequestMapping methods.

对不起,但我不相信有办法,因为 @ModelAttribute 是从表单发布参数绑定的,@RequestBody 将主体直接传递给 Json 转换器。您可以用一个简单的 json 帖子替换 spring 表单标签,但这可能不如拥有两个 @RequestMapping 方法方便。

回答by user1157934

Its @RequestBody. I feel its better to specify the mime type that you are expecting and producing as output using @RequestMapping as,

它的@RequestBody。我觉得最好使用 @RequestMapping 作为输出指定您期望和生成的 mime 类型,

  @RequestMapping(value="/authenticate",produces="application/json",   
consumes="application/json",method=RequestMethod.POST)

Then register appropriate message converters with AnnotationMethodHandlerAdapter

然后使用AnnotationMethodHandlerAdapter注册适当的消息转换器

This message converter is responsible for Marshalling & unmarshalling of your request & response entity based on produces & consumes attributes.

此消息转换器负责根据生产和消费属性对您的请求和响应实体进行编组和解组。

<bean
    class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" >
     <property name="order" value="1" />
         <property name="messageConverters">
         <list>
            <bean class="org.springframework.http.converter.json.MappingHymansonHttpMessageConverter" >

                 <property name="supportedMediaTypes" value="application/json"/>
            </bean>
            <bean class = "org.springframework.http.converter.StringHttpMessageConverter">
                <property name="supportedMediaTypes" value = "text/plain;charset=UTF-8" />
            </bean>
         </list>
    </property>
</bean>