Spring Web MVC项目的创建及使用

一、什么是Spring Web MVC?

  Spring Web MVC 是基于 Servlet API 构建的原始 Web 框架,从⼀开始就包含在 Spring 框架中,通常被称为Spring MVC。

1.1 MVC的定义

MVC 是 Model View Controller 的缩写,它是软件工程中的一种软件架构设计模式,它把软件系统分 为模型、视图和控制器三个基本部分  

• View(视图) 指在应用程序中专门用来与浏览器进行交互,展示数据的资源. 
• Model(模型) 是应用程序的主体部分,用来处理程序中数据逻辑的部分. 
• Controller(控制器)可以理解为一个分发器,用来决定对于视图发来的请求,需要用哪一个模型
来处理,以及处理完后需要跳回到哪一个视图。即用来连接视图和模型 


1.2 什么是Spring MVC?

总的来说:Spring MVC就是一个实现了MVC模式的Web框架

其实,在前面学习创建Spring Boot项目时,勾选的Spring Web框架其实就是Spring Web MVC框架:

可能有人会有疑问:为什么创建的是Spring Boot项目,又会创建了一个Spring MVC项目?其实,Spring Boot是实现Spring MVC的一种方式,Spring Boot可以添加多种依赖,通过不同的依赖实现不同的功能,Spring Boot正是通过添加Spring Web依赖来实现Web功能的。

Spring在实现MVC时,也做出了一些改变:

不过现在,我们在创建Spring MVC项目时已经不处理视图相关的问题了,这些问题一般交由前端人员进行处理。


二、练习Spring MVC

Spring MVC是一个Web框架,当用户在浏览器输入url后,Spring MVC可以感知到用户发送的请求并返回响应,因此,学习Spring MVC主要学习以下三个方面:

<1>建立连接:将用户(浏览器)和 Java 程序连接起来,也就是访问一个地址能够用到我们的 Spring 程序。 

<2>请求 :用户请求的时候会带一些参数,在程序中要想办法获取到参数, 所以请求这块主要是获取参数的功能. 

<3>响应: 执行了业务逻辑之后,要把程序执行的结果返回给用户, 也就是响应. 

2.1 创建Spring MVC项目

创建Spring MVC项目的方法与前面创建Spring Boot显目的方法一样:只需勾选上Spring Web依赖即可

 


2.2 建立连接 

在 Spring MVC 中使用 @RequestMapping 来实现 URL 路由映射 ,也就是浏览器连接程序的作用,在启动类(后缀名为Application)所在目录创建一个UserController类来实现用户通过浏览器和程序的互动:

2.2.1 @RequestMapping注解介绍 

@RequestMapping 是 Spring Web MVC 应用程序中最常被用到的注解之一,它是用来注册接口的路由映射的.
表示服务收到请求时, 路径为 /sayHi 的请求就会调用 sayHi 这个方法的代码.

 

路由映射: 当用户访问⼀个 URL 时, 将用户的请求对应到程序中某个类的某个方法的过程就叫路由映射. 

  既然@RequesMapping这个注解已经可以达到访问的目的,那为什么还要@RestController注解呢?

如果我们去掉@RestController注解,在来访问/sayHi这个路径,会出现如下情况:

可以看到程序报错,找不到该页面,这就是@RestController注解的作用,Spring会对所有的类进行扫描, 如果类加了注解@RestController, Spring才会去看这个类里面的方法
有没有加 @RequestMapping 这个注解
, 这个注解还有更多细节,后面会慢慢了解到,现在我们只需要知道,如果要通过浏览器访问程序的某个方法,那么这个方法所在的类一定要加上@Restcontroller注解


2.2.2 @RequestMapping的使用

 @RequestMapping既可以修饰类,也可以修饰方法,当修饰类和方法时,访问的地址为类路径+方法路径。

 

@RequestMapping标识⼀个类:设置映射请求的请求路径的初始信息 
@RequestMapping标识⼀个方法:设置映射请求请求路径的具体信息 

!!!@RequestMapping中的URL路径可以是多重路径,如果是多重路径,路径中的 / 一定不能省略,如果不是则可以省略。


2.2.3 @RequestMapping是GET请求还是POST请求? 

<1>GET请求:通过浏览器发送的请求都是GET请求,因此@RequestMapping支持GET请求

 

