前言
日常使用SpringBoot进行开发接口时,我们看到SpringBoot给我们提供了常用的四种RequestMapping: 1.@GetMapping 2.@PostMapping 3.@PutMapping 4.@DeleteMapping 它们分别对应四种基本操作:GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE 用来删除资源。 那么在我们进行接口开发的过程中,如何在不同的请求方式中获取Http请求传递的参数呢,相信大家并不陌生,但是了解的也不太全面,在这里我决定总结一下常用的接收请求参数的标准用法。下面我以最常用的POST、GET 请求举栗子🌰🌰,文章末尾有项目地址及postman导出的请求文件 。
??无注解 ??
无注解的参数接收方式,只能通过变量的标识和http参数中的key对应来寻找映射,并且不能指定校验规则等,前端爱传不传,不传就拉倒😌😌
@RestController
@RequestMapping("/noAnno")
public class NoAnnoController {
@GetMapping("/url")
public String getMapping(String msg){
return msg;
}
@GetMapping("/body")
public String getMapping(BodyParam param){
return param.toString();
}
@PostMapping("/post")
public String postMapping(String msg){
return msg;
}
@PostMapping("/post-body")
public String postMapping(BodyParam msg){
return msg.toString();
}
}
我们可以通过代码注释看出,前三种不出所料,第四种,post通过无注解的形式是无法接收body中携带的参数。
??@PathVariable??
带占位符的 URL 是 Spring3.0 新增的功能 通过 @PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中:URL 中的 {xxx} 占位符可以通过@PathVariable(“xxx“) 绑定到操作方法的入参中。下面我们来举个栗子🌰
@RestController
@RequestMapping("/path")
public class PathVariableController {
@GetMapping("/{msg}/middle/{msg2}")
public String getMapping(@PathVariable(value = "msg") String message,
@PathVariable(value = "msg2",required = false)String msg2){
return message+ msg2;
}
@GetMapping(value ={"/require/","/require/{id}"})
public String getMapping(@PathVariable(value = "id",required = false) String message){
return message;
}
}
注意这里如果少传一个参数,是会报错的,目测这个require=false没有什么用,那这种情况怎么办呢?我们看第二种写法,通过两个mapping,加上require=false的设置保证了不传参数也能正常访问接口,接口可以执行正常的逻辑,并且返回成功状态??????
??@RequestParam??
@RequestParam用于接收get请求url中的参数,其规则简单总结一下: (1)@RequestParam可以指定接收参数名称。例如@RequestParam(“userId”)String uId (2)@RequestParam写法参数为必传,可以通过require属性进行设置 (3)@RequestParam可以通过@RequestParam(defaultValue = “0”)指定参数默认值 (5)如果接口需要被RPC调用,则不能省略@RequestParam,否则RPC会找不到参数报错 下面我们来举例子🌰
@RestController
@RequestMapping("/requestParam")
public class RequestParamController {
@GetMapping("/url-require-true")
public String getMapping(@RequestParam(value = "message" ,required = false,defaultValue = "i am default value") String msg){
return msg;
}
}
这里没有传入参数,已经设置了require=false,因此不校验参数非空,并且设置了defaultValue,结果如上图。
??@RequestBody??
@RequestBody一般被用来接收http请求中body中的内容,最常用的咱们一般用json传输数据,将数据放置于body中。它会更加json的key值和接收参数对象的key值做映射,通过set方法进行设置。
@RestController
@RequestMapping("/requestBody")
public class RequestBodyController {
@PostMapping("/body")
public String getMapping(@RequestBody BodyParam param){
return param.toString();
}
}
接口报错400,真的是接口没有找到么,我们来看下后端日志,事实并不是这样子的,
Resolved [org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public
java.lang.String com.scott.paramrecieve.controller.RequestBodyController.getMapping(com.scott.paramrecieve.dto.BodyParam)]
代码提示我们Required request body is missing ,很显然,加上注解后body就不能是空了,我们看下注解的源码。这里已经说的很清楚了,require默认是true。
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestBody {
boolean required() default true;
}
我们通过body传入String、int、数组,返回结果,一切正常。
??@RequestHeader??
同样很直观,用于从header中获取数据
@RestController
@RequestMapping("/requestHeader")
public class RequestHeaderController {
@PostMapping("/header")
public String getMapping(@RequestHeader("param")String param){
return param;
}
}
我们通过header进行参数传递,同样它可以设置是否必传,默认值等,请大家自行翻阅源码,就不一一罗列了。
??HttpServletRequest??
这是直接拿到request对象,可以从对象中灵活的获取参数,下面我们简单的罗列集中方式:
@RestController
@RequestMapping("/hsr")
public class HttpServletRequestController {
@GetMapping("/getUrlValue")
public String getUrlValue(HttpServletRequest request) {
String msg = request.getParameter("msg");
return msg;
}
@GetMapping("/getUrlValues")
public String getHttpServletRequestValue(HttpServletRequest request) {
Map<String, String[]> parameterMap = request.getParameterMap();
String[] msgs = parameterMap.get("msg");
List<String> strings = Arrays.asList(msgs);
return strings.toString();
}
@PostMapping("/getHttpServletRequest")
public String getHttpServletRequest(HttpServletRequest request) throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(request.getInputStream()));
String line = "";
String body = "";
while ((line = reader.readLine()) != null) {
body += line;
}
return body;
}
}
验证一下请求结果,如果通过这种方式取参数的话,只能通过硬编码的方式来限制必填、默认值等,第三种方式我们可以看到获取到的实际上是字符串,我们还需要通过json来进行转换。
git仓库地址:https://gitee.com/ErGouGeSiBaKe/springboot-param-recieve postman文件已提交至工程中。
|