【Spring】详解SpringMVC,一篇文章带你快速入门

news2024/12/23 15:12:00

目录

一、初始MVC

二、SpringMVC

三、Spring MVC的运用

⭕@RequestMapping

⭕传递参数

1、传递单个参数 

2、传递多个参数

3、参数重命名

4、传递数组与集合

5、获取路径参数

6、传递JSON数据

7、上传文件


一、初始MVC

MVC(Model-View-Controller)是一种软件架构模式,主要用于简化复杂的应用程序开发过程,尤其是在Web应用中。将软件系统分成了模型、视图和控制器三个基本部分

  • 模型(Model)

模型是应用程序中用于处理应用程序数据逻辑的部分。它直接管理数据、逻辑和规则,并且与数据库交互。通常包含业务逻辑和业务数据。

  • 视图(View)

视图是应用程序中处理数据显示的部分。任何可以输出最终用户结果的界面都是视图的一部分。视图负责呈现数据给用户,并且不包含任何业务逻辑。

  • 控制器(Controller)

控制器是应用程序中处理用户交互的部分。它接收用户的输入并调用模型和视图去完成用户的需求。简单来说,控制器就是模型和视图之间的协调者。

一个简单的MVC模式示例:

假设有一个学生管理系统,其中包含学生的姓名、年龄等信息。

  • 模型:定义了学生的属性和方法,如获取学生信息、更新学生信息等。
  • 视图:负责展示学生的详细信息,可能是一个网页表格或者一个对话框。
  • 控制器:处理用户事件(如点击按钮),更新学生信息,并告诉视图重新显示更新后的信息。

二、SpringMVC

Spring MVC 是 Spring 框架的一个模块,专注于Web应用的表示层。它就是基于 MVC 架构模式的实现,用于构建灵活且松耦合的Web应用程序。总的来说,Spring MVC就是一个实现了 MVC 模式,并继承了 Servlet API 的 Web 框架

Spring MVC 全称是 Spring Web MVC

不过Spring在实现MVC时, 也结合⾃⾝项⽬的特点, 做了⼀些改变, 相对⽽⾔, 下⾯这个图或许更加合适⼀些

🌰其实就相当于去饭店吃饭时,直接在 前台 (控制器) 点单 (提出需求),前台 将需求传递给 后厨 (模型),由 后厨负责把菜做好 (处理需求),做好了返回给 前台,再叫 服务员 (视图) 把菜端给客户 (显示结果)

三、Spring MVC的运用

⭕@RequestMapping

@RequestMapping 是 Spring 框架中的一个核心注解,它是⽤来注册接⼝的路由映射的

路由映射(Routing):是指当⽤⼾访问⼀个 URL 时,映射 Web 请求到应用程序中特定的处理类或处理方法上的过程

@RequestMapping 既可修饰类,也可以修饰⽅法 ,当修饰类和⽅法时,访问的地址是类路径 + ⽅法路径
@RequestMapping("/user")
@RestController
public class UserController {
    @RequestMapping("/hello")
    public String say(){
        return "hello, Spring MVC";
    }
}

  • @RequestMappingGET 还是 POST 请求?
让我们用ApiFox测试一下:
发送 GET 请求:
发送 POST 请求:
从测试结果可以看出: 
@RequestMapping 既⽀持 GET 请求,⼜⽀持 POST 请求。同理,也⽀持其他的请求⽅式。可以说这个注解就是一个万金油了,不知道对方会发啥请求,用这个就对了。
  • 不过,在一些需求中,需要指定好用户发送的请求类型。我们也可以通过参数 method 来限定请求类型:
@RequestMapping("/user")
@RestController
public class UserController {
    @RequestMapping(value="/hello",method = RequestMethod.POST)
    public String say(){
        return "hello, Spring MVC";
    }
}

这时在发送 GET 请求就会 出现错误:

这里报了个 405 的错误,错误原因是 “Method Not Allowed”,也就是 方法不支持,其实就是服务端没有能处理这个 GET 请求的方法。

遇到错误不要慌,我们今后还会遇到各种各样的错误的,多遇到几次,熟悉熟悉就好了😁

