在springboot中,对HTTP GET请求,通常不会将请求体(body)作为主要的数据传输方式,因为GET请求通常用于请求数据,而不是发送数据到服务器(尽管从技术上讲,GET请求可以包含请求体,但这并不常见,也不符合RESTful API的设计原则)。因此,对于GET请求的入参,通常不会使用@RequestBody注解。
一、springboot控制器接收GET请求入参
@GetMapping("getParam")
public String getParam(@RequestParam(value = "name", required = false, defaultValue = "liming") String username) {
return username;
}
通常使用@RequestParam注解控制接收的入参;
二、springboot自动将GET请求入参转为实体类
@GetMapping("getParam1")
public String getParam1(@Validated Job job) {
return "";
}
springboot会自动的将GET请求入参转换为入参实体类对象,但是参数名必须和实体类中的属性字段一一对应;如果要对参数进行校验可以添加@Validated注解,在具体字段添加校验注解,如:@NotEmpty。
三、springboot的GET请求入参为请求体(body类型)
@GetMapping("getParam1")
public String getParam1(@Validated @RequestBody Job job) {
return "";
}
如果请求体为body类型,则接收的入参实体类对象前必须用@RequestBody标注,否则参数无法接收到。
四、问题思考
如果通过正常的GET请求如下两种方案都是可以正常获取请求入参,如何可以有一个比较友好的方案解决将两者获取的参数合并后数据重复的问题,目前暂时未想到比较好的方法,因为每种参数传递都有可能发生,容忍重复,而不是参数丢失。
- 通过HttpServletReqeust获取GET请求入参
Enumeration<String> names = request.getParameterNames();
while (names.hasMoreElements()) {
String key = names.nextElement();
if (!paramMap.containsKey(key)) {
paramMap.put(key, request.getParameter(key));
}
}
- 通过MethodInvocation获取方法参数
public static Map<String, Object> getMethodArgs(MethodInvocation invocation, String... field) {
Method method = invocation.getMethod();
Map<String, Object> paramMap = Maps.newHashMap();
List<String> list = ParamNameUtils.getParamNames(method);
Annotation[][] annotations = method.getParameterAnnotations();
Object[] obj = invocation.getArguments();
for (int i = 0; i < list.size(); i++) {
String name = list.get(i);
Object value = obj[i];
if (isFinal(value)) {
continue;
}
paramMap.put(name, value);
}
return paramMap;
return Collections.emptyMap();
}
开源 SDK:https://github.com/mingyang66/spring-parent