Spring MVC(建立连接 + 请求)

news2025/1/24 1:41:02

文章目录

  • 一、建立客户端和服务器的连接
  • 二、如何构造请求(传参)
    • 2.1 构造请求方式 + 参数通用注解
    • 2.2 传递单个参数
    • 2.3 传递多个参数
    • 2.4 传递数组/集合
    • 2.5 传递对象
    • 2.6 传递JSON
  • 三、相关的其他请求操作
    • 3.1 获取URL中的参数 @PathVariable
    • 3.2 上传文件 @RequestPart
    • 3.3 获取和设置 Cookie/Session
      • Cookie和Session相关概念
      • 获取 + 设置 Cookie
      • 获取 + 设置Session
    • 3.4 获取Header

一、建立客户端和服务器的连接

  1. 如何建立:@RequestMapping
    • 通过 @RequestMapping 注解建立一个路由映射
    • 由于Spring Boot 内置了Tomcat,Tomcat会帮我们根据这个路由映射,去找到执行的文件
  2. @RequestMapping
    • 修饰对象:类和方法都可以修饰
    • 支持的方法:所以的请求方法都支持
      • 关于指定支持的方法:使用method属性
@RestController
@RequestMapping("/test")
public class HelloController {
    @RequestMapping(value = "/sayhi",method = RequestMethod.GET)
    public String sayHi(){
        return "hello";
    }
}
  1. 注解的属性:如果注解没有写属性名,默认属性名是value,而一旦有多个就需要区分哪个是哪个了

  2. 地址相关问题

    • 访问地址:类的路径/方法路径
    • 路径的写法
      • 层级:可以写多层,如@RequestMapping(“/hello/m1”)
      • 类路径:企业开发商建议写上类路径,因为这既可以减少名字的重复率,降低取名的难度,还可以方便我们查找代码
      • 关于/:理论上可以省略,但实际在企业开发上,建议加上,且是前加后不加 -------> 【/hello/m1】
      • 路径名VS方法名:两者没有什么关系,可以不一样,但是我们通常会取名一样,因为这样可以减少取名频率,且方便我们查找代码

二、如何构造请求(传参)

2.1 构造请求方式 + 参数通用注解

  1. 请求构造方式

    • 两种方法:请求的构造主要由前端或工具两种方式构造
    • 为什么我们使用Postman:但由于前后端分离,后端开发人员只需要提供一个接受参数的服务即可,至于怎么传参是前端的事,所以我们一般不用前者,而且为了测试个后端代码,还要写个前端很不值当。所以,我们此处所讲的都是通过postman来构造请求。
  2. 如何构造post请求)

    • 依靠前端:依靠前端的form表单/ajax
    • 依靠工具:使用Postman工具构造
  3. 如何传递JSON对象

    • 依靠前端:依靠前端的ajax传递
    • 依靠工具:使用Postman工具构造
  4. Postman使用的简单介绍:与HTTP格式一一对应

    • 为什么优先使用POST:Postman如果使用GET请求,Spring会默认从查询字符串里拿数据,这是Postman的默认设置,此时如果要传的数据是JSON之类的,就会出bug。所以,我们优先使用POST方法
    • 接口的改名

在这里插入图片描述

在这里插入图片描述

  1. 后端参数重命名:@RequestParam注解,注解里面的参数是“前端传的”,后面的则是“后端想用的”
    • 底层逻辑:服务器获取到name对应的值后,将其赋值给username
    • 注意点:使用这个注解后,重命名的参数就变成必传参数了。如果想修改为“非必传”,只需要把required这个属性设置为false即可。
      在这里插入图片描述
@RestController
@RequestMapping("/param")
public class ParamController {
    @RequestMapping("/m4")
    public String m4(@RequestParam("name") String username){
        return username;
    }
}

2.2 传递单个参数

  1. 底层逻辑
    • 从请求的参数中,获取参数名为name的值,并给name赋值。
    • 相当于封装了Servlet的getPartmer方法,所以后端参数名要求和传的参数名一致。
@RestController
@RequestMapping("/param")
public class ParamController {
    @RequestMapping("/m1")
    public String m1(String name){
        return name;
    }
}

在这里插入图片描述

