当前位置: 首页 > news >正文

SpringBoot接收参数的几种常用方式

目录

    • 一、四种传参方式
    • 二、无注解
    • 三、@RequestParam
    • 四、@PathVariable
    • 五、@RequestBody
    • 六、@RequestHeader
    • 七、HttpServletRequest

如果对@RequestMapping不是特别了解的,建议读一下这篇文章: https://blog.csdn.net/weixin_43888891/article/details/126861310

参数映射准确来说是springmvc来帮我们干的活,但是由于springboot太过火爆,简化了springmvc相关配置文件,以至于很多人会误认为是springboot的功能。其实springboot是帮我们整合了spring相关框架。记住只是简化,底层还是不变的!

一、四种传参方式

在学习接收参数前,肯定要先了解一共有几种传参方式,下面一共提供了四种,供参考学习:

1)params传参,params传参的格式是http://xxx?参数名=值&参数名=值。在postman当中params当中添加参数会发现,他就是在地址栏上加的参数。

在这里插入图片描述

2)body表单传参,就是请求体传参

form-data的请求是在body中,为key=value格式,同时可以传文件,Content-Type为multipart/form-data,后端可以用@RequestParam接收。

在这里插入图片描述

3)json传参

json传参也是在body当中,只不过json是一种数据格式,后端可以用@RequestBody接收。

在这里插入图片描述

4)地址栏传参,直接通过/在地址上拼接参数值,这种方式不需要在地址栏上写参数名,后端只需要知道他在地址的哪个位置传的参数就可以拿到值!

在这里插入图片描述

这两个实体类用来当做测试类,用来接参数,后续我们会不断的使用到他:

public class Params {
    private String userName;
    private Integer age;

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Param{" +
                "userName='" + userName + '\'' +
                ", age=" + age +
                '}';
    }
}
public class User {
    private String userName;

    @Override
    public String toString() {
        return "User{" +
                "userName='" + userName + '\'' +
                '}';
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }
}

二、无注解

import com.gzl.cn.demo.entity.Params;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/noAnno")
public class NoAnnoController {

    @GetMapping("/url")
    public String getMapping(String msg) {
        return msg;
    }
	
	// 可以有多个实体类参数
    @GetMapping("/body")
    public String getMapping(Params param,User user) {
    	System.out.println(param);
        System.out.println(user);
        return param.toString();
    }

    @PostMapping("/post")
    public String postMapping(String msg) {
        return msg;
    }

    @PostMapping("/post-body")
    public String postMapping(Params msg) {
        return msg.toString();
    }

}

以下是测试的详细步骤:

(1)测试无注解params传参

测试:get请求:

http://localhost:8080/noAnno/url?msg=111
http://localhost:8080/noAnno/body?userName=张三&age=11
在这里插入图片描述

测试:post请求:post请求我们无法通过浏览器来访问,得需要借助postman调用

http://localhost:8080/noAnno/post?msg=111
http://localhost:8080/noAnno/post-body?userName=张三&age=22

当然也可以借用cmd框当中的curl命令来请求post
curl http://localhost:8080/noAnno/post-body -X POST -d "userName=66&age=22"

在这里插入图片描述

(2)测试无注解body表单传参

在这里插入图片描述

(3)测试无注解params传参+body表单传参 两种同时传参

在这里插入图片描述

总结:

  1. 没有注解的时候可以选择params传参也可以选择body表单传参,甚至可以两种同时传,两种同时传会将body传的参数使用逗号拼接上params传的参数
  2. 不管是body还是params 在不传参的情况下都不会报错,在后端会拿到null值,这块需要注意一下!假如是null值的情况下去get属性,或者是tostring就会空指针!如果传参的话,参数名要和controller当中定义的变量名一样才能接受到参数!任意请求方式 都是一样的!
  3. 可以有多个参数的,如果是实体类接参数的话,也是可以有多个实体类的!就算两个实体类当中有参数重复了,也不影响,两个实体类都会接到参数的!

三、@RequestParam

http://localhost:8089/conformity/parm/requestParm8?uid=1&uname=222&pwd=2222

就是在地址?然后加上&拼接。

不携带@RequestParm的时候,可以连key值都不传。

@GetMapping("/requestParm")
public void requestParm(Integer id){
	System.out.println("get不带@RequestParam:"+id);
}

