@RequestParam、@RequestBody和@ModelAttribute区别

2019/04/25 14:22
阅读数 94

<div id="cnblogs_post_body" class="blogpost-body"><p>一、@RequestParam<br>GET和POST请求传的参数会自动转换赋值到@RequestParam 所注解的变量上<br>1. @RequestParam(org.springframework.web.bind.annotation.RequestParam)用于将指定的请求参数赋值给方法中的形参。<br>例:<br>(1) get请求:</p> <p>url请求:<a href="http://localhost:8080/WxProgram/findAllBookByTag?tagId=1&amp;pageIndex=3" target="_blank">http://localhost:8080/WxProgram/findAllBookByTag?tagId=1&amp;pageIndex=3</a></p> <p>userTest.jsp</p> <div class="cnblogs_code"> <pre>&lt;form action="/WxProgram/json/requestParamTest" method="get"&gt;<span style="color: #000000;"> requestParam Test</span>&lt;br&gt;<span style="color: #000000;"> 用户名:</span>&lt;input type="text" <span style="color: #ff0000;">name="username"</span>&gt;&lt;br&gt;<span style="color: #000000;"> 用户昵称:</span>&lt;input type="text" <span style="color: #ff0000;">name="usernick"</span>&gt;&lt;br&gt; &lt;input type="submit" value="提交"&gt; &lt;/form&gt;</pre> </div> <p>UserController.java</p> <div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="//common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div> <pre> @RequestMapping(value="/requestParamTest", method =<span style="color: #000000;"> RequestMethod.GET) </span><span style="color: #0000ff;">public</span> String requestParamTest(<span style="color: #ff0000;">@RequestParam(value="username") String userName, @RequestParam(value="usernick"</span><span style="color: #000000;"><span style="color: #ff0000;">) String userNick</span>){ System.out.println(</span>"requestParam Test"<span style="color: #000000;">); System.out.println(</span>"username: " +<span style="color: #000000;"> userName); System.out.println(</span>"usernick: " +<span style="color: #000000;"> userNick); </span><span style="color: #0000ff;">return</span> "hello"<span style="color: #000000;">; }</span></pre> <div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="//common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div></div> <p>上述代码会将请求中的username参数的值赋给username变量。</p> <p>等价于:</p> <div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="//common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div> <pre> @RequestMapping(value="/requestParamTest", method =<span style="color: #000000;"> RequestMethod.GET) </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> String requestParamTest(String username, <span style="color: #ff0000;">HttpServletRequest request</span>){ System.out.println(</span>"requestParam Test"<span style="color: #000000;">); System.out.println(</span>"username: " +<span style="color: #000000;"> username); String usernick </span>= <span style="color: #ff0000;">request.getParameter("usernick"</span><span style="color: #000000;"><span style="color: #ff0000;">);</span> System.out.println(</span>"usernick: " +<span style="color: #000000;"> usernick); </span><span style="color: #0000ff;">return</span> "hello"<span style="color: #000000;">; }</span></pre> <div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="//common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div></div> <p>也可以不使用@RequestParam,直接接收,此时要求controller方法中的参数名称要跟form中name名称一致</p> <div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="//common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div> <pre> @RequestMapping(value="/requestParamTest", method =<span style="color: #000000;"> RequestMethod.GET) </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> String requestParamTest(<span style="color: #ff0000;">String username, String usernick</span>){ System.out.println(</span>"requestParam Test"<span style="color: #000000;">); System.out.println(</span>"username: " +<span style="color: #000000;"> username); System.out.println(</span>"usernick: " +<span style="color: #000000;"> usernick); </span><span style="color: #0000ff;">return</span> "hello"<span style="color: #000000;">; }</span></pre> <div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="//common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div></div> <p>总结:</p> <p>接收请求参数的方式:</p> <div class="cnblogs_code"> <pre>@RequestParam(value="username") String userName, @RequestParam(value="usernick") String userNick <span style="color: #008000;">//</span><span style="color: #008000;">value中的参数名称要跟name中参数名称一致</span> String username, String usernick<span style="color: #008000;">//</span><span style="color: #008000;"> 此时要参数名称一致</span> HttpServletRequest request <span style="color: #008000;">//</span><span style="color: #008000;">request.getParameter("usernick")</span></pre> </div> <p>(2) post请求:<br>跟get请求格式一样,只是把方法中的get换成post</p> <p>@RequestParam<br>用来处理Content-Type: 为 application/x-www-form-urlencoded编码的内容。提交方式为get或post。(Http协议中,如果不指定Content-Type,则默认传递的参数就是application/x-www-form-urlencoded类型)</p> <p>RequestParam实质是将Request.getParameter() 中的Key-Value参数Map利用Spring的转化机制ConversionService配置,转化成参数接收对象或字段。</p> <p>get方式中query String的值,和post方式中body data的值都会被Servlet接受到并转化到Request.getParameter()参数集中,所以@RequestParam可以获取的到。</p> <p>二. @RequestBody</p> <p>@RequestBody注解可以接收<span style="color: #ff0000;">json格式的数据</span>,并将其转换成对应的数据类型。</p> <p>1. @RequestBody接收一个对象<br>url请求:<a href="http://localhost:8080/WxProgram/findBookByName" target="_blank">http://localhost:8080/WxProgram/findBookByName</a></p> <div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="//common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div> <pre>@RequestMapping(value="/findBookByName", method = RequestMethod.<span style="color: #ff0000;">POST</span><span style="color: #000000;">) @ResponseBody </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> DbBook findBookByName(<span style="color: #ff0000;">@RequestBody DbBook book</span>){ System.out.println(</span>"book: " +<span style="color: #000000;"> book.toString()); System.out.println(</span>"book name: " +<span style="color: #000000;"> book.getTitle()); String bookName </span>=<span style="color: #000000;"> book.getTitle(); DbBook book </span>=<span style="color: #000000;"> wxService.findBookByName(bookName); </span><span style="color: #0000ff;">return</span><span style="color: #000000;"> book; }</span></pre> <div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="//common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div></div> <p>2. @RequestBody接收不同的字符串</p> <p>(1)前台界面,这里以小程序为例</p> <div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="//common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div> <pre><span style="color: #000000;">wx.request({ url: host.host </span>+ `/WxProgram/<span style="color: #000000;">deleteBookById`, method: </span>'POST'<span style="color: #000000;">, data: { <span style="color: #ff0000;"> nick</span>: </span><span style="color: #0000ff;">this</span><span style="color: #000000;">.data.userInfo.nickName, <span style="color: #ff0000;">bookIds</span>: bookIds }, success: (res) </span>=&gt;<span style="color: #000000;"> { console.log(res); </span><span style="color: #0000ff;">this</span><span style="color: #000000;">.getCollectionListFn(); }, fail: (err) </span>=&gt;<span style="color: #000000;"> { console.log(err); } })</span></pre> <div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="//common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div></div> <p>(2)controller</p> <div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="//common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div> <pre>@RequestMapping(value="/deleteBookById",method=<span style="color: #000000;">RequestMethod.POST) @ResponseBody </span><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">void</span> deleteBookById(<span style="color: #ff0000;">@RequestBody Map&lt;String, String&gt;</span><span style="color: #000000;"><span style="color: #ff0000;"> map</span>){ String bookIds </span>= <span style="color: #ff0000;">map.get("bookIds"</span><span style="color: #000000;"><span style="color: #ff0000;">)</span>; String nick </span>= <span style="color: #ff0000;">map.get("nick"</span><span style="color: #000000;"><span style="color: #ff0000;">)</span>; String[] idArray </span>= bookIds.split(","<span style="color: #000000;">); Integer userId </span>=<span style="color: #000000;"> wxService.findIdByNick(nick); </span><span style="color: #0000ff;">for</span><span style="color: #000000;">(String id : idArray){ Integer bookid </span>=<span style="color: #000000;"> Integer.parseInt(id); System.out.println(</span>"bookid: " +<span style="color: #000000;"> bookid); wxService.removeBookById(bookid, userId); } }</span></pre> <div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="//common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div></div> <p>@RequestBody<br>处理HttpEntity传递过来的数据,一般用来处理非Content-Type: application/x-www-form-urlencoded编码格式的数据。</p> <p>GET请求中,因为没有HttpEntity,所以@RequestBody并不适用。<br>POST请求中,通过HttpEntity传递的参数,必须要在请求头中声明数据的类型Content-Type,SpringMVC通过使用HandlerAdapter 配置的HttpMessageConverters来解析HttpEntity中的数据,然后绑定到相应的bean上。</p> <p>@RequestBody用于post请求,不能用于get请求</p> <p>这里涉及到使用@RequestBody接收不同的对象<br>1. 创建一个新的entity,将两个entity都进去。这是最简单的,但是不够“优雅”。<br>2. 用Map&lt;String, Object&gt;接受request body,自己反序列化到各个entity中。<br>3. 类似方法2,不过更为generic,实现自己的HandlerMethodArgumentResolver。参考<a href="https://sdqali.in/blog/2016/01/29/using-custom-arguments-in-spring-mvc-controllers/" target="_blank">这里&nbsp;</a></p> <p>三、@ModelAttribute</p> <p>@ModelAttribute注解类型将参数绑定到Model对象</p> <p>1. userTest.jsp</p> <div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="//common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div> <pre>&lt;form action="/WxProgram/json/modelAttributeTest" method="post"&gt;<span style="color: #000000;"> modelAttribute Test</span>&lt;br&gt;<span style="color: #000000;"> 用户id:</span>&lt;input type="text" name="userId"&gt;&lt;br&gt;<span style="color: #000000;"> 用户名:</span>&lt;input type="text" name="userName"&gt;&lt;br&gt;<span style="color: #000000;"> 用户密码:</span>&lt;input type="password" name="userPwd"&gt;&lt;br&gt; &lt;input type="submit" value="提交"&gt;&lt;br&gt; &lt;/form&gt;</pre> <div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="//common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div></div> <p>name的属性值要跟User的属性相对应。</p> <p>2. UserController.java</p> <div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="//common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div> <pre>@RequestMapping(value="/modelAttributeTest", method =<span style="color: #000000;"> RequestMethod.POST) </span><span style="color: #0000ff;">public</span><span style="color: #000000;"> String modelAttributeTest(<span style="color: #ff0000;">@ModelAttribute User user</span>){ System.out.println(</span>"modelAttribute Test"<span style="color: #000000;">); System.out.println(</span>"userid: " +<span style="color: #000000;"> user.getUserId()); System.out.println(</span>"username: " +<span style="color: #000000;"> user.getUserName()); System.out.println(</span>"userpwd: " +<span style="color: #000000;"> user.getUserPwd()); </span><span style="color: #0000ff;">return</span> "hello"<span style="color: #000000;">; }</span></pre> <div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="//common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div></div> <p>3. User.java</p> <div class="cnblogs_code"><div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="//common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div> <pre><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">class</span><span style="color: #000000;"> User { </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> Integer userId; </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> String userName; </span><span style="color: #0000ff;">private</span><span style="color: #000000;"> String userPwd;

