• Springboot之请求参数接收方式详解


    前言

    日常使用SpringBoot进行开发接口时,我们看到SpringBoot给我们提供了常用的四种RequestMapping:
    1.@GetMapping
    2.@PostMapping
    3.@PutMapping
    4.@DeleteMapping
    它们分别对应四种基本操作:GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE 用来删除资源。
    那么在我们进行接口开发的过程中,如何在不同的请求方式中获取Http请求传递的参数呢,相信大家并不陌生,但是了解的也不太全面,在这里我决定总结一下常用的接收请求参数的标准用法。下面我以最常用的POSTGET 请求举栗子🌰🌰,文章末尾有项目地址及postman导出的请求文件

    ⭐️无注解 ⭐️

    无注解的参数接收方式,只能通过变量的标识和http参数中的key对应来寻找映射,并且不能指定校验规则等,前端爱传不传,不传就拉倒😌😌

    @RestController
    @RequestMapping("/noAnno")
    public class NoAnnoController {
    
    	// 这里我们通过url传递参数	
        @GetMapping("/url")
        public String getMapping(String msg){
            return msg;
        }
    	// 这里的get请求 用对象接收参数,这里可以通过url传递也可以通过body进行传递
        @GetMapping("/body")
        public String getMapping(BodyParam param){
            return param.toString();
        }
    	// 这里是post请求,仅能接收url中携带的参数,
        @PostMapping("/post")
        public String postMapping(String msg){
            return msg;
        }
        // 这里是post请求,无法接收body中传入的参数 
        @PostMapping("/post-body")
        public String postMapping(BodyParam msg){
            return msg.toString();
        }
        
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    我们可以通过代码注释看出,前三种不出所料,第四种,post通过无注解的形式是无法接收body中携带的参数。
    在这里插入图片描述

    ⭐️@PathVariable⭐️

    带占位符的 URL 是 Spring3.0 新增的功能
    通过 @PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中:URL 中的 {xxx} 占位符可以通过@PathVariable(“xxx“) 绑定到操作方法的入参中。下面我们来举个栗子🌰

    @RestController
    @RequestMapping("/path")
    public class PathVariableController {
    	// 如果少一个参数会报404
        @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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    注意这里如果少传一个参数,是会报错的,目测这个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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    这里没有传入参数,已经设置了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();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    接口报错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)]
    
    • 1
    • 2

    代码提示我们Required request body is missing,很显然,加上注解后body就不能是空了,我们看下注解的源码。这里已经说的很清楚了,require默认是true。

    @Target(ElementType.PARAMETER)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface RequestBody {
    
    	/**
    	 * Whether body content is required.
    	 * <p>Default is {@code true}, leading to an exception thrown in case
    	 * there is no body content. Switch this to {@code false} if you prefer
    	 * {@code null} to be passed when the body content is {@code null}.
    	 * @since 3.2
    	 */
    	boolean required() default true;
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    我们通过body传入String、int、数组,返回结果,一切正常。
    在这里插入图片描述

    ⭐️@RequestHeader⭐️

    同样很直观,用于从header中获取数据

    @RestController
    @RequestMapping("/requestHeader")
    public class RequestHeaderController {
        
        @PostMapping("/header")
        public String getMapping(@RequestHeader("param")String param){
            return param;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    我们通过header进行参数传递,同样它可以设置是否必传,默认值等,请大家自行翻阅源码,就不一一罗列了。
    在这里插入图片描述

    ⭐️HttpServletRequest⭐️

    这是直接拿到request对象,可以从对象中灵活的获取参数,下面我们简单的罗列集中方式:

    @RestController
    @RequestMapping("/hsr")
    public class HttpServletRequestController {
    
        //通过getParameter直接获取,参数来源于URL中
        @GetMapping("/getUrlValue")
        public String getUrlValue(HttpServletRequest request) {
            String msg = request.getParameter("msg");
            return msg;
        }
    
        //通过参数集获取,参数来源于URL中
        @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();
        }
    
        //通过流获取body中的值,参数来源于请求body中
        @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;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    验证一下请求结果,如果通过这种方式取参数的话,只能通过硬编码的方式来限制必填、默认值等,第三种方式我们可以看到获取到的实际上是字符串,我们还需要通过json来进行转换。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    git仓库地址:https://gitee.com/ErGouGeSiBaKe/springboot-param-recieve
    postman文件已提交至工程中。

  • 相关阅读:
    【TensorFlow2 之012】TF2.0 中的 TF 迁移学习
    大三学生HTML期末作业,网页制作作业——HTML+CSS+JavaScript饮品饮料茶(7页)
    Spring Boot Actuator 漏洞复现合集
    Kotlin Multiplatform稳定版本发布:加速跨平台开发的新里程碑
    Python数据分析—Pandas可视化
    RocketMq4 消息发送示例及源码浅阅
    如何用three.js(webgl)搭建3D粮仓、3D仓库、3D物联网设备监控-第十二课
    ISIS—ISIS邻居建立&影响ISIS邻居建立的因素有哪些—03
    caffe 统计分析显示权重分布脚本
    ACL访问控制列表的解析和配置
  • 原文地址:https://blog.csdn.net/u010786653/article/details/125490056