<2>POST请求:我们可以通过form表单来构造请求:

接下来通过浏览器访问test.html,并点击提交:

可以看到,@RequestMapping也支持post请求。

那么,如何指定请求类型?

<1>通过@RequestMapping的method属性设置;

<2>将@RequestMapping注解改为@GetMapping或@PostMapping或其它(以此类推)

如图:

 我们发现,如果想要通过其它请求方式访问我们的代码,就需要通过编写前端代码来实现,非常麻烦,这里推荐使用Postman来发送请求,它可以指定任意请求方式,如有疑问,可参考如下文章:最简单最适合纯小白的postman使用方法(测试接口的不二利器)(从介绍到下载到使用的详细教程)_postman连接java后端-CSDN博客


2.3 请求

2.3.1 传递单个参数

接下来,使用Postman发送请求:

可以看到,getInt的类型为包装类,其实也可以使用普通类型来接收,但是如果此时传递来的参数是null,那么将会报错,如:

而包装类,则不会出现这种情况:

因此,使用基本类型来接收参数时,接收的参数一定不能为null,且使用基本类型接收参数,这个参数必传,否则也会报错,参数类型不匹配,也会报错(相当于接收参数为null)。


2.4.2  传递多个参数

传递多个参数与传递单个参数类似,直接使用多个形参接收即可:

需要注意的是,当有多个参数时,前后端进行参数匹配时,是以参数的名称进行匹配的,因此参数的位置是不影响后端获取参数的结果.


2.4.3 传递对象

<1> 先创建一个类

<2> 创建一个UserInfo对象,用于接收参数

<3>在Postman中传参,传参方式和传递多个参数一样

当需要传递的参数个数很多时,就可以改为使用对象来接收


2.4.4 后端参数重命名

某些特殊的情况下,前端传递的参数 key 和我们后端接收的 key 可以不⼀致,比如前端传递了⼀个 time 给后端,而后端是使用 createtime 字段来接收的,这样就会出现参数接收不到的情况,如果出现这种情况,我们就可以使⽤ @RequestParam 来重命名前后端的参数值 ,如:

在形参前面加上@RequestParam注解,并在注解中写入一个属性 “q“ ,表示前端传递过来的参数q的值,将会被keyWord接收:

同时,此时的 q 默认为一个必传参数,如果不传将会报错:

如果想要将 q 设置为非必传参数,可以将@RequestParama中的属性requird置为false即可


 2.4.5 传递数组

Spring MVC可以自动绑定数组的赋值,故可以直接使用数组接收


2.4.6 传递集合

Spring MVC不可以自动绑定集合的赋值,如果需要传递集合,需要使用@RequestParama注解进行参数绑定。 

接下来在Postman进行传参即可:

如果不加@RequestMapping注解,将会报错:


2.4.7 传递Json对象

传递Json对象需要使用@RequestBody注解,它能够将传递过来的Josn数据转换为相应的对象

 接下来在Postman中传递Json数据:

如果不使用@RequestBody注解,赋值不会成功:


2.4.8 获取URL中参数@PathVariable 

获取url上的参数需要使用@PathVariable注解,这个注解主要作用在请求url路径上的数据绑定

在Postman中发送请求:

参数对应关系如下:


2.4.9 上传文件@RequestPart

使用Postman发送请求:

然后观察相应路径,看是否上传成功即可


2.4.10 获取Cookie/Session

一、Cookie

由于HTTP属于“无状态”协议(两次通信之间没有直接联系),但是在实际开发中,需要知道两次请求之间的关系(如登录某个网站后,下一次访问服务器能知道这次的请求是否已经登录过了)

图中的令牌通常就存储在Cookie中

此时在服务器这边就需要记录"令牌"信息, 以及令牌对应的用户信息, 这个就是 Session 机制所做的工作.


二、Session

Session表示一个会话(客户与服务器之间的不中断的请求响应),它是服务器用来区分不同的请求属于哪个会话的,是服务器为了保存用户信息而创建的⼀个特殊的对象。

Session的本质是一个“哈希表”,Key就是SessionId,value就是保存的用户信息

 

 

 

上图中对应的流程如下:


三、Session和Cookie的区别

<1>Cookie是客户端保存用户信息的一种机制,Session是服务器保存用户信息的一种机制

<2>Cookie和Session通过SessionId关联起来