2.3 传递多个参数

  1. 如果设置的值未传怎么办:值为nul
    • 为何推荐使用包装类:因为如果未传值,该参数就会被赋值为null,如果此时数据类型为基本数据类型就会报错。所以企业开发中,我们建立使用包装类。
  2. 参数顺序:传递原理参考【传递单个参数】,所以参数传递顺序是无所谓的
@RestController
@RequestMapping("/param")
public class ParamController {
    @RequestMapping("/m2")
    public String m2(String name, Integer age){
        return "name:" + name + ", age:" + age;
    }
}

在这里插入图片描述

2.4 传递数组/集合

  1. 原理:当发送的请求中,同一个参数有多个时,浏览器会默认帮我们给封装成一个数组
  2. 传递数组
    • 两种请求路径
      • 参数间使用&:127.0.0.1:8080/param/m1?name=李四&name=张三&name=王五
      • 参数间使用,:127.0.0.1:8080/param/m1?name=李四,张三,王五
    • 后端代码
@RestController
@RequestMapping("/param")
public class ParamController {

    @RequestMapping("/m1")
    public String m1(String[] name){
        //使用lambda表达式进行循环
        Arrays.stream(name).forEach(s -> {
            System.out.print(s + " ");
        });
        return "已经正常接受数组";
    }
}
  1. 传递集合:使用 @RequestParam
    • 为什么要使用注解:因为如果收到多个同参数名的参数,Spring会默认帮我们封装为数组,此时我们是无法用调用集合的方法的。所以我们需要用@RequestParam注解告诉Spring这个参数是个集合。
    • 请求路径:和【传递数组】的传递方法一样
    • 后端代码
@RestController
@RequestMapping("/param")
public class ParamController {

    @RequestMapping("/m2")
    public String m2(@RequestParam List<String> name){
        return "接收到的list对象有:" + name.toString();
    }
}

2.5 传递对象

  1. 原理
    • 前三种方法的弊端
      • 一旦我们需要更改参数,就需要去修改接口定义,并且通知所以调用这个方法的地方,全部改请求参数,这十分繁琐。
      • 一旦前端未传一个后端业务运行所必须的参数,程序就会报错,容错率低
    • 为什么使用对象
      • 如果要修改参数,我们直接在对象内部添加即可
      • 遇到前端未传后端必须的数据时,后端代码里加点逻辑即可
  2. 后端代码
@RestController
@RequestMapping("/param")
public class ParamController {
    @RequestMapping("/m3")
    public String m3(Person person){
        return person.toString();
    }
}
public class Person {
    private String name;
    private String age;
}
  1. 请求发送:共有两种方法
    • query string:query string里直接把值放进去,Spring 会帮我们进行关系的映射。如【127.0.0.1:8080/param/m3?name=lisi&age=15】
    • JSON:解决了第一种方法query string内容太多的问题

2.6 传递JSON

  1. 什么是JSON
    • 一种轻量级的数据交互格式
    • 本质是一个字符串,可以和Java对象互相转换
      • 如何互转:使用ObjectMapper类的方法
  2. JSON的泛用性:因为只是数据交互格式,故而实际上面所有的传参都可以通过JSON来传
  3. JSON的格式介绍
    • 键值对
      • 存储地点:数据保存在键值对(Key/Value)中
      • 数据类型:key全部都是字符串,所以要用引号引起来,value则可以是各种类型
      • 分隔问题:键和值使用冒号分隔,数据之间则用逗号分隔
    • 对象和数组表示方法:对象用{}表示,数组用[]表示
  4. 如何传递JSON数据:使用 @RequestBody 注解
    • 为什么要使用该注解
      • 默认情况下,Spring MVC 会将请求参数绑定到方法的参数上,但请求体中的数据并不包含在标准的请求参数中(原本是key-value,传过来直接变成了一整个数据)
      • @RequestBody注解可以让Spring自动把Body里的数据转成对象
@RequestMapping("/param")
@RestController
public class ParamController {
    @RequestMapping("/m1")
    public String m1(@RequestBody Person person){
        return "收到的对象是:" + person.toString();
    }
}

在这里插入图片描述

三、相关的其他请求操作

3.1 获取URL中的参数 @PathVariable

  1. 获取一个URL
    在这里插入图片描述
  2. 可以获取多个URL,但要注意顺序:因为对于URL来说,他并不知道这些值有什么作用,它只会按照顺序放,不会一一对应
