Spring MVC 如何接收请求

news2024/11/24 16:44:31

1. 请求

浏览器访问不同的路径就是发送不同的请求,在发送请求时,可能会带有一些参数,所以我们就需要在后端接受参数。

2. 传递单个参数

接收单个参数,在Spring MVC中直接使用方法中的参数即可:

@RequestMapping("/request")
@RestController
public class RequestController {
    @RequestMapping("/request1")
    public String request1(String name) {
        return "接收到参数:" + name;
    }
}

使用PostMan发送带参数的请求:

可以看得到,request1方法接受到了参数 。(Params代表使用查询字符串传参......),注意请求中的 key(name)必须和方法中的参数名(name)相同,不同则接收不到,会默认为null

 接收基本类型:

@RequestMapping("/request")
@RestController
public class RequestController {
    @RequestMapping("/request2")
    public String request2(int age) {
        return "接受到参数:" + age;
    }
}

注意,如果请求中的key和代码中的参数名不同,则相当于没有传递这个参数,没有传递会默认传递一个null,显然把null传递给一个int类型是不行的,所以就会报错: 

 同理,如果我们传递一个非数字的值:

aaa无法强转为int类型,所以也会报错 。

使用包装类型接收:

@RequestMapping("/request")
@RestController
public class RequestController {
    @RequestMapping("/request3")
    public String request3(Integer age) {
        return "接受到参数:" + age;
    }
}

无参数时:

包装类型可以接受一个null,所以不会报错。

参数为aaa:

 

aaa同样无法强转为Integer,所以也会报错 。

所以接受基本类型时,建议使用其对应的包装类。

3. 传递多个参数

和传递单个参数相同,直接使用方法的参数接受即可

@RequestMapping("/request")
@RestController
public class RequestController {
    @RequestMapping("/request4")
    public String request4(String name, Integer age) {
        return "接收到参数,name: " + name + ",age:" + age;
    }
}

当参数过多时,我们要给方法写多个参数,这要很不美观,于是我们可以直接传递一个对象,我们新建一个类:

public class student {
    String name;
    Integer age;
    Character sex;
    Integer id;

    @Override
    public String toString() {
        return "student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex=" + sex +
                ", id=" + id +
                '}';
    }
}
@RequestMapping("/request")
@RestController
public class RequestController {
    @RequestMapping("/request5")
    public String request5(student s) {
        return "接收到参数,name: " + s;
    }
}

发送请求:

我们发现,并没有成功接收到参数,这是因为,传递对象参数时,服务器会调用默认的构造方法创建一个对象,然后调用set方法来给每个成员赋值,我们没有实现set方法所以没有成功接收到参数。 

我们给student类加上set方法:

public class student {
    String name;
    Integer age;
    Character sex;
    Integer id;

    public void setName(String name) {
        this.name = name;
    }

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

    public void setSex(Character sex) {
        this.sex = sex;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @Override
    public String toString() {
        return "student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", sex=" + sex +
                ", id=" + id +
                '}';
    }
}

可以发现此时就能够成功的接收到参数了。

如果此时我们的id和name使用int类型,我们不传递参数也不会报错,因为在创建对象后,会被默认赋值为0。

注意传递对象时,一定要保证传递的对象有无参数的构造方法,因为,接收参数时会默认调用无参数的构造方法,如果没有就会报错

4. 后端参数重命名

有时候前端传递过来的参数名含义太广,不利于我们阅读代码,例如前端传入一个 name,这个name 是人名,还是动物名,还是商品名,有很多解读,我们可以使用 @RequestParam 注解来重命名前后端的参数值。

@RequestMapping("/request")
@RestController
public class RequestController {
    @RequestMapping("/request6")
    public String request6(@RequestParam("name")String peopleName) {
        return "peopleName:" + peopleName;
    }
}

@RequestParam("name")String peopleName:代表把前端的参数"name"赋值给"peopleName"

