Spring MVC

发布于:2024-05-23 ⋅ 阅读:(137) ⋅ 点赞:(0)

目录

一、了解Servlet

二、什么是Spring MVC?

2.1 MVC定义

2.2 Spring MVC介绍

三、学习Spring MVC

3.1 建立连接

3.1.1 @RequestMapping注释介绍

3.1.2 @RequestMapping使用

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

 3.2 请求

3.2.1 传递单个参数

3.2.2 传递多个参数 

3.2.3 传递对象

3.2.4 后端参数重命名 

3.2.5 传递数组

 3.2.6 传递集合

3.2.7 传递JSON对象

​3.2.8 获取URL中参数@PathVariable

3.2.9 上传文件 


一、了解Servlet

        要想了解Spring MVC,先理解下Servlet,Servlet是一种实现动态页面的技术,准确来讲Servlet是一套Java Web开发的规范,或者说是一套Java Web开发的技术标准。 

二、什么是Spring MVC?

        Spring MVC全程Spring Web MVC,它是基于Servlet API构建的原始Web框架,从一开始就包含在Spring框架中。它正式名称为Spring Web MVC,但它通常被称为Spring MVC,Spring MVC是一个WEB框架。

2.1 MVC定义

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

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

举例:

比如去饭店吃饭,客户进店之后,服务员来接待客户点餐,客户点餐之后,把客户菜单交给前厅,前厅根据客户菜单给后厨下达命令,后厨负责做饭,做完之后,再根据菜单告诉服务员,这是哪位客人的饭菜。

在这个过程中:

服务员就是View(视图):负责接待客户,帮助客人点餐以及给顾客端饭

前厅就是Controller(控制器):根据用户的点餐情况,来选择给哪个后厨下达命令

后厨就是Model(模型):根据前厅的要求完成客户的用餐需求

2.2 Spring MVC介绍

        MVC是一种架构设计模式,也是一种思想,而Spring MVC是对MVC思想的具体实现,除此之外,Spring MVC还是一个Web框架。

总结来说,Spring Mvc是一个实现了MVC模式的Web框架。

        其实,Spring MVC我们在前面已经用过了,在创建Spring Boot项目时,我们在勾选Spring Web框架其实就是Spring MVC框架: 

这可能就有点懵了,前面创建的不是Spring Boot项目嘛?怎么又变成了Spring MVC项目了?它们之间到底有着什么样的联系? 

Spring Boot只是实现Spring MVC的其中一种方式而已,Spring Boot可以添加很多依赖,借助这些依赖实现不同的功能,Spring Boot通过添加Spring Web MVC框架来实现web功能。

不过在Spring在实现MVC时,也结合自身项目的特点,做出了一些改变,相对而言,下面的图或许更适合一些。 

比如上面的例子,去饭店吃饭,一些饭店是前厅来负责接待客户,帮助客户点餐,也就是Controller来负责接收用户的请求

再举一个例子: 

比如你去面试公司,可能直接是面试团队来接待候选人,直接省去了HR中间的交接过程,再由面试团队挑选面试官对你进行面试,面试官再将面试情况返回给面试团队,再转交给HR,HR再通知你是否面试通过。

三、学习Spring MVC

学习Spring MVC,重点也就是学习如何通过浏览器和用户程序进行交互

主要分以下三个方面:

  • 建立连接:将用户(浏览器)和Java程序连接起来,也就是访问一个地址能够调用到我们的Spring程序。
  • 请求:用户请求的时候会带一些参数,在程序中要想办法获取到参数,所以请求这块主要是获取参数的功能。
  • 响应:执行了业务逻辑之后,要把程序执行的结果返回给用户,也就是响应。

3.1 建立连接

在Spring MVC中使用@RequestMapping来实现URL路由映射,也就是浏览器连接程序的作用。

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class UserController {
    @RequestMapping("/sayHi")
    public String sayHi() {
        return "hello, Spring MVC";
    }
}

接下来访问:http://127.0.0.1:8080/sayHi,就可以看到程序返回的数据了

3.1.1 @RequestMapping注释介绍

@RequestMapping是Spring Web MVC应用程序中最常用的注解之一,它是用来注册接口的路由映射的。

表示服务收到请求时,路径为/sayHi的请求就会调用sayHi这个方法的代码。

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

既然@RequestMapping已经达到了我们的目的,为什么还需要加@RestController注解呢?

我把@RestController注解去掉,再访问一次:

可以看到,程序报了404,找不到页面

这就是@RestController起到的作用

是因为一个项目中会有很多类,每个类可能会有很多的方法,Spring程序怎么知道要执行哪个方法呢?