</span><span style="color: #0000ff;">public</span><span style="color: #000000;"> User(){
    </span><span style="color: #0000ff;">super</span><span style="color: #000000;">();
}
    </span><span style="color: #008000;">//</span><span style="color: #008000;">setter and getter      </span>

}</pre>

<div class="cnblogs_code_toolbar"><span class="cnblogs_code_copy"><a href="javascript:void(0);" onclick="copyCnblogsCode(this)" title="复制代码"><img src="//common.cnblogs.com/images/copycode.gif" alt="复制代码"></a></span></div></div> <p>&nbsp;</p> <p>当前台界面使用GET或POST方式提交数据时,数据编码格式由请求头的ContentType指定。分为以下几种情况:<br>1. application/x-www-form-urlencoded,这种情况的数据@RequestParam、@ModelAttribute可以处理,@RequestBody也可以处理。<br>2. multipart/form-data,@RequestBody不能处理这种格式的数据。(form表单里面有文件上传时,必须要指定enctype属性值为multipart/form-data,意思是以二进制流的形式传输文件。)<br>3. application/json、application/xml等格式的数据,必须使用@RequestBody来处理。</p> <p>参考:</p> <p><a href="https://blog.csdn.net/xinluke/article/details/52710706" target="_blank">@RequestBody和@RequestParam区别&nbsp;</a></p> <p><a href="https://segmentfault.com/q/1010000009017635" target="_blank">https://segmentfault.com/q/1010000009017635</a></p></div>

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部