 如果我们使用peopleName发送请求:

这时候报错了,所以使用peopleName无法接收到参数,但是 String类型是可以接收 null 类型的 ,为什么会报错?我们在idea查看报错信息:

这里说 方法参数类型为String的参数不存在 ,即报错的原因是没有传递这个参数,所以由此可知:使用@RequestParam 注解的参数必须传递。

要想保留@RequestParam 注解,又想使参数可以不传递,我们可以如下这样写:

@RequestMapping("/request")
@RestController
public class RequestController {
    @RequestMapping("/request7")
    public String request7(@RequestParam(value = "name", required = false)String peopleName) {
        return "peopleName:" + peopleName;
    }
}

value和required称为注解的属性,value就代表接收的参数名,required代表这个参数是否一定需要,我们可以选中这个注解点的 ctrl+B 转到这个注解的定义:

我们发行required的默认值是true, 即默认必须要传递,所以我们把它设置为false,就可以不用传递了。 

5. 传递数组

@RequestMapping("/request")
@RestController
public class RequestController {
    @RequestMapping("/request8")
    public String request8(int[] array) {
        return "接收到参数:" + Arrays.toString(array);
    }
}

数组传参有两种方式:

 

key相同时会组装成一个数组。

6. 传递集合

和传递数组类似:

@RequestMapping("/request")
@RestController
public class RequestController {
    @RequestMapping("/request9")
    public String request9(List<Integer> list) {
        return "接收到参数:" + list;
    }
}

我们发现使用数组的传递方式并没有传递成功,而是报错了,我们查看idea的报错信息 :

第一句就已经告诉了我们错误的原因:没有找到 接口java.util.List 主要的或唯一的构造函数。我们前面就说到了,接收对象时,服务器端会调用其默认的构造方法,然后在把参数赋值进对象,List是一个接口,并没有提供默认的构造方法,所以会报错。

现在我们把List改为 ArrayListL:

@RequestMapping("/request")
@RestController
public class RequestController {
    @RequestMapping("/request9")
    public String request9(ArrayList<Integer> list) {
        return "接收到参数:" + list;
    }
}

我们发现,这次没有报错,但是参数并没有接收成功, 这是因为,默认情况下,请求中参数名相同的多个值,是封装为数组,所以无法将请求中的参数值正确地转换为ArrayList 对象导致的,这时我们可以使用上面使用过的@RequestParam注解:

@RequestMapping("/request")
@RestController
public class RequestController {
    @RequestMapping("/request9")
    public String request9(@RequestParam ArrayList<Integer> list) {
        return "接收到参数:" + list;
    }
}

@RequestParam注解会获取指定名称参数的值(这里没有指定则默认和后端的参数的名称相同),然后根据后端参数类型进行自动类型转换,这里即转换为ArrayList。

此时我们再发送请求就能正常获取到参数了:

既然@RequestParam注解会根据后端参数类型进行自动类型转换,那么代表后端参数并不用调用构造方法,直接接收@RequestParam注解转化的对象,所以我们也可以使用接口作为参数:

@RequestMapping("/request")
@RestController
public class RequestController {
    @RequestMapping("/request9")
    public String request9(@RequestParam List<Integer> list) {
        return "接收到参数:" + list;
    }
}

 7. 传递JSON数据

JSON:JavaScript Object Notation (Java Script 对象表示法)

JSON是一种数据格式,用键值对的形式储存数据,使用文本表示一个对象或数组的信息,本质上是字符串,用于不同语言中数据的传递和交换。

JSON语法:

