• 【Spring】Spring MVC入门


    Spring MVC入门

    一、什么是Spring Web MVC?

    1.1 MVC定义

    MVC是Model View Controller的缩写,是一种软件架构的设计模式,将软件系统分为模型、视图、控制器三个部分。

    示意图如下:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    可以看到,Controller作为一个==“粘合剂”==处于Model和View之间,充当传话筒。

    就好比:

    在饭店顾客将想吃的饭菜报给前台,前台将这个请求报给后厨,后厨选择对应的菜谱进行制作,完成之后前台再将饭菜反馈给前台,前台将饭菜端到顾客面前。

    在这个例子中:

    顾客 -> View

    前台 -> Controller

    后厨 -> Model


    1.2 什么是Spring Web MVC?

    简单来说,MVC是一种架构设计模式,Spring Web MVC 是对于这种思想的一种实现

    Spring: 是一种框架,便于进行开发

    Web: 网页开发

    MVC:架构设计模式

    1. Spring Web MVC 一般简称为 SpringMVC。
    2. Spring MVC就是一种网页开发的框架,这种框架的设计架构是MVC。

    示意图:

    在这里插入图片描述

    可以看到相比于MVC的示意图只是添加了一个浏览器。

    那么饭店的那个例子就是:

    顾客去吃饭,将想吃的饭菜报给传菜员,传菜员报给前厅,前厅报给后厨,后厨制作,反馈给前厅,传菜员将饭菜端过去。


    二、 学习Spring MVC

    2.1 如何使用?

    由上图可以知道,打开MVC大门的是浏览器,所以需要让我们的Java代码和浏览器建立连接。

    流程:

    1. 建立连接:代码和浏览器建立连接。

    2. 请求:用户使用浏览器发送请求,要在代码中获得这个请求。

      具体说就是获取参数这个动作。

    3. 响应:MVC这一套下来以后会有一个具体的响应,所以需要让这个响应返回给用户。

      获取到用户请求后,需要在代码部分对于请求进行分析,分析完成后的响应需要通过连接返回给用户。

    2.2 建立连接

    建立路由映射的注解是:@RequestMapping("路径名称")

    有了这个路径,就可以打通代码和浏览器之间的连接,使得代码可以通过这个 url 对浏览器建立连接。

    但是光有这个路径还不够:

    代码:

    package com.example.springmvcdemo;
    
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RequestMapping("/request")
    
    public class RequestController {
        @RequestMapping("/hello")
        public String sayHello() {
            return "hello, Spring MVC";
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    结果:

    在这里插入图片描述

    会报404的错误,使得资源不存在。

    原因在于没有加上@RestController的注解,这并不会使得Spring认为这个程序是一个想要与浏览器建立连接的程序,Spring不回扫描这个程序所带的路径:“/request/hello”,只有加上这个注解,Spring才会扫描这个路径,这样资源才能够找得到。


    @RestController解释:

    1. 这个注解是@Controller@Responsebody的组合,成为组合注解。

    2. @controller是控制器注解,表明这个类是一个控制器

    3. @Responsebody表示将方法的结果直接写入HTTP响应

      如果返回值是字符串,则将在网页上直接显示该字符串

    代码:

    package com.example.springmvcdemo;
    
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RequestMapping("/request")
    @RestController
    public class RequestController {
        @RequestMapping("/hello")
        public String sayHello() {
            return "hello, Spring MVC";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    结果:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


    2.3 总结

    1. 建立路由映射时使用的注解是:@RequestMapping

    2. 必须让需要与浏览器建立连接的代码成为控制器类才能交由Spring进行扫描,使用的注解是@RestController

    3. @RequestMapping注解可以使用在类和方法上,访问的路径是:类路径(如果有)+方法路径

    4. 在使用@RequestMapping注解时,可以在路径前面加上斜杠,也可以不加(Spring会自动帮忙加上)

      建议加上斜杠 “/”

    5. 可以指定方式接收响应

      代码:

          // 指定使用GET
          @RequestMapping(value = "/hello", method = RequestMethod.GET)
          public String sayHello() {
              return "hello, Spring MVC";
          }
      
      • 1
      • 2
      • 3
      • 4
      • 5
    6. @RequestMapping同时支持GET和POST请求

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


    三、 传递参数

    3.1 传递单个参数

    代码:

        @RequestMapping("/r1")
        public String r1(String para) {
            return "接收到参数:" + para;
        }
    
        @RequestMapping("/r2")
        public String r2(Integer para) {
            return "r2接收到参数:" + para;
        }
    
        @RequestMapping("/r3")
        public String r1(int para) {
            return "r3接收到参数:" + para;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    结果(成功):

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    结果(失败):

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


    总结:

    从以上实验结果可知:

    1. 传递参数时,形参尽量使用包装类。如果是基本类型,必须传参(除了Boolean类型)。

      包装类是一个引用,可以为空

      基本类型是一个值,不能为空,但是有默认值的概念(int的默认值是0,bool的默认值是false)

    2. 传参的时候名称不对则传参不成功。

    3. 传参的时候会发生类型强制转化,所以如果形参和传递参数的类型不一致,那么会发生类型转化异常。

      在浏览器传递参数都是以字符串的形式进行传递,浏览器并不负责类型解析的工作,但是在传递到程序一端的时候,就会对于这个参数进行类型转化,所以会发生异常。


    3.2 传递多个参数

    代码:

        @RequestMapping("/r4")
        public String r4(String para1, Integer para2) {
            return "r4接收到参数1:" + para1 + " 参数2:"+para2;
        }
    
    • 1
    • 2
    • 3
    • 4

    结果:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传 外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    总结:

    1. 传递多个参数会按序传递。
    2. 传递的时候是按照名称进行匹配的,所以浏览器在进行传参的时候可以不按照代码的参数顺序进行传参。
    3. 传递的时候,基本类型和包装类型的规则同传递单个参数的情况

    3.3 传递对象

    在可以一次传递多个参数的基础上,演化为可以传递对象,因为如果每次增加参数的时候都去在参数部分增加,那会让代码冗长不易读,而且修改代码的工程量大,所以需要有一个对象就将所要传递的参数进行封装。

    代码:

        @RequestMapping("/r5")
        public String r5(Person para) {
            return "r5接收到对象:" + para.toString();
        }
    
    • 1
    • 2
    • 3
    • 4

    结果:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    总结:

    1. 在传递对象的时候,会按照名称进行寻找传递的参数。
    2. 包装类和基本类型的传递规则同上。
    3. 总而言之,与传递多个参数保持一致。

    3.4 后端参数重命名(从URL中获取参数)

    使用@RequestPram注解。

    代码:

        @RequestMapping("/r6")
        public String r6(@RequestParam("intPara") Integer para) {
            return "r6接收到参数:" + para;
        }
    
    • 1
    • 2
    • 3
    • 4

    结果:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    总结:

    1. @RequestParam注解并不适用于类,只能对于单个、多个参数(每个参数都需要再写一遍@RequestParam)进行使用

    2. 使用时,是从URL中拿到参数,所以注解当中的名称应当和浏览器一方的名称相同。

    3. 在传递参数时,如果是必传,可以在注解中加上 required=true(此项在实现中默认是true,所以默认加上这个注解之后就是必传)

      代码:

          @RequestMapping("/r6")
          public String r6(@RequestParam(value = "intPara", required = true) Integer para) {
              return "r6接收到参数:" + para;
          }
      
      
      • 1
      • 2
      • 3
      • 4
      • 5

      结果:

      image-20240418155459641

      可以看到即使是包装类,在加上required=true这个条件之后也会发生错误。


    3.5 传递数组

    代码:

        @RequestMapping("/r7")
        public String r7(String[] para) {
            return "r7接收到数组:" + Arrays.toString(para);
        }
    
    • 1
    • 2
    • 3
    • 4

    结果:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


    3.6 传递集合-@RequestParam

    代码:

        @RequestMapping("/r8")
        public String r8(@RequestParam List<String> para) {
            return "r8接收到集合:" + para;
        }
    
    • 1
    • 2
    • 3
    • 4

    结果:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    总结:

    1. 传递集合时需要加上@RequestParam注解。

      传递数组不需要加是因为Spring会自动将参数解析到数组中,但是集合不能解析,所以需要加上这个注解进行解析

    2. 其余与传递数组相同。

    3.7 传递JSON数据-@RequestBody

    代码:

        @RequestMapping("/r9")
        public String r9(@RequestBody Person para) {
            return "r9接收到JSON:" + para;
        }
    
    • 1
    • 2
    • 3
    • 4

    结果:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    总结:

    1. 需要加上 @RequestBody注解

    2. 在使用postman传递参数的时候需要使用Body选项,选择json进行传递

    3. JSON语法:

      1. 对象使用 {}

      2. 数组使用 []

      3. 数据表示为 键:值

        值也可以是数组

      4. 数据之间使用 , 进行分隔

    4. JSON的优点:

      1. 简单易用

        使用键值对的形式表示非常清晰

      2. 跨平台

      3. 轻量级

      4. 易于扩展

      5. 安全性

        JSON是纯文本格式, 不包含可执行代码, 所以恶意代码注入也不会执行


    ## 3.8 从URL占位符中获取参数-@PathVariable

    代码:

        @RequestMapping("/r10/{para1}/{para2}/{para3}")
        public String r10(@PathVariable Integer para1,
                          @PathVariable String para2,
                          @PathVariable("para3") String userName) {
            return "r10接收到参数1:" + para1 + " 参数2:" + para2 +" 参数3:" + userName;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    结果:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    总结:

    1. 需要使用 @PathVariable注解

      字面意思, 就是在路径中的变量

    2. 可以在注解中对于参数进行重新命名, 注解中的名字是作为URL的占位名字.

      @PathVariable(“para3”) String userName中的para3就是重新命的名,所以:

      占位符是para3而不是userName


    3. 9 上传文件-@RequestPart

    代码:

        @RequestMapping("/r11")
        public String r11(@RequestPart("file") MultipartFile file) throws IOException {
            // 获取文件名称
            String fileName = file.getOriginalFilename();
    
            // 上传文件到指定路径
            file.transferTo(new File("D://" + file.getOriginalFilename()));
    
            return "接收到的文件名称为:"+ fileName;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    结果:

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    总结:

    1. 需要使用 @RequestPart注解
    2. 不能上传过大的文件
        @RequestMapping("/r11")
        public String r11(@RequestPart("file") MultipartFile file) throws IOException {
            // 获取文件名称
            String fileName = file.getOriginalFilename();
    
            // 上传文件到指定路径
            file.transferTo(new File("D://" + file.getOriginalFilename()));
    
            return "接收到的文件名称为:"+ fileName;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    结果:

    [外链图片转存中…(img-zWR4a7oE-1713446966779)]

    [外链图片转存中…(img-g9Q5EwFH-1713446966779)]

    总结:

    1. 需要使用 @RequestPart注解
    2. 不能上传过大的文件
    3. 需要在传文件的时候在key里写上对应的名称 (注解规定的那个名称)
  • 相关阅读:
    vue相关面试题:computed和watch区别
    设计一个基于 GraphQL 的 Node.js 工单系统
    CSS布局的三种方式
    K8S集群中Pod资源调度失败的故障排查思路
    代码可读性,前置检查、注释及总结
    Scrum 实施过程的主要内容及5大常用工具
    Maven生命周期与插件
    mapstruct lombok结合使用
    MYSQL8解压版 windows 主从部署步骤及配置(包含配置文件,教程文件,免积分下载)
    bash 条件语句
  • 原文地址:https://blog.csdn.net/leadera_/article/details/137938369