Spring 还提供了 @PostMapping()、@GETMapping()、@PUTMapping()、@DELETEMapping()方法注解,用来针对某一应用场景。实际开发中使用 @RequestMapping 还是其它注解功能上其实没啥区别,还是看具体的公司规范个人习惯来选择使用


⭕传递参数

1、传递单个参数 
接收单个参数, 在 Spring MVC 中直接⽤⽅法中的参数就可以,⽐如以下代码:
@RequestMapping("/user")
@RestController
public class UserController {
    @RequestMapping("/hello")
    public String say(String name){
        return "hello, "+name;
    }
}

可以看到,后端程序正确拿到了name参数的值。
Spring MVC 会根据⽅法的参数名, 找到对应的参数, 赋值给⽅法

如果参数不一致就会出现,就会导致无法获取参数:

注意:

  • 如果采用包装类型接收参数时,如果不传参数的话,由于包装类型会有初始值,所以并不会出现报错,而是会返回默认的 null值
  • 如果采用基本类型来接收参数时,如果不穿参数的话(boolean 类型除外),就会报500错误。因为基本类型没有被初始化。

让我们看看下面这个代码:

@RequestMapping("/user")
@RestController
public class UserController {
    @RequestMapping("/age")
    public String age(int age){
        return "age: "+age;
    }
}

正常传参:

程序正常响应,HTTP响应状态码为200

不传参:

程序发送错误,HTTP状态码为500

传递错误参数:

程序发生错误,这里要的是int型参数,但传来的确是字符串,类型不匹配。HTTP状态码为400

  • 因此在实际开发中,对于参数可能为空的数据,还是建议用包装类型,相对没那么容易出错。
2、传递多个参数
  • 直接使用多个形参接收:
@RequestMapping("/user")
@RestController
public class UserController {
    public String login(String username,String password){
        return "username: "+username+"  password: "+password;
    }
}

注意:

这里路径上参数的顺序并不用和服务端一一对应,主要是采用键值对的形式,一参数的名称进行匹配的,参数的顺序并不会影响后端获取参数。

不过,与单个参数时类似,路径上参数的名字必须与后端方法中的形参名称保持一致,程序才能正确读写。不写或错写都会导致后端无法正常匹配参数。

同样的,如果参数里有基本类型但没有成功接收参数,就会出现 400 错误,如果是包装类型参数未接收就会为默认的 null值,这里就不做演示了。

  • 采用对象传参

如果参数比较多,就需要在方法声明中协议很多形参,这对代码的书写与维护都是不太友好的。因此,我们可以将这些参数封装成一个对象:

Spring MVC 可以⾃动实现对象参数的赋值,⽐如 User对象:
public class User {
    private String name;
    private String password;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

就可以将形参换为自定义对象了:

@RequestMapping("/user")
@RestController
public class UserController {
    @RequestMapping("/login")
    public String login(User user){
        return user.toString();
    }
}

路径中的参数要与对应类的成员变量名保持一致:

Spring 会根据参数名称⾃动绑定到对象的各个属性上,如果某个属性未传递,则赋值为null(基本类型则赋值为默认初识值,⽐如int类型的属性,会被赋值为0)

3、参数重命名

在一些应用场景中,我们并不希望直接使用前端传来的参数名进行接收,就可以用 @RequestParam(" ") 注解来进行参数的重命名:

@RequestMapping("/user")
@RestController
public class UserController {
    @RequestMapping("/time")
    public String getTime(@RequestParam("time") String createtime){
        return "createtime: "+createtime;
    }
}

正常传参:

同样的,这时传递错误的参数名也会报 400 :

说明使⽤ @RequestParam 进⾏参数重命名时,请求参数只能和 @RequestParam 声明的名称⼀致,才能进⾏参数绑定和赋值

不同的是,此时不传参也会报 400 :

因为这时当形参前加上 @RequestParam() 注解时,该参数会默认变成必传参数,如果不传就会发生错误。

而有的时候业务上该参数可能是一个非必传参数,我们就可以通过设置 @RequestParam 中的required 来进行调整。