  1. 数据在键值对中,键和值用 : 隔开
  2. 数据由逗号分隔
  3. 对象用{ }表示
  4. 数组用[ ]表示
  5. 值可以为对象也可以为数组,数组中可以包含多个对象

使用JSON传递一个对象:

@RequestMapping("/request")
@RestController
public class RequestController {
    @RequestMapping("/request10")
    public String request10(student s) {
        return "接收到参数,name: " + s;
    }
}

在PostMan中我们选择Body 然后选择raw就可以看到有方有个蓝色字体的JSON,就可以传递JSON数据了:

我们发现并没有接收成功,这是因为,接收参数时会在接收的数据中找student的各个属性来赋值,而传递的JSON是一个对象是一个整体,所以是找不到student的属性的,这是我们需要使用@RequestBody 注解,表示要把body中的整个数据表示,转化为student对象

@RequestMapping("/request")
@RestController
public class RequestController {
    @RequestMapping("/request10")
    public String request10(@RequestBody student s) {
        return "接收到参数,name: " + s;
    }
}

 JSON字符串转化为Java对象的过程是通过JSON转换工具实现的,Spring MVC框架已经集成了JSON转换工具,jackson-databind,如果要脱离Spring MVC使用则要添加对应的依赖。

使用示例:

public class JSONTest {
    public static void main(String[] args) throws JsonProcessingException {
        ObjectMapper objectMapper = new ObjectMapper();
        String s = "{\n" +
                "    \"name\":\"小明\",\n" +
                "    \"age\":20,\n" +
                "    \"sex\":\"男\",\n" +
                "    \"id\":1001\n" +
                "}";
        student stu = objectMapper.readValue(s, student.class);
        System.out.println(stu);
    }
}

 这个方法的原理是通过反射获取到student的造方法创建对象,然后解析 字符串s中的内容映射到student对象中,注意要提供无参数的构造方法,否则可能会出错

8. 获取URL中的参数 

参数可以直接放在URL中,例如: http://127.0.0.1:8080/request/request11/123456

这个123456可能不是代表路径,而是一个数据。

获取URL中的数据需要使用 @ PathVariable注解:

@RequestMapping("/request")
@RestController
public class RequestController {
    @RequestMapping("/request11/{id}")
    public String request11(@PathVariable("id") Integer id) {
        return "接收到参数:" + id;
    }
}

作为参数的部分路径要使用{ } 括起来,两个注解中获取的路径名称要相同(即都是id),@PathVariable 中可不写参数(即不写id),这是则要求,后面参数的名称要和URL中相同(即Integer id),如果@PathVariable 中可写了参数,则对后面(Integer)的参数名没有要求。

9. 上传文件 

文件要使用 MultipartFile 接口来接收,并且需要加上@RequestPart注解

@RequestMapping("/request")
@RestController
public class RequestController {
    @RequestMapping("/request12")
    public String request11(@RequestPart("file") MultipartFile file) {
        return "接收到文件:" + file.getOriginalFilename();
    }
}

@RequestPart注解的参数要和接收的数据的Key相同

在PostMan中点击Body 再点击 form-data 或者 x-www-form-urlencoded 就可以传输文件

成功返回了文件的名称。

10. 获取Cookie/Session

  • Cookie:之前我们介绍过Cookie,简单来说,Cookie就是一段数据,存储了关于用户的一些信息。当我们在某个网站登录时,网站会发送给我们一个令牌(token),这个令牌就储存在Cookie中,有了这个令牌,我们下次访问网站时把Cookie传入到服务器,服务器就可以知道我们的身份,就不用每次登录都要登录账号。
  • Session:Session是用于服务器储存用户的信息的,上面我们说,我们访问网站时,登录后网站会给我们一个令牌,Session就可以理解为,记录每个令牌对应的用户数据,让服务器拿到令牌时能区分出用户,Session的本质是一个哈希表,储存了一些键值对结构,Key称为SessionId,Value就是用户信息,令牌就可以看作SessionId。
  • SessionId是服务器生成的一个“唯一性字符串”,从Session机制的⻆度来看,这个唯⼀性字符串称为SessionId但是站在整个登录流程中看待,也可以把这个唯⼀性字符串称为token,(注意SessionId只是实现token的一种方式,两者不能完全对等)