@RequestMapping("/param")
@RestController
public class ParamController {
    @RequestMapping("/m2/{userId}/{userName}")
    public String m2(@PathVariable Integer userId, @PathVariable String userName){
        return "接受到的userId为:" + userId + ", userName为:" + userName;
    }
}
  1. 请求格式必须要和后端定义的URL格式,不一致会报错
  2. 关于改名
@RequestMapping("/param")
@RestController
public class ParamController {
    @RequestMapping("/m2/{id}/{userName}")
    public String m2(@PathVariable("id") Integer userId, @PathVariable String userName){
        return "接受到的id为:" + userId + ", userName为:" + userName;
    }
}

3.2 上传文件 @RequestPart

  1. 如何上传:使用MultipartFile类接收文件 + @RequestPart 注解 + form-data式发送
    • 关于 MultipartFile类:可以接收各种文件,此处我们不用File类
    • 关于 form-data:以表单的形式传输二进制数据,而文件底层就是一大串二进制数据
@RequestMapping("/param")
@RestController
public class ParamController {
    @RequestMapping("/m3")
    public String m3(@RequestPart MultipartFile file) throws IOException {
    	//打印传过来的文件名,此处是【普洱.jpg】
        System.out.println(file.getOriginalFilename());
        //将传过来的文件保存在当前机器上,路径为【D:/apply/+file.getOriginalFilename()】
        file.transferTo(new File("D:/apply/" + file.getOriginalFilename()));
        return "success";
    }
}

在这里插入图片描述

3.3 获取和设置 Cookie/Session

Cookie和Session相关概念

结合这个理解

  1. 为什么会有Cookie和Session
    • (1)HTTP是无状态的,即没有记忆功能,现在请求和过一会请求,同样的请求参数只会执行同样的处理逻辑。
    • (2)这就意味着,哪怕访问的是一个频繁访问的路径,我们也需要反复登录
    • (3)但有时候,我们需要让我们的服务有记忆功能,Cookie和Session就可以满足这个需求
  2. Cookie可以伪造,Session不行
  3. Cookie 和 Session 都是会话机制
    • 什么是会话机制:会话即对话
      在这里插入图片描述

获取 + 设置 Cookie

这是获取

  1. 使用Servlet原生的API获取可以获取到所有的Cookie
    • 为何能使用:因为Spring 是基于Servlet封装的,所以Servlet能用的,他都能用
    • HttpServletRequest和HttpServletResponse:都是Spring的内置对象,可以两个都加上,也可以只放一个,根据需求来
    • 为何要伪造Cookie:如果此时没有Cookie,cookies就会为null,后面更是会空指针异常。所以在没有Cookie的情况下,我们如果要测试该代码,需要伪造Cookie。
@RequestMapping("/param")
@RestController
public class ParamController {
    @RequestMapping("/getCookie")
    public String getCookie(HttpServletRequest request, HttpServletResponse response){
        Cookie[] cookies = request.getCookies();

        //使用lambda表达式进行循环
        Arrays.stream(cookies).forEach(cookie -> {
            System.out.println(cookie.getName() + ":" + cookie.getValue());
        });

        return "success";
    }
}
  1. 使用@CookieValue注解获取只能获取到指定的Cookie
@RequestMapping("/param")
@RestController
public class ParamController {
    @RequestMapping("/getCookie")
    public String getCookie(@CookieValue String name, @CookieValue Integer age){ 
    	//可以放置多个参数 
        return "Cookie存储的name为" + name;
    }
}

这是伪造Cookie

在这里插入图片描述
在这里插入图片描述

获取 + 设置Session

获取

  1. 使用内置对象 HttpServletRequest
@RequestMapping("/param")
@RestController
public class ParamController {
    @RequestMapping("/getSession")
    public String getSession(HttpServletRequest request){
        HttpSession session = request.getSession(false);  //默认值为true
        if (session != null){
            String username = (String)session.getAttribute("username");
            return "登录用户:" + username;
        }

        return "session 为空";
    }
}
  1. 使用内置对象 HttpSession
    • 对 HttpSession session 的理解:相当于第一种方法的【request.getSession(true)】