携带@RequestParm的时候,必须传值。因为@RequestParam注解的required默认是true。假如不传会报错。

@GetMapping("/requestParm1")
public void requestParm1(@RequestParam Integer id){
	System.out.println("get带@RequestParam:"+id);
}
  • @RequestParam接收参数,不可使用使用实体来封装,如下所示,直接会报400错误。
  • 不带@RequstParm然后使用实体来接参数,其实是没问题的,并且不传key值也是可以的。post、get都一样。
// 错误的
@PostMapping("/requestParm7")
public void requestParm7(@RequestParam User user){
	System.out.println("get带@RequestParam:"+user);
}

@RequestParam参数映射:注意@RequestParam默认是以变量名作为前端传参名称,但是假如我们注解设置了名称,如下,那么参数名称以注解当中的属性为准!假如前端传msg而不是msg1就会报异常。

@GetMapping("/url")
public String getMapping(@RequestParam("msg1") String msg) {
    System.out.println(msg);
    System.out.println(aaa);
    return msg;
}

总结:

1、传单个参数的时候可以使用@RequestParam,不带也可以,带上就意味着前端必须传这个值。

2、实体接受参数的话,不可以带,带上就会报错。不带的话是可以接受多个参数的。并且没有key限制。

@RequestParam的属性

  • valuename属性使用了@AliasFor,在spring当中起着一个注解属性别名传递值的作用。也就是我给value属性赋值,name属性同样也能取到值,name属性赋值,value属性也同样可以取到值。
    @RequestParam(value = "msg")等同于@RequestParam("msg"),因为注解当中不带属性名称默认指的就是value属性,而@RequestParam("msg")等同于@RequestParam(name = "msg")
  • required属性代表的是否是必填,默认是true,这个true代表的是前端必须传key值,value值可以随意,但是key值是必须的。假如不传就是400异常!
  • defaultValue属性:设置默认值,可以避免required属性设置为true然后前端不传key值报错的问题。相当于设置defaultValue属性之后,前端传不传值都可以,传值就以前端的为准,不传值就以设置的defaultValue值为准!示例如下:
    @RequestParam(name = "pageNo",required = false,defaultValue = "1") Integer pageNo
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {

	@AliasFor("name")
	String value() default "";

	@AliasFor("value")
	String name() default "";

	boolean required() default true;

	String defaultValue() default ValueConstants.DEFAULT_NONE;
}

四、@PathVariable

@PathVariable 用于绑定 url 中的占位符。例如:请求 url 中 /delete/{id},这个{id}就是 url 占位符。url 支持占位符是 spring3.0 之后加入的。是 springmvc 支持 rest 风格 URL 的一个重要标志。

@RequestMapping("/pathVariable2/{id}")
public void pathVariable2(@PathVariable Integer id){
	System.out.println("get带@RequestParam:"+id);
}

上面代码示例使用了地址栏传参,就算不带@PathVariable也可以访问,只不过接不到值。

@PathVariable 的属性

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PathVariable {

	@AliasFor("name")
	String value() default "";

	@AliasFor("value")
	String name() default "";

	boolean required() default true;

}

总结:

  • 如果@PathVariable不设置属性值,默认的话,只要参数名称和占位符当中的名称一致就可以,如果名称不一致就会报错
  • 一旦设置属性值了,就一定要和占位符当中的一致,否则就会报错!

在这里插入图片描述

五、@RequestBody

@RequestBody一般被用来接收http请求中body中json数据。

get、post都可以使用。一般用于post。

@RequestMapping("/requestBody2")
public void requestBody2(@RequestBody Params params){
    System.out.println("get带@RequestParam:"+params);
}

{"userName":"111","age":"11"},传输json数据,也可以不传key。这里有一点需要注意,mvc给我们做了参数类型转换,Params 对象当中的age是Integer类型,但是json传字符串,照样可以映射进去。Boolean、BigDecimal、Integer、String、Date这些其实都可以映射进去的。当然Date相对来说比较特殊一点。传yyyy-MM-dd格式是不会报错的。但是其他格式可能就会报错了,一般使用Date类型接参数涉及到需要咱们自己格式化,关于日期相关问题感兴趣的可以看这一篇文章:https://blog.csdn.net/weixin_43888891/article/details/126846791