 Cookie和Session的区别:

  • Cookie是客户端保存用户信息的一种机制,Session是服务器保存用户信息的一种机制
  • Session默认保存在内存中,如果重新服务器Session数据会丢失,Cookie储存在硬盘中
  • Cookie和Session经常会配合在一起使用,但不是必须配和,SessionId不一定非要保存在Cookie中,SessionId也不一定非要通过Cookie传输。

 传统方式获取Cookie:

@RequestMapping("/request")
@RestController
public class RequestController {
    @RequestMapping("/request13")
    public String getCookie(HttpServletRequest request, HttpServletResponse response) {
        Cookie[] cookies = request.getCookies();
        if(cookies != null) {
            Arrays.stream(cookies).forEach(x -> System.out.println(x.getName() + ":" + x.getValue()));
        }
        return "接收到Cookie";
    }
}

HttpServletRequest类用于接收一个请求,即包含了请求中的所有内容

调用getCookies()方法即可的到对应的Cookie数组,由于我们并没有Cookie所以获取到的Cookie是空的,我们可以通过浏览器的调试工具添加Cookie

也可以使用PostMan修改Cookie

 通过@CookieValue注解获取Cookie:

@RequestMapping("/request")
@RestController
public class RequestController {
    @RequestMapping("/request14")
    public String getCookie2(@CookieValue("ck") String ck) {
        return "接收到Cookie,ck:" + ck;
    }
}

注解中填要获取的Cookie的Key,一次只能获取一个:

传统方式设置Session:

@RequestMapping("/request")
@RestController
public class RequestController {
    @RequestMapping("/request15")
    public String setSession(HttpServletRequest request) {
        //从Cookie中获取SessionId再通过SessionId找到Session
        HttpSession session = request.getSession();
        session.setAttribute("name", "小明");
        return "设置Session成功";
    }
}

访问该方法即可设置Session

直接在参数中写HttpSession类:

@RequestMapping("/request")
@RestController
public class RequestController {
    @RequestMapping("/request16")
    public String setSession2(HttpSession session) {
        session.setAttribute("name", "小明");
        return "设置Session成功";
    }
}

传统方式获取Session:

@RequestMapping("/request")
@RestController
public class RequestController {
    @RequestMapping("/request17")
    public String getSession1(HttpServletRequest request) {
        //从Cookie中获取SessionId再通过SessionId找到Session
        HttpSession session = request.getSession();
        String name = (String)session.getAttribute("name");
        return "获取到Session:" + name;
    }
}