<3>Cookie和Session通常在一起使用,但并不一定:

       1. Cookie可以用来保存其它数据,不一定是用户身份信息和SessionId

       2.SessionId也不一定通过Set-Cookie传递给Cookie,也可以通过URL传递


四、获取Cookie

<1>传统方式获取Cookie

如果想要获取HTTP请求中的任何数据,都可以使用HttpServletRequest这个类创建的对象来获取,如:

接下来在浏览器中访问:

由于现在Cooike中还没有值,因此控制台没有输出相关信息:

接下来,通过F12手动添加一个Cookie:

手动添加后,刷新页面查看idea控制台,此时Cookie的值已被打印

!!!可以看到,Cookie是可以伪造的,因此在后端使用Cookie时,需要进行校验

 

<2>通过注解@CookieValue获取Cookie

通过浏览器访问:

通过注解可以更简单地获取到Cookie的值,但是缺点是一次只能获取一个Cookie(一次请求携带的Cookie可能有多个)


五、Session的存储

Session时服务端的机制,需要先存储,才能获取

getSession方法带有一个布尔类型的参数,默认情况下为true,表示如果没有Session对象,就会创建一个空的Session对象,如果改为false,则没有Session的情况下会返回null,通过Session对象的setAttribute保存用户信息。


六、Session的获取

<1>通过HttpServletRequest获取

getSession是通过SessionId来获取Session的,因此需要先通过访问setSession方法存储Session,再访问getSession方法,其对应的具体流程为:

(1)首次创建会话时(即通过setSession的getSession方法获取到session对象),服务器会生成JSESSIONID并通过Set-Cookie发送给客户端

(2)客户端在后续请求中通过Cookie字段发送JSESSIONID;

(3)服务器通过JSESSIONID找到对应的HttpSession对象,供getSession方法使用。

 

现在先通过浏览器访问setSession方法,通过F2观察:

可以看到,SessionId已经通过Set-Cookie保存到Cookie中了,接下来通过浏览器访问getSession方法:

成功获取到用户信息,如果不先调用setSession方法,返回用户未登录:

 

<2>通过HttpSession获取Session

 

<3>通过注解获取Session


 2.4.11 获取Header

<1>通过HttpServletRequest获取

同理,也可以通过getHeader获取到Header中的Content-Length、Content-Type等属性。

通过Postman访问getHeader方法:

 

<2>通过注解获取Header


2.4 响应

在前面的请求代码中,也已经设置了响应数据, 响应结果可以是数据, 也可以是静态页面,也可
以针对响应设置状态码, Header信息等。

2.4.1 返回静态页面

(1)首先,在static文件夹中创建index.html文件

(2)编写后端代码

(3)在浏览器中访问

可以看到,成功返回了一个页面。

但是在这里有几个需要注意的问题:

<1>一般后端代码中返回的页面的路劲最前面需要加上“ / ”,前端一般不加

<2>如果后端返回的是一个页面,需要将注解@RestController改为@Controller,因为@RestController表示返回结果是数据,@Controller表示返回结果是页面,如果在上面的代码中还是使用@RestController注解的话,那么会将"/index.html"解析为数据,如:

<3>如果类注解使用了@Controller,而类中有一个方法需要返回数据,可以在方法前加上注解@ResponseBody,可以理解为@RestController包含了@Controller和@responseBody两个注解。

 

!!!到了现在Spring MVC已经不再返回视图,而是返回显示视图需要的数据,将返回视图的任务交由前端完成。


 2.4.2 返回数据@ResponseBody

这里的类注解为Controller,故方法前需要加上注解@ResponseBody表示返回数据

如果不加@ResponseBody,会报404

 

!!!@ResponseBody 既是类注解, 又是方法注解 如果作用在类上, 表示该类的所有方法, 返回的都是数据, 如果作用在方法上, 表示该方法返回的是数据. 


2.4.3 返回HTML代码片段

在返回的数据中,如果又HTML代码片段,会被浏览器解析

在浏览器访问:

通过Fiddler抓包观察,发现Content-Type的类型为text/html,表示响应Body中的数据格式为HTML

如果不想返回结果被解析为HTML,可以通过@RequestMapping的produces属性将Content-Type修改为text/plain,如:

通过浏览器访问:

再次通过Fillder抓包:

可以看到Content-Type已被修改


2.4.4 返回JSON 

