MVC官方文档:https://docs.spring.io/spring/docs/5.2.3.RELEASE/spring-framework-reference/web.html#mvc
张开涛《跟我学SpringMVC》:https://www.iteye.com/blog/jinnianshilongnian-1752171
本章演示代码:https://gitee.com/tysite-web/tysite-service/tree/master/src/main/java/org/tysite/tyservice/example/restful
说明
spring mvc 为我们提供了多种 controller
接收参数的注解,以下我整理下最常用的注解:
- @PathVariable :用于访问URI变量,即获取URI路径中的路径片段,默认必填。
- @RequestHeader :将请求标头绑定到控制器的方法参数,默认必填。
- @CookieValue :将 HTTP cookie 的值绑定到控制器中的方法参数,默认必填。
- @RequestParam :将HTTP请求的
查询参数
或表单数据 (form-data)
绑定到控制器的方法参数,默认必填。 - @ModelAttribute:注解在参数前,将HTTP请求中的
查询参数
和表单字段
与model
中的字段绑定 (model不存在时会实例化它);注解在方法上,该方法在所有的请求前执行。 - @RequestBody :从请求体中读取数据并反序列化成对象。
- HttpServletRequest :用户接收完整的
request
对象,多用于获取域名、端口等信息。
一. 环境准备
为了演示 spring mvc 参数接收注解的使用,我们需要准备 Postman
和 tysite-service
服务端项目。
1、Postman
这是一款非常流行的接口测试软件,我们可以通过其官网 https://www.postman.com/downloads/ 下载即可,它的windows版本安装相对简单,这里就不做赘述。
本文仅对Postman的基本使用做一个简单的说明,以便大家可以快速了解本文请求测试的内容。
- 请求方法:在 java web 项目中通常使用的请求方法包括
POST
、DELETE
、PUT
、GET
。 - 资源的URL地址:录入服务端接口的URL地址。
- 请求调用按钮:点击该按钮,触发请求调用事件。
- 参数设置区域:该区域可以模拟 查询参数、请求头、请求体、cookie 中的配置信息,以模拟实际请求。
- 响应结果区域:显示请求调用后服务端返回的结果信息。
下面简单演示通过查询参数
、请求头属性
、cookie
、请求体
进行传参的设置方法,如下所示:
查询参数设置方法
如下图所示,在Params
标签下设置的参数,会自动添加到 URL
的 query-string
位置,即对 接口的查询参数
赋值。
请求头设置方法
如下图所示,在Headers
标签下设置的属性值,会通过请求头进行提交,多用于验证秘钥等信息的传参。
cookie设置方法
如下图所示,点击右侧的Cookie Code
弹出 cookie 设置界面。
在该界面,须先设置domain name
, 即cookie所属的域名;然后再在domain name
下设置cookie
信息,注意cookie的格式。
请求体传参设置方法
Body
支持多种传参方式,本文将要用到form-data
、x-www-form-urlencoded
、raw
三种方式。
form-data
:以表单数据键值对通过请求体传参,编码类型为multipart/form-data
,支持上传文件。
x-www-form-urlencoded
:是 post
请求的默认格式,使用URLencode转码,会对非ASCII
字符进行编码。
raw
:以文本格式进行传参,这里推荐application/json
,因为 angular
和 vue
的默认请求调用都是此方式。
参数内容需要我们自行编辑JSON字符串,如下图所示:
2、tysite-service
前面的章节中,我们已经搭建了一个简单的tysite-service
项目,为了提高开发效率,我们需要使用IDE工具进行日常开发,这里使用作者最喜欢的 IntelliJ IDEA
,安装配置参考作者的博文《IDEA 安装详解及常用插件配置》。
下面将简单介绍 IDEA 导入 gradle
项目并自动加载依赖的过程。
- 打开
IDEA
,点击Import Project
按钮,在弹出界面选择项目中的主build.gradle
文件。
- 首次导入项目时,
IDEA
会根据gradle
的项目配置,自动加载依赖、导入配置信息等。
- 我们使用
JReble
的DEBUG
模式启动项目,点击Rebel Debug TysiteServiceApplication
按钮,该方式启动同时指出热加载和DEBUG,可以加快我们的开发效率。
二. 验证测试
这里我们以POST
请求为例,演示@PathVariable
、@RequestHeader
、@CookieValue
、@RequestParam
、BowDTO param
、@RequestBody BowDTO param
注解接收参数的语法。
码云下载地址:https://gitee.com/tysite-web/tysite-service
以下演示代码为 tysite-service
项目的 org.tysite.tyservice.example.controller.RestfulController.java
类
package org.tysite.tyservice.example.restful.controller;
import org.springframework.web.bind.annotation.*;
import org.tysite.tyservice.example.restful.dto.BowDTO;
import java.util.HashMap;
import java.util.Map;
/**
* spring mvc 参数接收演示代码
* @author tysite
* @date 2020/2/29 0029 16:21
*/
@RestController
@RequestMapping("/api/example/restful")
public class RestfulController {
@PostMapping("/{path}")
public Map demoReceiveParams(@PathVariable String path,
@RequestHeader(name = "secret-key", required = false) String key,
@CookieValue(name = "cookie", required = false) String cookie,
@RequestParam(value = "poundage", required = false) String[] poundage,
BowDTO param
) {
Map<String,Object> result = new HashMap<>(16);
result.put("path segments", path);
result.put("secret-key", key);
result.put("cookie", cookie);
result.put("request param", poundage);
result.put("body model", param);
return result;
}
@PostMapping("/request-body")
public Map demoRequestBody(@RequestBody BowDTO param) {
Map<String,Object> result = new HashMap<>(16);
result.put("model", param);
return result;
}
}
@RequestBody
与@RequestParam
、BowDTO param
用法不能同时使用,所以我按照这两中类型进行拆分演示代码。
所有注解接收参数都是默认必填的,如需非必填,可设置required
属性为false
。
1、演示 form-data 提交
/api/example/restful/{path}
演示 form-data 表单提交方式可以使用的参数接收注解。
从下图的调用结果可以发现:
@PathVariable 接收到 {path}
的内容 path-segments
。
@RequestHeader 接收到请求头中的属性secret-key
的值 8675E21E23E35989DDB624C68B1F264F
。
@CookieValue 接收到cookie的值cookie_attribute
。
@RequestParam 接收到 form-data
中的 poundage
的数组值 "20磅", "30磅"
。
BowDTO param 接收到 form-data
中的 DTO
数据。
图中的form-data
模块参数整理了Long
、String
、String[]
和 List<BowCategoryDTO>
类型的postman
传参写法,其将会经常应用在我们日常后端开发中。
注意:
GET
请求不支持 form-data
提交。
angular
在以form-data
提交时,须先构建form-data
对象。x-www-form-urlencoded
的请求参数接收与form-data
基本相同,区别在于x-www-form-urlencoded
对非ASCII
字符会进行转码。
2、演示 application/json 提交
/api/example/restful/request-body
演示 application/json 提交可以使用的参数接收注解。
@RequestBody BowDTO param 只能接收 application/json
媒体类型的 JSON
对象传参,如有特殊需要可以使用application/xml
等媒体类型。
注意:
@RequestParam
注解只能从查询参数
或者form-data
和x-www-form-urlencoded
参数绑定中接收到参数,application/json
媒体类型时无法接收到参数。- 前端框架
angular
、vue
默认请求调用方式即为application/json
,jquery
需要使用JSON.stringify()
语法将对象格式化为json字符串。
三. 推荐用法
根据以上演示代码的注解应用场景和作者多年的开发经验,给出如下使用建议:
- 新增操作采用
POST
请求、删除操作采用DELETE
请求、修改操作采用PUT
请求、查询操作采用GET
请求。 - 通常情况下新增、修改、查询操作,均建议采用
application/json
方式提交,通过@RequestBody
注解绑定属性到DTO
或ENTITY
对象实现接参。(angular / vue 前端操作相对简单
) - 新增或修改操作的对象含有文件附件时,参数传输必须采用
form-data
方式,通过绑定DTO
或ENTITY
对象属性实现接参。 - 查询或修改单个资源时,
资源ID
通过@PathVariable
从URL 路径片段中获取,一般id
放在资源名称之后(允许同时获取多个路径片段)。 - 查询操作,多于两个查询条件的,建议采用
application/json
方式提交,通过@RequestBody
注解绑定属性到DTO
或ENTITY
对象实现接参。 DTO
或ENTITY
的所有属性都必须设置spring validation
限制,在控制器读取请求参数时进行数据格式校验,以避免非法数据导致数据库操作异常。- 面对分页查询这种常用的请求规则,应当建立系统级的标准DTO接收参数,以实现代码复用。
- 两个系统间鉴权验证,推荐采用
@RequestHeader
注解通过请求头传递秘钥等验证信息。 - 获取诸如域名等服务器信息时,可以接收
HttpServletRequest
对象获取所需信息。