@RequestBody 的属性

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestBody {

	boolean required() default true;

}
  • required默认为true,代表的就是json不能什么都不传,否则报错400,但是允许个别属性不传。
  • 设置为false的话就是可以什么都不传。

六、@RequestHeader

@RequestHeader主要用来获取请求当中的请求头

@RestController
@RequestMapping("/requestHeader")
public class RequestHeaderController {
    
    @PostMapping("/header")
    public String getMapping(@RequestHeader("param")String param){
        return param;
    }
}

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

在这里插入图片描述

七、HttpServletRequest

这是直接拿到request对象,通过request可以从对象中灵活的获取参数:

@RestController
@RequestMapping("/request")
public class HttpServletRequestController {

    @GetMapping("/getUrlValue")
    public String getUrlValue(HttpServletRequest request) {
        // 没有的时候不会报错,直接为null
        String msg = request.getParameter("msg");
        System.out.println(msg);
        return msg;
    }

    @GetMapping("/getUrlValues")
    public String getHttpServletRequestValue(HttpServletRequest request) {
        Map<String, String[]> parameterMap = request.getParameterMap();
        return JSONObject.toJSONString(request.getParameterMap());;
    }
}

针对于request.getParameter("msg");,其实就是跟@RequestParam差不多,可以获取到body当中的for-data的数据以及使用url ?拼接的参数的数据

http://localhost:8080/request/getUrlValue

相关文章:

  • Linux--权限
  • ESP32上手指南
  • 多径信道下通过LMS均衡算法提高通信质量——详细版
  • 前端笔试/面试题
  • 基于C51语音控制小车
  • 算法优化 | MATLAB实现BO-RF贝叶斯优化随机森林算法
  • C# 中的多线程
  • 【C++】类和对象(下)—— 再谈构造函数 | static成员 | C++11补丁 |友元
  • 初始C语言(2)
  • DevOps CI/CD 常见面试题
  • SpringSecurity (二) --------- 认证
  • Mybatis新增数据,存在就更新,不存在就添加
  • 嵌入式linux驱动之并发
  • 【Nginx】三、Nginx实现四层负载均衡Nginx实现限流防盗链流量镜像
  • 【第一弹】Python题库刷题---完事开头难,从基础题开始
  • 【Leetcode】104. 二叉树的最大深度
  • Computed property XXX was assigned to but it has no setter
  • dva中组件的懒加载
  • ECMAScript6(0):ES6简明参考手册
  • es的写入过程
  • Fabric架构演变之路
  • Linux下的乱码问题
  • node-sass 安装卡在 node scripts/install.js 解决办法
  • PHP的Ev教程三(Periodic watcher)
  • RxJS 实现摩斯密码(Morse) 【内附脑图】
  • Vue 动态创建 component
  • Vue实战(四)登录/注册页的实现
  • XForms - 更强大的Form
  • 从tcpdump抓包看TCP/IP协议
  • 观察者模式实现非直接耦合
  • 基于axios的vue插件,让http请求更简单
  • 罗辑思维在全链路压测方面的实践和工作笔记
  • 每天10道Java面试题,跟我走,offer有!
  • 模仿 Go Sort 排序接口实现的自定义排序
  • 日剧·日综资源集合(建议收藏)
  • 使用putty远程连接linux
  • 试着探索高并发下的系统架构面貌
  • 思考 CSS 架构
  • 文本多行溢出显示...之最后一行不到行尾的解决
  • 我这样减少了26.5M Java内存!
  • MPAndroidChart 教程:Y轴 YAxis
  • UI设计初学者应该如何入门?
  • 浅谈sql中的in与not in,exists与not exists的区别
  • # 20155222 2016-2017-2 《Java程序设计》第5周学习总结
  • #1015 : KMP算法
  • #大学#套接字
  • $.ajax中的eval及dataType
  • (Mac上)使用Python进行matplotlib 画图时,中文显示不出来
  • (TipsTricks)用客户端模板精简JavaScript代码
  • (动手学习深度学习)第13章 计算机视觉---图像增广与微调
  • (深度全面解析)ChatGPT的重大更新给创业者带来了哪些红利机会
  • (转载)虚幻引擎3--【UnrealScript教程】章节一:20.location和rotation
  • (总结)Linux下的暴力密码在线破解工具Hydra详解
  • .describe() python_Python-Win32com-Excel
  • .htaccess 强制https 单独排除某个目录