HTTP协议不支持直接传输Java对象或List等,如果后端返回了Java对象或List,就会转换为JSON,如:

通过Postman访问:


2.4.5 设置状态码 

通过HttpServletResponse修改状态码:

通过浏览器访问:

使用Fiddler抓包并观察:

虽然请求成功的状态码一般默认为200,但是后端人员也可以将其设置为404,但是并不符合人HTTP规范


2.4.6 设置Header

<1>设置Content-type 

前面已近提到,可以通过@RequestMapping注解的produces属性进行修改

<2>自定义Header片段

使用HttpServletResponse对象进行修改

通过浏览器访问并使用Fiddler抓包观察:

成功在Header中添加新的字段

 

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

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

相关文章

oracle:索引(B树索引,位图索引,分区索引,主键索引,唯一索引,联合索引/组合索引,函数索引)

索引通过存储列的排序值来加快对表中数据的访问速度&#xff0c;帮助数据库系统快速定位到所需数据&#xff0c;避免全表扫描 B树索引(B-Tree Index) B树索引是一种平衡树结构&#xff0c;适合处理范围查询和精确查找。它的设计目标是保持数据有序&#xff0c;并支持高效的插入…

android 适配 api 35(android 15) 遇到的问题

首先升级 targetSdkVersion 和 compileSdkVersion 到 35&#xff0c;升级后发生的报错 一、 解决方案: 升级 gradle 和 gradle 插件版本 com.android.tools.build:gradle -> 8.3.0-alpha02 gradle-wrapper.properties : distributionUrl -> gradle-8.6-bin.zip htt…

@Value属性读取系统变量错误

Value属性读取配置属性错误 场景 在测试Value读取yml配置文件属性时&#xff0c;发现系统配置属性优先级高于配置文件&#xff0c;导致注入异常值&#xff1a; 配置文件: user:name: yanxin测试类: RestController RequestMapping("/books") public class BookC…

BFS算法——广度优先搜索,探索未知的旅程(下)

文章目录 前言一. N叉树的层序遍历1.1 题目链接&#xff1a;https://leetcode.cn/problems/n-ary-tree-level-order-traversal/description/1.2 题目分析&#xff1a;1.3 思路讲解&#xff1a;1.4 代码实现&#xff1a; 二. 二叉树的锯齿形层序遍历2.1 题目链接&#xff1a;htt…

【Ubuntu】ARM交叉编译开发环境解决“没有那个文件或目录”问题

【Ubuntu】ARM交叉编译开发环境解决“没有那个文件或目录”问题 零、起因 最近在使用Ubuntu虚拟机编译ARM程序&#xff0c;解压ARM的GCC后想要启动&#xff0c;报“没有那个文件或目录”&#xff0c;但是文件确实存在&#xff0c;环境配置也检查过了没问题&#xff0c;本文记…

清理服务器/docker容器

清理服务器 服务器或docker容器清理空间。 清理conda环境 删除不用的conda虚拟环境&#xff1a; conda env remove --name python38 conda env remove --name python310清理临时目录&#xff1a;/tmp du -sh /tmp # 查看/tmp目录的大小/tmp 目录下的文件通常是可以直接删除…

康谋方案 | BEV感知技术:多相机数据采集与高精度时间同步方案

随着自动驾驶技术的快速发展&#xff0c;车辆准确感知周围环境的能力变得至关重要。BEV&#xff08;Birds-Eye-View&#xff0c;鸟瞰图&#xff09;感知技术&#xff0c;以其独特的视角和强大的数据处理能力&#xff0c;正成为自动驾驶领域的一大研究热点。 一、BEV感知技术概…

HarmonyOS 5.0应用开发——ContentSlot的使用

【高心星出品】 文章目录 ContentSlot的使用使用方法案例运行结果 完整代码 ContentSlot的使用 用于渲染并管理Native层使用C-API创建的组件同时也支持ArkTS创建的NodeContent对象。 支持混合模式开发&#xff0c;当容器是ArkTS组件&#xff0c;子组件在Native侧创建时&#…

脚本一键生成管理下游k8s集群的kubeconfig

一、场景 1.1 需要管理下游k8s集群的场景。 1.2 不希望使用默认的cluster-admin权限的config. 二、脚本 **重点参数&#xff1a; 2.1 配置变量。 1、有单独namespace的权限和集群只读权限。 2、自签名的CA证书位置要正确。 2.2 如果配置错误&#xff0c;需要重新…