 通过@SessionAttribute注解获取Session:

@RequestMapping("/request")
@RestController
public class RequestController {
    @RequestMapping("/request18")
    public String getSession2(@SessionAttribute("name") String name) {
        return "获取到Session:" + name;
    }
}

11. 获取Header

Header包含在请求中,我们同样可以使用HttpServletRequest 类获取到:

@RequestMapping("/request")
@RestController
public class RequestController {
    @RequestMapping("/request19")
    public String getHeader1(HttpServletRequest request) {
        String userAgent = request.getHeader("User-Agent");
        return "获取到,User-Agent:" + userAgent;
    }
}

使用@RequestHeader注解获取:

@RequestMapping("/request")
@RestController
public class RequestController {
    @RequestMapping("/request20")
    public String getHeader1(@RequestHeader("User-Agent")String userAgent) {
        return "获取到,User-Agent:" + userAgent;
    }
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1523281.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++中的struct与class详解

在C中&#xff0c;struct和class都是用户定义类型&#xff08;UDT&#xff09;的关键字&#xff0c;用于封装数据和函数。尽管它们在许多方面都非常相似&#xff0c;但也存在一些关键差异。 1. 默认访问权限 • **struct**&#xff1a;默认的成员访问权限是public。• **clas…

jvm的垃圾回收器以及触发full gc的场景

JVM&#xff08;Java虚拟机&#xff09;的垃圾回收器有很多种&#xff0c;主要包括以下几种&#xff1a; Serial收集器&#xff1a;串行收集器是最古老、最稳定的收集器。它使用单个线程进行垃圾收集工作&#xff0c;在进行垃圾回收时会暂停所有用户线程。 ParNew收集器&#…

nginx实时流量拷贝ngx_http_mirror_module

参考&#xff1a; Module ngx_http_mirror_module Nginx流量拷贝ngx_http_mirror_module模块使用方法详解 ngx_http_mirror_module用于实时流量拷贝 请求一个接口&#xff0c;想实时拷贝这个请求转发到自己的服务上&#xff0c;可以使用ngx_http_mirror_module模块。 官网好像…

本地用AIGC生成图像与视频

最近AI界最火的话题&#xff0c;当属Sora了。遗憾的是&#xff0c;Sora目前还没开源或提供模型下载&#xff0c;所以没法在本地跑起来。但是&#xff0c;业界有一些开源的图像与视频生成模型。虽然效果上还没那么惊艳&#xff0c;但还是值得我们体验与学习下的。 Stable Diffu…

python3GUI--qt仿暴风影音视频播放器By:PyQt5(附下载地址)

文章目录 一&#xff0e;前言二&#xff0e;环境1.开发环境2.打包环境3.运行环境 三&#xff0e;软件截图1.启动页2.视频播放3.音频播放4.其他1.托盘2.对话框 四&#xff0e;功能总览五&#xff0e;代码展示&心得1.UI设计2.如何防止卡顿3.如何自定义组件 五&#xff0e;思考…

实在智能Agent——RPA终极进化方向

RPA技术备受瞩目&#xff0c;它通过“机器人”自动化了人力执行的重复性、低复杂度任务&#xff0c;解放了员工并降低了企业成本。RPA机器人全天候运行&#xff0c;避免人为错误&#xff0c;高效处理任务&#xff0c;成为处理事务、操作数据、回应查询的理想选择。在管理后台&a…

HTML基础:了解CSS的3种创建方法

你好&#xff0c;我是云桃桃。 CSS&#xff0c;即层叠样式表&#xff08;Cascading Style Sheets&#xff09;&#xff0c;是一种用于描述网页样式和布局的标记语言。它通过定义样式规则来控制网页元素的外观和排版&#xff0c;包括文字大小、颜色、边距、背景等&#xff0c;从…

mac打开exe文件的三大方法 mac怎么运行exe文件 mac打开exe游戏 macbookpro打开exe

exe文件是Windows系统的可执行文件&#xff0c;虽然Mac系统上无法直接打开exe文件&#xff0c;但是你可以在Mac电脑上安装双系统或者虚拟机来实现mac电脑上运行exe文件。除了这两种方法之外&#xff0c;你还可以在Mac电脑上使用类虚拟机软件打开exe文件&#xff0c;这三种方法各…

基于springboot的高校化学试剂仓储管理系统

文章目录 项目介绍主要功能截图&#xff1a;部分代码展示设计总结项目获取方式 &#x1f345; 作者主页&#xff1a;超级无敌暴龙战士塔塔开 &#x1f345; 简介&#xff1a;Java领域优质创作者&#x1f3c6;、 简历模板、学习资料、面试题库【关注我&#xff0c;都给你】 &…

大数据面试题之SQL题

大数据面试题之SQL题 1.有一个录取学生人数表&#xff0c;记录的是每年录取学生人数和入学学生的学制 以下是表结构&#xff1a; CREATE TABLE admit ( id int(11) NOT NULL AUTO_INCREMENT, year int(255) DEFAULT NULL COMMENT ‘入学年度’, num int(255) DEFAULT NULL COMM…

opencv中的图像均值模糊—blur

平均模糊是通过对图像的每个像素及其周围像素的值求平均来实现的。 blur函数通过计算输入图像image中每个像素及其邻域内像素的平均值来工作。 // 图像卷积 void QuickDemo::Conv_image_demo(Mat &image) {Mat dst;blur(image, dst, Size(3, 3), Point(-1, -1));// Point(…

Android 地图SDK 设置中心点和缩放比例

问题 Android 地图SDK 设置中心点和缩放比例 详细问题 笔者进行Android 项目开发&#xff0c;接入高德地图SDK。但是默认在地图所设置的中心点为北京天安门&#xff0c;缩放比例固定。如何修改 期望效果 解决方案 import com.amap.api.maps.model.LatLng; import com.amap…

基于java+springboot+vue实现的学生宿舍管理系统(文末源码+Lw+ppt)23-438

摘 要 伴随着我国社会的发展&#xff0c;人民生活质量日益提高。于是对贵工程学生宿舍进行规范而严格是十分有必要的&#xff0c;所以许许多多的信息管理系统应运而生。此时单靠人力应对这些事务就显得有些力不从心了。所以本论文将设计一套贵工程学生宿舍管理系统&#xff0…

【机器学习300问】35、什么是随机森林?

〇、让我们准备一些训练数据 idx0x1x2x3x4y04.34.94.14.75.5013.96.15.95.55.9022.74.84.15.05.6036.64.44.53.95.9146.52.94.74.66.1152.76.74.25.34.81 表格中的x0到x4一共有5个特征&#xff0c;y是目标值只有0,1两个值说明是一个二分类问题。 关于决策树相关的前置知识&am…

实现一个横向的picker

Picker 选择器显示一个或多个选项集合的可滚动列表&#xff0c;相比于原生 picker&#xff0c;实现了 iOS 与 Android 端体验的一致性。 要实现横向 picker&#xff0c;其实跟纵向 picker差不多&#xff0c;都支持滚动时停留在指定位置&#xff0c;并且支持滚动到边界支持反弹…

代码随想录 贪心算法-难度题目-其他题目

目录 53.最大子数组和 134.加油站 968.监控二叉树 53.最大子数组和 53. 最大子数组和 中等 给你一个整数数组 nums &#xff0c;请你找出一个具有最大和的连续子数组&#xff08;子数组最少包含一个元素&#xff09;&#xff0c;返回其最大和。 子数组 是数组中的一个…

HJ212协议C#代码解析实现

HJ212协议C#代码解析实现 HJ212协议是环保中一个非常重要的标准协议&#xff08;字符串协议&#xff09;&#xff0c;之前写了两篇C HJ212协议解析的相关博文&#xff1a; 环保 HJ212协议解析基于Qt5.14.2的HJ212 TCP服务端接收解析入库程序 最近在学习C#&#xff0c;所以打算…

T1.数据库MySQL

二.SQL分类 2.1 DDL 2.1.1数据库操作 1). 查询所有数据库 show databases ; 2). 查询当前数据库 select database(); 3)创建数据库 create database [if not exists] 数据库名 [default charset 字符集] [collate 排序规则] ; 4&#xff09;删除数据库 drop database …

【你也能从零基础学会网站开发】Web建站之jQuery进阶篇 jQuery常见属性和方法概述与使用

&#x1f680; 个人主页 极客小俊 ✍&#x1f3fb; 作者简介&#xff1a;程序猿、设计师、技术分享 &#x1f40b; 希望大家多多支持, 我们一起学习和进步&#xff01; &#x1f3c5; 欢迎评论 ❤️点赞&#x1f4ac;评论 &#x1f4c2;收藏 &#x1f4c2;加关注 jQuery创建新的…

Docker 哲学 - 容器操作 (二)

命令行启动 参数键值之间可以使 " " 或者 空格 卷的挂载是在容器创建时指定的&#xff0c;不能在容器运行时再添加 当加上 --network-alias 设置同一网络下别名参数后 &#xff0c;inspect 该容器发现 会同步到 容器信息中 2、给容器打日志 docker logs 【-…