  • required默认为 true,表示为必传参数。当把required设置为 false 时,就是非必传参数了:
@RequestMapping("/user")
@RestController
public class UserController {
    @RequestMapping("/time")
    public String getTime(@RequestParam(value="time",required=false) String createtime){
        return "createtime: "+createtime;
    }
}

不传参:

传错参:

这样设置后,即使不传参也不会报 400了。

4、传递数组与集合
Spring MVC 可以⾃动绑定数组参数的赋值:
@RequestMapping("/user")
@RestController
public class UserController {
    @RequestMapping("/array")
    public String getArray(String[] array){
        return Arrays.toString(array);
    }
}

在url上有两种传参方式:

方式一

方式二

类似的,Spring MVC 可以⾃动绑定集合参数的赋值,不过需要通过使⽤ @RequestParam 绑定参数关系:

@RequestMapping("/user")
@RestController
public class UserController {
    @RequestMapping("/list")
    public String getList(@RequestParam List<String> list){
        return "size:"+list.size()+" list:"+list;
    }
}

这样就能像获取数组一样将多个参数名一致的请求自动自动封装成集合类了:

默认情况下,请求中参数名相同的多个值,是封装到数组。如果要封装到集合,要使⽤
@RequestParam 绑定参数关系
5、获取路径参数

所谓路径参数就是指不以键值对的形式直接出现在url中的参数,举个栗子:

上面这个url中的 “1” 就是一个路径参数。让我们先来试试直接接收会发生什么:

@RequestMapping("/user")
@RestController
public class UserController {
    @RequestMapping("/text/{id}")
    public String getId(Integer id){
        return "id:"+id;
    }
}

注意:路径参数的url我们需要用 { } 来包裹起来

我们发现后端并不能够拿到路径参数。我们需要使用 @PathVariable 注解与请求URL路径上的数据绑定:

@RequestMapping("/user")
@RestController
public class UserController {
    @RequestMapping("/text/{id}")
    public String getId(@PathVariable Integer id){
        return "id:"+id;
    }
}

这样就能成功获取路径参数了:

  • 获取多个路径参数:
@RequestMapping("/user")
@RestController
public class UserController {
    @RequestMapping("/text/{id}/{name}")
    public String getId(@PathVariable Integer id,@PathVariable String name){
        return "id:"+id+" name:"+name;
    }  
}

注意:如果后端要获取多个路径参数时,每个参数都会变成必传参数,因为后端无法判别是哪个路径参数没有传递,就会发生错误

6、传递JSON数据
接收JSON对象, 需要使⽤ @RequestBody 注解
RequestBody: 请求正⽂,意思是这个注解作⽤在请求正⽂的数据绑定,请求参数必须在写在请求正⽂中
我们先试试不加 @RequestBody 注解直接接收 JSON 对象会发生什么:
我们会发现后端并不能成功成功读取 JSON 对象。再用Fiddler抓包看看:

我们可以看到,JSON 对象的确成功传过去了。但后端却把  JSON 字符串当成了一个不可拆分的整体,所以这样拿不到传递的参数。

让我们再加上 @RequestBody 注解试试看:

@RequestMapping("/user")
@RestController
public class UserController {
    @RequestMapping("/login")
    public String login(@RequestBody User user){
        return user.toString();
    }
}

由此我们可以得出,当后端需要接收 JSON 对象时,需要在形参前加上 @RequestBody 注解,才能正确接收。
7、上传文件

主要通过 @RequestPart("file") 注解来实现:

@RequestMapping("/user")
@RestController
public class UserController {
    @RequestMapping("/file")
    public String getFile(@RequestPart("file")MultipartFile file) throws IOException {
        //获取文件名称
        String fileName=file.getOriginalFilename();
        //将文件上传至指定路径下
        file.transferTo(new File("D:/picture/"+fileName));
        return "文件名称:"+fileName;
    }
}

可以看到后端成功获取了文件的名称。在去指定路径下看看文件是否上传成功:

注意:如果文件过大就会导致上传失败了


那么本篇文章就到此为止了,如果觉得这篇文章对你有帮助的话,可以点一下关注和点赞来支持作者哦。如果有什么讲的不对的地方欢迎在评论区指出,希望能够和你们一起进步✊

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

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

相关文章

python 深度学习 项目调试 识别数学公式 LaTeX-OCR

起因&#xff0c; 目的: 提取图片中的数学公式。 其实这个项目&#xff0c;我很久之前就做过。 而且,我还录了一个视频: https://www.bilibili.com/video/BV1nD421p7jS/?vd_source198e876d811b3ccea94908fd163c223f 简介: 项目来源: https://github.com/lukas-blecher/La…

MongoDB简单学习

MongoDB 一、基本使用 1.1业务应用场景 传统的关系型数据库&#xff08;如Mysql&#xff09;&#xff0c;在数据库操作的“三高”需求以及对应web2.0的网站需求面前&#xff0c;显得力不从心 三高&#xff1a; High performance - 对数据库高并发读写的要求Huge Storage -…

STM32--基于STM32F103C8T6的OV7670摄像头显示

本文介绍基于STM32F103C8T6实现的OV7670摄像头显示设计&#xff08;完整资源及代码见文末链接&#xff09; 一、简介 本文实现的功能&#xff1a;基于STM32F103C8T6实现的OV7670摄像头模组实时在2.2寸TFT彩屏上显示出来 所需硬件&#xff1a; STM32F103C8T6最小系统板、OV76…

[C++ 11] 列表初始化:轻量级对象initializer_list

C发展历史 C11是C语言的第二个主要版本&#xff0c;也是自C98以来最重要的一次更新。它引入了大量的新特性&#xff0c;标准化了已有的实践&#xff0c;并极大地改进了C程序员可用的抽象能力。在2011年8月12日被ISO正式采纳之前&#xff0c;人们一直使用“C0x”这个名称&#…

10-1.idea中的项目结构,辅助快捷键,模块的操作

idea中的项目结构和辅助快捷键 IDEA中项目结构 首先是创建项目&#xff0c;新建的项目中有子项目&#xff0c;我们可以创建模块 然后在模块中我们可以创建包&#xff0c;在包中的SRC中写我们的源代码&#xff0c;也就是类。 VScode写Java项目 如何你电脑比较卡的话&#…

基于GPT的智能客服落地实践

&#x1f4cd;前言 在日常生活中&#xff0c;「客服」这个角色几乎贯穿着我们生活的方方面面。比如&#xff0c;淘宝买东西时&#xff0c;需要客服帮你解答疑惑。快递丢失时&#xff0c;需要客服帮忙找回。报名参加培训课程时&#xff0c;需要客服帮忙解答更适合的课程…… 基…

RTE 2024 隐藏攻略

大家好&#xff01;想必今年 RTE 大会议程大家都了解得差不多了&#xff0c;这将是一场实时互动和多模态 AI builder 的年度大聚会。 大会开始前&#xff0c;我们邀请了参与大会策划的 RTE 开发者社区和超音速计划的成员们&#xff0c;分享了不同活动的亮点和隐藏攻略。 请收…

InnoDB 存储引擎<一>InnoDB简介与MySQL存储架构及相关数据结构

目录 回顾MySQL架构 InnoDB简介 ​MySQL存储结构 回顾MySQL架构 对MySQL架构图的总结: MySQL服务器是以网络服务的方式对外提供数据库服务的&#xff0c;我们使用的应用程序以及客户端统称为外部程序。 外部程序通过发送网络请求的方式来连接MySQL服务器&#xff0c;这时首先每…

SpringBoot启动报错java.nio.charset.MalformedInputException: Input length =1

启动springboot项目时&#xff0c;出现了以下报错&#xff1a; defaultPattern_IS_UNDEFINEDdefaultPattern_IS_UNDEFINEDdefaultPattern_IS_UNDEFINEDjava.lang.IllegalStateException: Failed to load property source from location classpath:/application-local.yamlat o…

使用pytest单元测试框架执行单元测试

Pytest 是一个功能强大且灵活的 Python 单元测试框架&#xff0c;它使编写、组织和运行测试变得更加简单。以下是 Pytest 的一些主要特点和优点&#xff1a; 简单易用&#xff1a;Pytest 提供了简洁而直观的语法&#xff0c;使编写测试用例变得非常容易。它支持使用 assert 语…

《皮革制作与环保科技》是什么级别的期刊?是正规期刊吗?能评职称吗?

​问题解答 问&#xff1a;《皮革制作与环保科技》是不是核心期刊&#xff1f; 答&#xff1a;不是&#xff0c;是知网收录的正规学术期刊。 问&#xff1a;《皮革制作与环保科技》级别&#xff1f; 答&#xff1a;国家级。主管单位&#xff1a;中国轻工业联合会 …

软考:CORBA架构

CORBA过时了吗 CORBA指南 个人小结&#xff1a; IPC&#xff0c;进程间通信&#xff0c;Socket应用在不同机器之间的通信 RPC是一种技术思想而非一种规范 但站在八九十年代的当口&#xff0c;简单来说&#xff0c;就是我在本地调用了一个函数&#xff0c;或者对象的方法&…

uvm_info、uvm_warning,uvm_error、uvm_fatal

1、warning/error/fatal调试语句 调试语句除了uvm_info&#xff0c;UVM内部根据问题的严重性&#xff08;severity&#xff09;由低到高&#xff0c;还引入了uvm_warning/uvm_error/uvm_fatal。 它们也是UVM预定义的宏&#xff0c;格式跟umv_info很像&#xff0c;只是不再需要…

int main(int argc,char* argv[])详解

#include <stdio.h> //argc 是指命令行输入参数的个数; //argv[]存储了所有的命令行参数, //arg[0]通常指向程序中的可执行文件的文件名。在有些版本的编译器中还包括程序文件所在的路径。 //如:"d:\Production\Software\VC_2005_Test\Win32控制台应用程序\Vc_T…

Kafka-Windows搭建全流程(环境,安装包,编译,消费案例,远程连接,服务自启,可视化工具)

目录 一. Kafka安装包获取 1. 官网地址 2. 百度网盘链接 二. 环境要求 1. Java 运行环境 (1) 对 java 环境变量进行配置 (2) 下载完毕之后进行解压 三. 启动Zookeeper 四. 启动Kafka (1) 修改Conf下的server.properties文件&#xff0c;修改kafka的日志文件路径 (2)…

软件分享丨Marktext 编辑器

Marktext是一款开源免费的Markdown编辑器&#xff0c;它具有简洁优雅的界面设计和强大的功能&#xff0c;支持多种Markdown语法&#xff0c;包括表格、流程图、甘特图、数学公式、代码高亮等。Marktext还支持导出HTML和PDF格式的文档&#xff0c;非常适合需要编写Markdown文档的…

sersync实时同步部署案例

目录 sersync介绍 案例信息 操作步骤 服务端部署 客户端部署 创建存储目录 安装sersync 修改配置文件 启动服务 停止服务 测试 sersync介绍 sersync是一个基于inotifyrsync的实时文件同步工具&#xff0c;通过监控目录的变动达到实时同步的目的。 案例信息 拓扑…

【微软商店平台】如何将exe打包上传微软商店

打开微软合作者中心&#xff1a;https://partner.microsoft.com/en-us/dashboard/home点击App and Games板块可以创建项目。 3. 重新生成包含私钥的自签名证书 运行以下命令&#xff0c;确保生成的证书包含私钥&#xff1a; New-SelfSignedCertificate -Type CodeSigning -Su…

Git的初次使用

一、下载git 找淘宝的镜像去下载比较快 点击这里 二、配置git 1.打开git命令框 2.设置配置 git config --global user.name "你的用名"git config --global user.email "你的邮箱qq.com" 3.制作本地仓库 新建一个文件夹即可&#xff0c;然后在文件夹…

从零开始:构建一个高效的开源管理系统——使用 React 和 Ruoyi-Vue-Plus 的实战指南

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…