一、什么是SpringMVC🍭
官方对于 Spring MVC 的描述是这样的:
Spring Web MVC is the original web framework built on the Servlet API and has been included in the Spring Framework from the very beginning. The formal name, "Spring Web MVC," comes from the name of its source module (spring-webmvc), but it is more commonly known as "Spring MVC".
Spring Web MVC是基于Servlet API的原始Web框架,从一开始就包含在Spring框架中。其正式名称“Spring Web MVC”来自其源模块(Spring -webmvc)的名称,但更常见的名称是“Spring MVC”。
Spring Web MVC :: Spring Framework
从上述官方定义的描述我们可以提取两个关键信息:
- Spring MVC 是⼀个 Web 框架。
- Spring MVC 是基于 Servlet API 构建的。
然而要真正的理解什么是 Spring MVC?我们首先要搞清楚什么是 MVC?
1、什么是MVC?🍉
MVC 是 Model View Controller 的缩写,它是软件⼯程中的⼀种软件架构模式,它把软件系统分为模型、视图和控制器三个基本部分
- Model(模型) 是应用程序中用于处理应⽤程序数据逻辑的部分。通常模型对象负责在数据库中存取数据。
- View(视图) 是应用程序中处理数据显示的部分。通常视图是依据模型数据创建的。
- Controller(控制器) 是应用程序中处理用户交互的部分。通常控制器负责从视图读取数据, 控制用户输入,并向模型发送数据。
2、MVC 和 Spring MVC 的关系🍉
Spring MVC是基于MVC模式的Java Web开发框架,是Spring框架的一部分。Spring MVC提供了一种结构良好的开发模式,使得开发人员能够更好地组织和管理代码。它使用了MVC的概念,将应用程序的逻辑分离为模型、视图和控制器,并提供了一些额外的功能,如请求处理、表单验证、数据绑定等。是⼀个实现了 MVC 模式,并继承了 Servlet API 的 Web 框架,当⽤户在浏览器中输⼊了 url 之后,我们的 Spring MVC 项目就可以感知到用户的请求。
因此,可以说Spring MVC是基于MVC模式的一种实现方式,它将MVC的概念应用于Web开发,并提供了一些与Web开发相关的功能和特性。
二、为什么要学 Spring MVC?🍭
现在绝大部分的 Java 项目都是基于 Spring(或 Spring Boot)的,而 Spring 的核心就是 Spring MVC。也就是说 Spring MVC 是 Spring 框架的核心模块,而 Spring Boot 是 Spring 的脚手架,因此 我们可以推断出,现在市⾯上绝⼤部分的 Java 项目约等于 Spring MVC 项⽬,这是我们要学 Spring MVC 的原因。
SpringMVC的优点:🍓
- 轻量级:Spring MVC是一个轻量级的框架,它只提供了基本的Web开发功能,没有过多的冗余功能,使得应用程序的开发和部署更加高效。
- 灵活性:Spring MVC采用了基于注解的配置方式,使得开发者可以更灵活地定义控制器、请求映射和视图解析等,极大地简化了开发过程。
- 松耦合:Spring MVC采用了MVC设计模式,将应用程序的不同层次分离开来,使得各个模块之间的耦合度降低,提高了代码的可维护性和可测试性。
- 可扩展性:Spring MVC提供了丰富的扩展点和插件机制,开发者可以根据自己的需求进行扩展和定制,满足各种复杂的业务需求。
- 高度集成:Spring MVC与Spring框架紧密集成,可以很容易地与其他Spring组件(如Spring Boot、Spring Security等)进行集成,提供了更完整的解决方案。
- 强大的视图解析能力:Spring MVC提供了多种视图解析器,支持多种视图技术(如JSP、Thymeleaf、Freemarker等),使得开发者可以根据自己的喜好选择合适的视图技术。
- 易于测试:Spring MVC采用了面向接口的编程方式,使得控制器和服务层的代码可以很容易地进行单元测试,提高了代码的质量和稳定性。
在创建 Spring Boot 项⽬时,我们勾选的 Spring Web 框架其实就是 Spring MVC 框架,如下图所示:
简单来说,咱们之所以要学习 Spring MVC 是因为它是⼀切项目的基础,我们以后创建的所有 Spring、Spring Boot 项目基本都是基于 Spring MVC 的。
三、怎么学 Spring MVC?🍭
学习 Spring MVC 我们只需要掌握以下 3 个功能:
- 连接的功能:将用户(浏览器)和 Java 程序连接起来,也就是访问⼀个地址能够调用到我们的 Spring 程序。
- 获取参数的功能:用户访问的时候会带⼀些参数,在程序中要想办法获取到参数。
- 输出数据的功能:执行了业务逻辑之后,要把程序执行的结果返回给用户。
对于 Spring MVC 来说,掌握了以上 3 个功能就相当于掌握了 Spring MVC。
1、Spring MVC 创建和连接🍉
Spring MVC 项目创建和 Spring Boot 创建项目相同(Spring MVC 使用 Spring Boot 的方式创建), 在创建的时候选择 Spring Web 就相当于创建了 Spring MVC 的项目。 在 Spring MVC 中使用 @RequestMapping 来实现 URL 路由映射,也就是浏览器连接程序的作用。
Ⅰ、创建SpringMVC项目🍓
- 使用Maven方式传统的创建SpringMVC(不过这已经是过时的方法)。
- 使用Spring Boot添加Spring Web模块(Spring MVC)。
创建步骤:
创建之后,初始化完成:
接下来,创建⼀个 TextController 类,实现⽤户到 Spring 程序的互联互通,具体实现代码如下:
package com.example.mvcdemo.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; @Controller//让框架启动的时候加载当前类(只有加载的类,别人才能使用[访问]) @ResponseBody//告诉程序我返回的是一个数据而非页面 @RequestMapping("/text")//路由注册 public class TextController { @RequestMapping("/hi")//路由注册 public String sayHi(){ return "Hi,Spring MVC"; } }
运行起来:
也可以使用@RestController代替@Controller+@ResponseBody
package com.example.mvcdemo.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; /*@Controller//让框架启动的时候加载当前类(只有加载的类,别人才能使用[访问]) @ResponseBody//告诉程序我返回的是一个数据而非页面*/ @RestController//@Controller+@ResponseBody @RequestMapping("/text")//路由注册 public class TextController { @RequestMapping("/hi")//路由注册 public String sayHi(){ return "Hi,Spring MVC"; } }
Ⅱ、@RequestMapping 注解介绍🍓
@RequestMapping 是 Spring Web 应用程序中最常被用到的注解之⼀,它是用来注册接口的路由映射的。
路由映射:所谓的路由映射指的是,当⽤户访问⼀个 url 时,将⽤户的请求对应到程序中某个类的某个方法的过程。
@RequestMapping 即可修饰类,也可以修饰方法,当修饰类和方法时,访问的地址是类 + 方法。
@RequestMapping 也可以直接修饰方法,代码实现如下:
package com.example.mvcdemo.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; /*@Controller//让框架启动的时候加载当前类(只有加载的类,别人才能使用[访问]) @ResponseBody//告诉程序我返回的是一个数据而非页面*/ @RestController//@Controller+@ResponseBody /*@RequestMapping("/text")//路由注册*/ public class TextController { @RequestMapping("/hi")//路由注册 public String sayHi(){ return "Hi,Spring MVC"; } }
代码运行:
Ⅲ、@RequestMapping 是 post 还是 get 请求?🍓
我们先在浏览器看一下这是post请求还是get请求?
可以看到这是get请求。
下面使用 PostMan 测试⼀下,默认情况下使用注解 @RequestMapping 是否可以接收 GET 或 POST 请求?
我们测试之后发现在现在版本的@RequestMapping 既支持GET方式的请求有支持PSOT方式的请求。
GET:
POST:
GET方法和POST方法有什么区别🍒
下面这篇文章讲解的十分详细了:
面试突击71:GET 和 POST 有什么区别? - 掘金 (juejin.cn)
指定 GET/POST 方法类型🍒
package com.example.mvcdemo.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; /*@Controller//让框架启动的时候加载当前类(只有加载的类,别人才能使用[访问]) @ResponseBody//告诉程序我返回的是一个数据而非页面*/ @RestController//@Controller+@ResponseBody /*@RequestMapping("/text")//路由注册*/ public class TextController { @RequestMapping(value = "/hi",method= RequestMethod.POST)//路由注册 public String sayHi(){ return "Hi,Spring MVC"; } }
我们打开浏览器发现报错了,难道代码有问题?我们使用Postman看看
GET:
使用GET请求仍然报405,使用POST请求试试,发现可以访问:
这是因为我们设置了方法为POST,即只能使用POST请求去访问。我们的浏览器之前已经看了。它是GET请求。
Ⅳ、@GetMapping 和 PostMapping🍓
get 请求的 3 种写法:🍒
// 写法1 @RequestMapping("/hi") // 写法2 @RequestMapping(value = "/hi",method = RequestMethod.GET) // 写法3 @GetMapping("/hi")
post 请求的 2 种写法:🍒
// 写法1 @RequestMapping(value = "/hi",method = RequestMethod.POST) // 写法2 @PostMapping("/hi")
2、获取参数🍉
Ⅰ、传递单个/多个参数🍓
在 Spring MVC 中可以直接用方法中的参数来实现传参,比如以下代码:
package com.example.mvcdemo.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; /*@Controller//让框架启动的时候加载当前类(只有加载的类,别人才能使用[访问]) @ResponseBody//告诉程序我返回的是一个数据而非页面*/ @RestController//@Controller+@ResponseBody /*@RequestMapping("/text")//路由注册*/ public class TextController { /*@RequestMapping(value = "/hi",method= RequestMethod.POST)//路由注册*/ /*@PostMapping("/hi")*/ @GetMapping("/hi") public String sayHi(String name){ return "Hi"+name; } }
不加参数,直接输出null
添加name参数,输出:Hi 张三
浏览器也是一样:
如果我们参数名错误(不同)则传递不成功:
如果我们传递了多个参数,其中有所需要的(参数名字相同),那它会自动匹配:
多个参数也是一样传递,而且我们通过上面,也发现了参数的顺序并不影响参数的传递。
总结说明:当有多个参数时,前后端进行参数匹配时,是以参数的名称进行匹配的,因此参数的位置 是不影响后端获取参数的结果
Ⅱ、传递对象🍓
当参数个数过多时,可以进行传递对象,将参数封装成一个类。
Person对象
package com.example.mvcdemo.controller; import lombok.Data; @Data public class Person { private int id; private String name; private String password; }
TextController
package com.example.mvcdemo.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; /*@Controller//让框架启动的时候加载当前类(只有加载的类,别人才能使用[访问]) @ResponseBody//告诉程序我返回的是一个数据而非页面*/ @RestController//@Controller+@ResponseBody /*@RequestMapping("/text")//路由注册*/ public class TextController { /*@RequestMapping(value = "/hi",method= RequestMethod.POST)//路由注册*/ /*@PostMapping("/hi")*/ @GetMapping("/hi1") public String sayHi1(Person p){ return "Hi "+p.getId()+" "+p.getName()+" "+p.getPassword(); } }
运行代码+传递参数:
注意事项🍒
在Spring Boot(Spring MVC)中传参一定要是包装类型,而非基础类型。
package com.example.mvcdemo.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; /*@Controller//让框架启动的时候加载当前类(只有加载的类,别人才能使用[访问]) @ResponseBody//告诉程序我返回的是一个数据而非页面*/ @RestController//@Controller+@ResponseBody /*@RequestMapping("/text")//路由注册*/ public class TextController { /*@RequestMapping(value = "/hi",method= RequestMethod.POST)//路由注册*/ /*@PostMapping("/hi")*/ @GetMapping("/num") public String sayHi2(int num){ return "num="+num; } }
我们先正常传递参数:
但是如果我们忘记传递或是没有传递(前后端工作人员沟通不及时时),则会报错,而且这是非常严重的。
这个时候就很莫名其妙,也找不到错误。
如果我们将int换成它的包装类时:
正常传递参数可以正常显示:
没有传递参数时它则会显示null,这就会很明显发现错误的来源。
所以注意:参数类型应该设置为包装类
初识SpringMVC(二)https://developer.aliyun.com/article/1393173