@RequestMapping("/param")
@RestController
public class ParamController {
    @RequestMapping("/getSession")
    public String getSession(HttpSession session){
        String username = (String)session.getAttribute("username");
        return "username为:" + username;
    }
}
  1. 使用 @SessionAttribute 注解
    • 注意该参数变成了必传的:该注解的内部定义
      在这里插入图片描述
@RequestMapping("/param")
@RestController
public class ParamController {
    @RequestMapping("/getSession")
    public String getSession(@SessionAttribute String username){
        return "session中存储的username为:" + username;
    }
}

设置

  1. 通过Servlet方法设置:因为Session是服务端的,我们没有办法进行伪造,所以只能通过后端代码创建
@RequestMapping("/param")
@RestController
public class ParamController {
    @RequestMapping("/setSession")
    public String setSession(HttpServletRequest request){
        HttpSession session = request.getSession();
        session.setAttribute("username", "zhangsan");
        return "success";
    }
}

在这里插入图片描述

3.4 获取Header

  1. 使用内置对象HttpServletRequest
@RequestMapping("/param")
@RestController
public class ParamController {
    @RequestMapping("/getHeader")
    public String getHeader(HttpServletRequest request){
        //获取Header中某个key的值
        String userAgent = request.getHeader("User-Agent");
        return "userAgent:" + userAgent;
    }
}
  1. 使用@RequestHeader注解
    在这里插入图片描述

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

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

相关文章

Golang | Leetcode Golang题解之第92题反转链表II

题目&#xff1a; 题解&#xff1a; func reverseBetween(head *ListNode, left, right int) *ListNode {// 设置 dummyNode 是这一类问题的一般做法dummyNode : &ListNode{Val: -1}dummyNode.Next headpre : dummyNodefor i : 0; i < left-1; i {pre pre.Next}cur :…

Dubbo配置上的一些概念

对于dubbo在spring中我们可能看到有如下配置&#xff08;可参考Schema 配置参考手册 | Apache Dubbo&#xff09;&#xff1a; dubbo:application:id: dubbo-account-examplename: dubbo-account-example# 是否启用 Dubbo 的 QoS&#xff08;Quality of Service&#xff09;服…

什么是趋肤效应

很多同行来问什么是趋肤效应&#xff0c;趋肤效应应该是附在表面&#xff0c;为什么变成了附在线路横截面的底面&#xff1f;下面就和小易&#xff0c;一起具体了解下趋肤效应。 趋肤效应也称集肤效应&#xff0c;英文术语是Skin effection,它是指在电流流过导体时&#xff0c;…

DOS学习-目录与文件应用操作经典案例-cd

欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一.前言 二.案例 三.练习 一.前言 虽然Windows 2000/XP/2003系统已经不再使用纯DOS平台&#xff0c;但它们内建了一个功能强大的命令行界面。在这个界面中&#xff0c;用户可以像在Wind…

2024.05.15学习记录

1、完成Ts重构Axios项目中更多功能的开发 2、刷题&#xff1a;二叉树&#xff08;代码回忆录&#xff09; 3、复习diff算法源码解读

在k8s中搭建elasticsearch高可用集群,并对数据进行持久化存储

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《洞察之眼&#xff1a;ELK监控与可视化》&#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、Elasticsearch简介 2、k8s简介 二、环境准备 …

k8s概述及核心组件

一、k8s概述 1.1 引言 docker compose 单机编排工具 有企业在用 docker swarm 能够在多台主机中构建一个docker集群 基本淘汰集群化管理处理工具 容器 微服务封装 dockerfile 编写成镜像 然后进行发布 dockerfile 可以写成shell脚本&#xff08;函数做调…

xmzs切换镜像源

1.全局安装 npm install xmzs -g 2.mmp ls 查看镜像源 3.mmp use 选择镜像源

CTF网络安全大赛web题目:just_sqli

这道题目是bugku的web题目 题目的 描  述: KosenCTF{} 原文链接&#xff1a; CTF网络安全大赛web题目&#xff1a;just_sqli - 红客网-网络安全与渗透技术 题目Web源代码&#xff1a; <?php$user NULL; $is_admin 0;if (isset($_GET["source"])) {highlig…

Spring实现数据库读写分离(MySQL实现主从复制)

