SpringBoot接收参数所有方式总结
作者:鞋尖的灰尘
方法形参接收参数【不推荐】
- 此场景适用于请求参数比较少的情况
- Springboot3.2会异常报错:
Name for argument of type [java.lang.String] not specified, and parameter name information not available via reflection. Ensure that the compiler uses the '-parameters' flag.
- 解决方案
@RequestMapping("/test1") public String test1(String name,String age) { return String.format("name:%s,age:%s", name, age); }
以实体类接受参数 【不推荐】
- 此场景适用于请求参数比较多的情况
@Getter @Setter public static class DTO { private String name; private Integer age; } @RequestMapping("/test2") public String test2(DTO request) { return String.format("name:%s,age:%s", request.getName(), request.getAge()); }
以形参和实体类接受参数 【不推荐】
- Springboot3.2会异常报错:
Name for argument of type [java.lang.String] not specified, and parameter name information not available via reflection. Ensure that the compiler uses the '-parameters' flag.
- 解决方案
@RequestMapping("/test3") public String test3(DTO requestDto,String sex) { return String.format("name:%s,age:%s,sex:%s", requestDto.getName(), requestDto.getAge(),sex); }
上述三种接受参数的方式,只能用来获取query-params,form-data,x-www-form-urlencoded格式数据
@PathVariable注解
@PathVariable
注解可用于处理请求 URI 映射中的模板变量,并将其绑定到 Controller 方法参数
- 使用
@PathVariable
注解来提取 URI 的模板部分,该部分由变量{name}
表示
@RequestMapping("/test4/{name}/{age}") public String test4(@PathVariable("name") String name,@PathVariable("age") Integer age) { return String.format("name:%s,age:%s", name, age); }
指定路径变量名
由于方法参数和路径变量的名称相同,可以不用主动设置模板路径变量的名称。如果路径变量名不同,可以在
@PathVariable
注解的参数中指定
@GetMapping("/test5/{name}") public String test4(@PathVariable("name") String id) { return String.format("name:%s",id); }
- 单个请求中的多个路径变量
@GetMapping("/test5/{name}/{id}") public String test5(@PathVariable(value = "name") String name,@PathVariable(value = "id") String id) { return String.format("name:%s id:%s", name, id); }
java.util.Map<String, String>
类型的方法参数来处理多个 `@PathVariable 参数 [不推荐]
@GetMapping("/test5/{name}/{id}") public String test6(@PathVariable Map<String,String> request) { return JSON.toJSONString(request); }
- 可选择的路径变量
@RequestMapping(value = {"/test6","test6/{name}/{age}"}) public String test6(@PathVariable("name") String name,@PathVariable("age") Integer age) { return String.format("name:%s,age:%s", name, age); }
咋一看,上述 Controller 应该可以处理 /test6
和 /test6/smile/32
请求。但是,由于 @PathVariables
所注解的方法参数默认为必选参数,因此它无法处理 /api/employeeswithrequired
请求
有三种不同的方法来处理这个问题
设置required为false
@RequestMapping(value = {"/test6","test6/{name}/{age}"}) public String test6(@PathVariable(value = "name",required = false) String name,@PathVariable(value = "age",required = false) Integer age) { return String.format("name:%s,age:%s", name, age); }
使用 java.util.Optional
@RequestMapping(value = {"/test7","test7/{name}/{age}"}) public String test7(@PathVariable Optional<String> name,@PathVariable Optional<String> age) { return String.format("name:%s,age:%s", name.orElse("null"), age.orElse("null")); }
使用 Map<String, String> 类型的方法参数 [不推荐]
@RequestMapping(value = {"/test8","test8/{name}/{age}"}) public String test8(@PathVariable Map<String,String> request) { return String.format("name:%s,age:%s", request.get("name"), request.get("age")); }
@RequestParam
可以使用 @RequestParam
从请求中提取查询参数、表单参数甚至是多个参数
指定请求参数名称
如果变量名称和参数名称不同,可以使用
name
属性配置@RequestParam
名称:
@RequestMapping("/test9") public String test9(@RequestParam("name") String name,@RequestParam("age") Integer age) { return String.format("name:%s,age:%s", name, age); }
也可以使用 @RequestParam(value = "name")
或直接使用 @RequestParam("name")
可选的请求参数
使用
@RequestParam
注解的方法参数默认为必填参数。这意味着,如果请求中没有该参数,就会返回 400 错误- 可以使用
required
属性将@RequestParam
配置为可选参数:
- 可以使用
@RequestMapping("/test10") public String test10(@RequestParam(value = "name",required = false) String name,@RequestParam(value = "age",required = false) Integer age) { return String.format("name:%s,age:%s", name, age); }
如果没有指定参数,方法参数将绑定为 null
使用 Java 8 Optional
@RequestMapping("/test11") public String test11(@RequestParam(value = "name") Optional<String> name,@RequestParam(value = "age") Optional<Integer> age) { return String.format("name:%s,age:%s", name.orElse(null), age.orElse(null)); }
在这种情况下,不需要指定
required
属性。如果没有提供请求参数,则使用默认值:
请求参数的默认值
还可以使用 defaultValue
属性为 @RequestParam
设置默认值
@RequestMapping("/test12") public String test12(@RequestParam(value = "name",defaultValue = "smile") Optional<String> name,@RequestParam(value = "age") Optional<Integer> age) { return String.format("name:%s,age:%s", name.orElse(null), age.orElse(null)); }
与 required=false
类似,用户不再需要提供参数:
注意,当设置 defaultValue
属性时,required
会被被设置为 false
映射所有参数
还可以使用 Map
来封装多个参数,而无需定义它们的名称(name
)或数量:
@RequestMapping("/test13") public String test13(@RequestParam Map<String,String> request) { return String.format("name:%s,age:%s", request.get("name"), request.get("age")); }
多值参数(列表/数组)
一个 @RequestParam
可以有多个值:
@RequestMapping("/test14") public String test14(@RequestParam("id") List<String> idList) { return String.format(JSON.toJSONString(idList)); }
@RequestBody
将HttpRequest主体映射到方法上实体属性中
以字符串的方式接收 body 的数据
@PostMapping("/test15") public String test15(@RequestBody String requestString) { return requestString; }
以Map的方式接收body 的数据
@RequestMapping("/test16") public String test16(@RequestBody Map<String,Object> requestMap) { return String.format(JSON.toJSONString(requestMap)); }
以实体类的方式接收body 的数据 【最常用】
@RequestMapping("/test17") public String test17(@RequestBody DTO requestDto) { return String.format(JSON.toJSONString(requestDto)); }
当body中没有任何数据传递时,会抛出异常:Resolved [org.springframework.http.converter.HttpMessageNotReadableException: Required request body is missing: public java.lang.String com.fs.smile.home.controller.RequestController.test16(java.util.Map<java.lang.String, java.lang.Object>)]
这种情况,应该如何解决
可以使用 required
属性将 @RequestBody
配置为可选参数
@RequestMapping("/test17") public String test17(@RequestBody DTO requestDto) { return String.format(JSON.toJSONString(requestDto)); }
使用 Java 8 Optional
在这种情况下,不需要指定 required
属性
@RequestMapping("/test18") public String test18(@RequestBody Optional<Map<String,Object> > requestMap) { return String.format(JSON.toJSONString(requestMap.orElse(null))); }
@RequestBody接收数据的格式要求
- Content-Type: application/json
- Content-Type: application/xml
- Content-Type: text/plain
- Content-Type: application/octet-stream
根据不同的Content-Type等情况,Spring-MVC会采取不同的HttpMessageConverter实现来进行信息转换解析。@RequestBody不能用来处理application/x-www-form-urlencoded
或 multipart/form-data
格式的请求数据,如果尝试使用 @RequestBody
来处理这类请求,通常会遇到 415 Unsupported Media Type 异常。要处理这两种格式的数据,应该使用 @RequestParam
或 @ModelAttribute
注解
@RequestHeader
RequestHeader主要用来获取请求当中的请求头
- 获取单个header属性
@RequestMapping("/test20") public String test20(@RequestHeader("name") String name,@RequestHeader("age") Integer age) { return String.format("name:%s,age:%s", name, age); }
当header中不存在该参数时,系统会抛出400的异常,可以参考@PathVariable的处理方案
获取所有header属性
@RequestMapping("/test21") public String test21(@RequestHeader Map<String,String> headers) { return String.format("name:%s,age:%s", headers.get("name"), headers.get("age")); }
获取header对象
@RequestMapping("/test22") public String test22(@RequestHeader HttpHeaders headers) { return String.format("name:%s,age:%s", headers.get("name"), headers.get("age")); }
以上就是SpringBoot接受参数所有方式总结的详细内容,更多关于SpringBoot接受参数的资料请关注脚本之家其它相关文章!