Spring会对所有的类进行扫描,如果类加了注解@RestController,Spring才会去看这个类里面的方法有没有加@RequestMapping这个注解,当然它的作用不止这一点,后续会详细介绍。

3.1.2 @RequestMapping使用

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

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

为什么 @RequestMapping既可修饰类,也可以修饰方法?

点进去@RequestMapping源码进行查看

红色框中是它的元注解,表示这个注解既可修饰方法 ,也可修饰方法,具体后面介绍。

注意

  • 我们在写项目时,最好也用@RequestMapping注解修饰类,因为我们要是没加这个类注解的话,Spring在进行扫描的时候,不同的类中可能存在相同的修饰方法的@RequestMapping注解,这就会导致找不到究竟执行哪条命令。
  • @RequestMapping的URL路径最前面加不加/都可以,Spirng程序启动时,会进行判断,如果前面没有加/,Spring会接上一个/

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

此处我们使用Postman来发送请求

1、发送GET请求

2、发送POST请求

通过上图发现,@RequestMapping既支持GET请求也支持POST请求。

 3.2 请求

        访问不同的路径,就是发送不同的请求,在发送请求时,可能会带一些参数,所以学习Spring的请求,主要学习如何传递参数到后端以及后端如何接收。

传递参数,此处使用Postman来模拟。

3.2.1 传递单个参数

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/param")
public class Param {
    @RequestMapping("/m1")
    public String param(String name) {
        return "接到的参数name:" + name;
    }
}

3.2.2 传递多个参数 

@RequestMapping("/m2")
    public String param2(String name, String password) {
        return "接到的参数name:" + name + ", password:" + password;
    }

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

3.2.3 传递对象

如果参数比较多,方法声明就需要有很多形参,并且后续每次新增一个参数,也需要修改方法声明,我们不妨把这些参数封装成一个对象。

@RequestMapping("/m3")
    public String param3(Person p) {
        return p.toString();
    }

3.2.4 后端参数重命名 

某些特殊的情况下,前端传递的参数 key 和我们后端接收的key不⼀致,这样就会出现参数接收不到的情况,如果出现这种情况,就可以使用 @RequestParam 来重命名前后端的参数值。
@RequestMapping("/m4")
    public String param4(@RequestParam("time") String createTime) {
        return "接收到的参数createTime:" + createTime;
    }
       

注意: 

  • 使用@RequestParam进行参数重命名时,请求参数只能和@RequestParam声明的名称一致,才能进行参数绑定和赋值。
  • 使用@RequestParam进行参数重命名时,参数就变成了必传参数。

如果想注解的参数不是必传参数呢?

非必传参数设置

先来了解下参数必传的原因,我们查看@RequestParam注解的实现细节就可以发现端倪,注解实现如下:

可以看到required的默认值为true,表示的含义就是:该注解修饰的参数为必传 。

既然如此,我们可以用过设置@RequestParam中的required=false来避免不传递时报错,具体实现如下:

@RequestMapping("/m4")
    public String param4(@RequestParam(value = "time", required = false) String createTime) {
        return "接收到的参数createTime:" + createTime;
    }

可以看到添加required=false后,在请求的URL中没有添加time参数,程序没有报错。

3.2.5 传递数组

@RequestMapping("/m5")
    public String param5(String[] arrayParam) {
        return Arrays.toString(arrayParam);
    }

 3.2.6 传递集合

集合参数:和数组类似,同一个请求参数名有很多个,且需要使用@RequestParam绑定参数关系

@RequestMapping("/m6")
    public String param6(@RequestParam List<String> list) {
        return "size:" + list.size() + ",listParam:" + list;
    }

 

3.2.7 传递JSON对象

接收JSON对象,需要使用@RequestBody注解

@RequestBody:请求正文,意思就是这个注解作用在请求正文的数据绑定,请求参数必须在写请求正文中。

@RequestMapping("/m7")
    public String param7(@RequestBody Person person) {
        return person.toString();
    }

通过Fiddler观察一下请求参数:

 3.2.8 获取URL中参数@PathVariable

path variable:路径变量

和字面表达的意思一样,这个注解主要作用在请求URL路径上的数据绑定

@RequestMapping("/m8/{id}/{name}")
    public String param8(@PathVariable Integer id, @PathVariable("name") String username) {
        return "解析参数id:" + id + ",name:" + username;
    }

3.2.9 上传文件 

@RequestMapping("/m9")
    public String param9(@RequestPart("file") MultipartFile file) throws IOException {
        //获取文件名称
        String filename = file.getOriginalFilename();
        //文件上传到指定路径
        file.transferTo(new File("G:/temp" + filename));
        return "文件名称:" + filename;
    }

 


网站公告

今日签到

点亮在社区的每一天
去签到