目录 1、背景 2、方案 2.1 应用层解决: 2.2 中间件解决 3、使用Spring基于应用层实现 3.1 原理 3.2 DynamicDataSource 3.3 DynamicDataSourceHolder 3.4 DataSourceAspect 3.5 配置2个数据源 3.5.1 jdbc.properties 3.5.2 定义连接池 3.5.2 定义DataSource 3.6…

企业微信hook接口协议,ipad协议http,大文件网络上传

大文件网络上传 参数名必选类型说明url是String网络图片地址 请求示例 {"uuid":"2b0863724106a1160212bd1ccf025295","authkey":"0AAxxx031", "filekey":"346b7bff-08d5-4ac2-bc67-fd10e3eb2388", "fileur…

恒创科技:域名CNAME解析和A记录解析有哪些区别?

​  域名是互联网上的一种地址&#xff0c;是用以替代复杂IP地址的字符标识&#xff0c;在进行域名解析时&#xff0c;主要有两种常见的记录类型&#xff1a;CNAME 记录和 A记录解析。今天就给大家讲下CNAME解析和A记录解析有哪些区别、优势。这里&#xff0c;我们先了解下什…

2024年代理!武汉重点实验室申报条件、奖励补贴

2024年武汉重点实验室申报条件、奖励补贴的想想内容整理如下&#xff0c;江岸区、江汉区、硚口区、汉阳区、武昌区、青山区、洪山区、蔡甸区、江夏区、黄陂区、新洲区、东西湖区、汉南区、武汉经开区、东湖高新区企业申报重点实验室有不明白的可了解&#xff1a; 武汉重点实验室…

【Leetcode每日一题】 综合练习 - 括号生成(难度⭐⭐)(76)

1. 题目解析 题目链接&#xff1a;22. 括号生成 这个问题的理解其实相当简单&#xff0c;只需看一下示例&#xff0c;基本就能明白其含义了。 2.算法原理 问题描述 我们需要找出所有可能的、有效的括号序列。一个有效的括号序列指的是一个仅由(和)组成的字符串&#xff0c;…

高效协同,智慧绘制:革新型流程图工具全解析

流程图&#xff0c;作为一种直观展示工作过程和系统运作的工具&#xff0c;在现代办公和项目管理中发挥着不可或缺的作用。 其优势在于能够清晰、直观地呈现复杂的过程和关系&#xff0c;帮助人们快速理解并掌握关键信息。同时&#xff0c;流程图也广泛应用于各种场景&#xf…

C++ static_cast学习

static_cast可实现&#xff0c; 1 基本类型之间的转换 2 void指针转换为任意基本类型的指针 3 用于有继承关系的子类与父类之间的指针或引用的转换 用于基本类型转化时&#xff0c;会损失精度类似于C语言的强制转化&#xff1b; 下面先看一下void指针的转换&#xff1b; …

cpu卡片详解(FM1208)

​ 目录 ​1. 引言 1.1 FM1208 CPU卡芯片 2. FM1208 CPU卡芯片概述 2.1 FM1208及其在智能卡中的作用 2.2 FM1208功能框图 3.FM1208的技术规格 4.FM1208工作流程 5.&#xff26;&#xff2d;1208文件结构 6.FM1208与其他智能卡技术的比较 7.FM1208安全特性 7.1 DES/…

哈希表法快速求解最长连续序列 | 力扣128题详细解析

❤️❤️❤️ 欢迎来到我的博客。希望您能在这里找到既有价值又有趣的内容&#xff0c;和我一起探索、学习和成长。欢迎评论区畅所欲言、享受知识的乐趣&#xff01; 推荐&#xff1a;数据分析螺丝钉的首页 格物致知 终身学习 期待您的关注 导航&#xff1a; LeetCode解锁100…

美团小程序mtgsig1.2逆向

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01;wx a15018601872 本文章未…

HarmonyOS ArkTS 实现类似Android中RadioButton得效果

在Android中如实现下图可以用radioGroup和RadioButton实现&#xff0c;但在ArkTs中radio不能实现自定义样式&#xff0c;所以用Tabs来实现这种效果&#xff0c;效果图如下&#xff1a; 一、效果图 二、实现横向布局的三个TabContent&#xff0c;代码如下 State currentIndex: n…