windows安装linux子系统【ubuntu】操作步骤

1.在windows系统中开启【适用于Linux的Windows子系统】 控制面板—程序—程序和功能—启用或关闭Windows功能—勾选适用于Linux的Windows子系统–确定 2.下载安装Linux Ubuntu 22.04.5 LTS系统 Ununtu下载链接 3.安装完Ununtu系统后更新系统 sudo apt update4.进入/usr/l…

LabVIEW自定义测量参数怎么设置?

以下通过一个温度采集案例&#xff0c;说明在 LabVIEW 中设置自定义测量参数的具体方法&#xff1a; 案例背景 ​ 假设使用 NI USB-6009 数据采集卡 和 热电偶传感器 监测温度&#xff0c;需自定义以下参数&#xff1a; 采样率&#xff1a;1 kHz 输入量程&#xff1a;0~10 V&a…

老游戏回顾:G2

一个老的RPG游戏。 剧情有独到之处。 ------- 遥远的过去&#xff0c;古拉纳斯将希望之光给予人们&#xff0c;人类令希望之光不断扩大&#xff0c;将繁荣握在手中。 但是&#xff0c;暗之恶魔巴鲁玛将光从人类身上夺走。古拉纳斯为了守护人类与其展开了一场激战&#xff0c…

DeepSeek R1 Distill Llama 70B(免费版)API使用详解

DeepSeek R1 Distill Llama 70B&#xff08;免费版&#xff09;API使用详解 在人工智能领域&#xff0c;随着技术的不断进步&#xff0c;各种新的模型和应用如雨后春笋般涌现。今天&#xff0c;我们要为大家介绍的是OpenRouter平台上提供的DeepSeek R1 Distill Llama 70B&…

【LeetCode: 887. 鸡蛋掉落 + 递归 + 二分 + dp】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

学习 PostgreSQL 流复制

PostgreSQL 流复制 PostgreSQL数据库异常中止后&#xff0c;数据库刚重启时&#xff0c;会重放停机前最后一个checkpoint点之后的 WAL日志&#xff0c;在把数据库恢复到停机的状态后&#xff0c;自动进入正常的状态&#xff0c;可以接收其他用户的查询和修改。 想象另一个场景…

LabVIEW位移测量系统

本文介绍了一种基于LabVIEW的位移测量系统&#xff0c;结合先进的硬件设备与LabVIEW平台的强大功能&#xff0c;能够实现对位移的精确测量和高效数据处理。该系统具备高精度、实时性和良好的可扩展性&#xff0c;适用于工程与科学实验中对位移测量的多种需求。 项目背景 位移…

Qt+海康虚拟相机的调试

做机器视觉项目的时候&#xff0c;在没有相机或需要把现场采集的图片在本地跑一下做测试时&#xff0c;可以使用海康的虚拟相机调试。以下是设置步骤&#xff1a; 1.安装好海康MVS软件&#xff0c;在菜单栏->工具选择虚拟相机工具&#xff0c;如下图&#xff1a; 2.打开虚拟…

数据结构【链式队列】

基于链式存储结构的队列实现与分析 一、引言 队列作为一种重要的数据结构&#xff0c;在计算机科学的众多领域有着广泛应用&#xff0c;如操作系统中的任务调度、网络通信中的数据缓冲等。本文通过C 代码实现了一个基于链式存储结构的队列&#xff0c;并对其进行详细解析。 …

路由器如何进行数据包转发?

路由器进行数据包转发的过程是网络通信的核心之一&#xff0c;主要涉及以下几个步骤&#xff1a; 接收数据包&#xff1a;当一个数据包到达路由器的一个接口时&#xff0c;它首先被暂时存储在该接口的缓冲区中。 解析目标地址&#xff1a;路由器会检查数据包中的目标IP地址。…

大数据sql查询速度慢有哪些原因

1.索引问题 可能缺少索引&#xff0c;也有可能是索引不生效 2.连接数配置&#xff1a;连接数过少/连接池比较小 连接数过 3.sql本身有问题&#xff0c;响应比较慢&#xff0c;比如多表 4.数据量比较大 -这种最好采用分表设计 或分批查询 5.缓存池大小 可能是缓存问题&#xff…