【SSM】Spring MVC 程序开发(重点:SpringMVC 工作流程)

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 本文重点介绍SpringMVC 工作流程、Spring MVC的主要组件、Spring MVC 如何连接、如何获取参数、如何输出数据的。

 【大家好,我是爱干饭的猿,本文重点介绍SpringMVC 工作流程、Spring MVC的主要组件、Spring MVC 如何连接、如何获取参数、如何输出数据的。

后续会继续分享MyBatis、Spring AOP及其他重要知识点总结,如果喜欢这篇文章,点个赞👍,关注一下吧】

上一篇文章:《【web】HTTP(s)协议详解(重点:HTTPS 的加密过程&浏览器中输入网址后,发生了什么?)》


🤞目录🤞

🎨1.什么是 Spring MVC?

1.1 MVC 定义

1.2 MVC 和 Spring MVC 的关系

1.3 Spring 、Spring Boot、Spring MVC有什么区别?

1.4 Spring MVC的主要组件

1.5 SpringMVC 工作流程***

🎨2. Spring MVC 的使用

2.1 Spring MVC 的连接

1. 创建 Spring MVC 项目

2. @RequestMapping 注解介绍

3. @RequestMapping 是 post 还是 get 请求?

4. @GetMapping 和 PostMapping

2.2 获取参数

1. 传递单个参数

2. 传递对象

3. 表单参数传递/传递多个参数(非对象)

4. 参数重命名

5. 设置参数必传

6. @RequestBody 接收JSON对象

7. 获取URL中参数@PathVariable

8. 上传文件@RequestPart

9. 获取Cookie/Session/header

2.3 返回数据

1. 返回静态页面

2. 返回 text/html

3. 返回 JSON 对象

4. 请求转发或请求重定向(两者区别)

5. @ResponseBody

6. 组合注解:@RestController


🎨1.什么是 Spring MVC?

    1. Spring MVC 是一个 Web 框架。
    2. Spring MVC 是基于 Servlet API 构建的。

    1.1 MVC 定义

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

    image.gif编辑

      • Model(模型)是应用程序中用于处理应用程序数据逻辑的部分。通常模型对象负责在数据库中存取数据。
      • View(视图)是应用程序中处理数据显示的部分。通常视图是依据模型数据创建的。
      • Controller(控制器)是应用程序中处理用户交互的部分。通常控制器负责从视图读取数据,控制用户输入,并向模型发送数据。

      1.2 MVC 和 Spring MVC 的关系

      MVC 是一种思想,而 Spring MVC 是对 MVC 思想的具体实现。

      总结来说,Spring MVC 是一个实现了 MVC 模式,并继承了 Servlet API 的 Web 框架。既然是 Web 框 架,那么当用户在浏览器中输入了 url 之后,我们的 Spring MVC 项目就可以感知到用户的请求。

      1.3 Spring 、Spring Boot、Spring MVC有什么区别?

      spring是一个IOC容器,用来管理Bean,使用依赖注入实现控制反转,可以很方便的整合各种框架,提供AOP机制弥补OOP的代码重复问题、更方便将不同类不同方法中的共同处理抽取成切面、自动注入给方法执行,比如日志、异常等。

      springboot是spring提供的一个快速开发工具包,让程序员能更方便、更快速的开发spring+springmvc 应用,简化了配置(约定了默认配置),整合了一系列的解决方案(starter机制)、redis、 mongodb、es。

      springmvc是spring对web框架的一个解决方案,提供了一个总的前端控制器Servlet,用来接收请求,然后定义了一套路由策略(url到handle的映射)及适配执行handle,将handle结果使用视图解析技术生成视图展现给前端。

      1.4 Spring MVC的主要组件

        1. Handler:也就是处理器。它直接应对着MVC中的C也就是Controller层,它的具体表现形式有很多,可以是类,也可以是方法。在Controller层中@RequestMapping标注的所有方法都可以看成是一个 Handler,只要可以实际处理请求就可以是Handler
        2. HandlerMapping initHandlerMappings(context),处理器映射器,根据用户请求的资源uri来查找Handler的。在 SpringMVC中会有很多请求,每个请求都需要一个Handler处理,具体接收到一个请求之后使用哪个 Handler进行,这就是HandlerMapping需要做的事。
        3. HandlerAdapter initHandlerAdapters(context),适配器。因为SpringMVC中的Handler可以是任意的形式,只要能处理请求就ok,但是Servlet需要的处理方法的结构却是固定的,都是以request和response为参数的方法。如何让固定的Servlet处理方法调用灵活的Handler来进行处理呢?这就是HandlerAdapter要做的事情。 Handler是用来干活的工具;HandlerMapping用于根据需要干的活找到相应的工具;HandlerAdapter 是使用工具干活的人。
        4. HandlerExceptionResolver initHandlerExceptionResolvers(context), 其它组件都是用来干活的。在干活的过程中难免会出现问题,出问题后怎么办呢?这就需要有一个专门的角色对异常情况进行处理,在SpringMVC中就是 HandlerExceptionResolver。具体来说,此组件的作用是根据异常设置ModelAndView,之后再交给 render方法进行渲染。
        5. ViewResolver initViewResolvers(context),ViewResolver用来将String类型的视图名和Locale解析为View类型的视图。View是用来渲染页面的,也就是将程序返回的参数填入模板里,生成html(也可能是其它类型)文件。这里就有两个关键问题:使用哪个模板?用什么技术(规则)填入参数?这其实是ViewResolver 主要要做的工作,ViewResolver需要找到渲染所用的模板和所用的技术(也就是视图的类型)进行渲染,具体的渲染过程则交由不同的视图自己完成。
        6. RequestToViewNameTranslator initRequestToViewNameTranslator(context),ViewResolver是根据ViewName查找View,但有的 Handler处理完后并没有设置View也没有设置ViewName,这时就需要从request获取ViewName了,如何从request中获取ViewName就是RequestToViewNameTranslator要做的事情了。RequestToViewNameTranslator在Spring MVC容器里只可以配置一个,所以所有request到 ViewName的转换规则都要在一个Translator里面全部实现。
        7. LocaleResolver initLocaleResolver(context), 解析视图需要两个参数:一是视图名,另一个是Locale。视图名是处理器返回的,Locale是从哪里来的?这就是LocaleResolver要做的事情。LocaleResolver用于从request 解析出Locale,Locale就是zh-cn之类,表示一个区域,有了这个就可以对不同区域的用户显示不同的结果。SpringMVC主要有两个地方用到了Locale:一是ViewResolver视图解析的时候;二是用到国际化资源或者主题的时候。
        8. ThemeResolver initThemeResolver(context),用于解析主题。SpringMVC中一个主题对应一个properties文件,里面存放着跟当前主题相关的所有资源、如图片、css样式等。SpringMVC的主题也支持国际化,同一个主 题不同区域也可以显示不同的风格。SpringMVC中跟主题相关的类有 ThemeResolver、ThemeSource 和Theme。主题是通过一系列资源来具体体现的,要得到一个主题的资源,首先要得到资源的名称,这是ThemeResolver的工作。然后通过主题名称找到对应的主题(可以理解为一个配置)文件,这是 ThemeSource的工作。 后从主题中获取资源就可以了。
        9. MultipartResolver initMultipartResolver(context),用于处理上传请求。处理方法是将普通的request包装成 MultipartHttpServletRequest,后者可以直接调用getFile方法获取File,如果上传多个文件,还可以调用getFileMap得到FileName->File结构的Map。此组件中一共有三个方法,作用分别是判断是不是上传请求,将request包装成MultipartHttpServletRequest、处理完后清理上传过程中产生的临时资源。
        10. FlashMapManager initFlashMapManager(context),用来管理FlashMap的,FlashMap主要用在redirect中传递参数。

               -- 源自 陈橘又青的博客

        1.5 SpringMVC 工作流程***

        image.gif编辑

          1. 用户发送请求至前端控制器 DispatcherServlet。
          2. DispatcherServlet 收到请求调用 HandlerMapping 处理器映射器。
          3. 处理器映射器找到具体的处理器(可以根据 xml 配置、注解进行查找),生成处理器及处理器拦截器 (如果有则生成)一并返回给 DispatcherServlet。
          4. DispatcherServlet 调用 HandlerAdapter 处理器适配器。
          5. HandlerAdapter 经过适配调用具体的处理器(Controller,也叫后端控制器)
          6. Controller 执行完成返回 ModelAndView。
          7. HandlerAdapter 将 controller 执行结果 ModelAndView 返回给 DispatcherServlet。8) DispatcherServlet 将 ModelAndView 传给 ViewReslover 视图解析器。
          8. ViewReslover 解析后返回具体 View。
          9. DispatcherServlet 根据 View 进行渲染视图(即将模型数据填充至视图中)。
          10. DispatcherServlet 响应用户。

          🎨2. Spring MVC 的使用

          学习 Spring MVC 我们只需要掌握以下 3 个功能:

            1. 连接的功能:将用户(浏览器)和 Java 程序连接起来,也就是访问一个地址能够调用到我们的 Spring 程序。
            2. 获取参数的功能:用户访问的时候会带一些参数,在程序中要想办法获取到参数。
            3. 输出数据的功能:执行了业务逻辑之后,要把程序执行的结果返回给用户。

            2.1 Spring MVC 的连接

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

            1. 创建 Spring MVC 项目

            Spring MVC 项目创建和 Spring Boot 创建项目相同(Spring MVC 使用 Spring Boot 的方式创建),在 创建的时候选择 Spring Web 就相当于创建了 Spring MVC 的项目。

            创建一个 Test1类,实现用户到 Spring 程序的互联互通:

            @Slf4j
            @ResponseBody // 返回一个 text/html 信息(响应体)
            @Controller
            @RequestMapping("/test1")
            public class Test1 {
                @RequestMapping("/hello")
                public String sayWord(){
                    log.info("hello");
                    return "word";
                }
            }

            image.gif

            2. @RequestMapping 注解介绍

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

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

            上面代码的访问地址就是 127.0.0.1:8080/test1/hello

            3. @RequestMapping 是 post 还是 get 请求?

            @RequestMapping 默认是 get 方式的请求,可以使用 Apipost6进行测试。

            image.gif编辑

            如何接收 post 请求? 我们可以显示的指定 @RequestMapping 来接收 POST 的情况

            @RequestMapping(value = "/hi",method= RequestMethod.POST)

            4. @GetMapping 和 PostMapping

            get 请求的 3 种写法:

            // 方法一:
                @RequestMapping("/hello")
                // 方法二:
                @RequestMapping(value = "/hello", method = RequestMethod.GET)
                // 方法三:
                @GetMapping("/hello")

            image.gif

            post 请求的 2 种写法:

            // 方法一:
                @RequestMapping(value = "/hello", method = RequestMethod.POST)
                // 方法二:
                @PostMapping("/hello")

            image.gif

            2.2 获取参数

            1. 传递单个参数

            @RequestMapping("/method1")
                @ResponseBody
                public String method1(String name){
                    System.out.println("请求参数:" + name);
                    return name;
                }

            image.gif

            image.gif编辑

            2. 传递对象

            @Data
                class Person{
                    public String name;
                    public String gender;
                }
                @RequestMapping("/method2")
                @ResponseBody
                public String method2(Person person){
                    System.out.println("请求对象:" + person);
                    return person.name + " " +person.gender;
                }

            image.gif

            3. 表单参数传递/传递多个参数(非对象)

            @RequestMapping("/method3")
                @ResponseBody
                public String method3(String name, String gender){
                    System.out.println(name + " " + gender);
                    return name + " " + gender;
                }

            image.gif

            4. 参数重命名

            某些特殊的情况下,前端传递的参数 key 和我们后端接收的 字段 key 可以不一致,可以使用 @RequestParam 来重命名前后端的参数值。

            @RequestMapping("/method4")
                @ResponseBody
                public String method4(@RequestParam("time") String getTime){
                    System.out.println(getTime);
                    return getTime;
                }

            image.gif

            5. 设置参数必传

            @RequestParam 上面的列子,如果我们是前端传递一个非 time 的参数,就会出现程序报错的情况。

            非必传参数设置

            如果我们的实际业务前端的参数是一个非必传的参数,我们可以通过设置 @RequestParam 中的 required=false 来避免不传递时报错,具体实现如下:

            @RequestMapping("/method5")
                @ResponseBody
                public String method5(@RequestParam(value = "time", required = false) String getTime){
                    System.out.println(getTime);
                    return getTime;
                }

            image.gif

            6. @RequestBody 接收JSON对象

            @RequestMapping(value = "/method6", method = RequestMethod.POST)
                public Object method6(@RequestBody Person person) {
                    System.out.println("Person:" + person);
                    return "redirect:/index.html"; 
                }

            image.gif

            7. 获取URL中参数@PathVariable

            @PostMapping("/method7/{name}/{password}")
                @ResponseBody
                public String method7(@PathVariable String name, @PathVariable String password){
                    System.out.println(name + " " + password);
                    return name + " " + password;
                }

            image.gif

            8. 上传文件@RequestPart

            @RequestMapping("/method8") 
                public String method7(String name, @RequestPart("myfile") MultipartFile file) throws IOException { 
                    // 获取文件后缀名 
                    String fileName = file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".") ); 
                    // 文件保存地址 
                    String filePath = ClassUtils.getDefaultClassLoader().getResource("static").getPath() + "/" + UUID.randomUUID() + fileName; 
                    // 保存文件 
                    file.transferTo(new File(filePath)); 
                    return filePath + " 上传成功."; 
                }

            image.gif

            9. 获取Cookie/Session/header

            @RequestMapping("/method9")
                @ResponseBody()
                public String method9(
                        HttpServletRequest req, 
                        HttpServletResponse res,
                        HttpSession session)
                {
                    //...
                    return "...";
                }

            image.gif

            2.3 返回数据

            1. 返回静态页面

            @RequestMapping("/index")
                public Object index(){
                    return "/index.html";
                }

            image.gif

            2. 返回 text/html

            @RequestMapping("/method10")
                @ResponseBody
                public String method10(){
                    return "hello word";
                }

            image.gif

            3. 返回 JSON 对象

            @RequestMapping("/method11")
                @ResponseBody
                public Map<Integer, Integer> method11(){
                    Map<Integer, Integer> map = new HashMap<>();
                    map.put(1, 1);
                    map.put(2, 2);
                    map.put(3, 3);
                    return map;
                }

            image.gif

            4. 请求转发或请求重定向(两者区别)

            // 请求重定向
                @RequestMapping("/index2") 
                public String index2(){
                    return "redirect:/index.html";
                }
                // 请求转发 
                @RequestMapping("/index3") 
                public String index3(){ 
                    return "forward:/index.html"; 
                }

            image.gif

            forward 和 redirect 具体区别:

              1. 请求重定向(redirect)将请求重新定位到资源;请求转发(forward)服务器端转发。
              2. 请求重定向地址发生变化,请求转发地址不发生变化。
              3. 请求重定向与直接访问新地址效果一直,不存在原来的外部资源不能访问;请求转发服务器端转发 有可能造成原外部资源不能访问。

              5. @ResponseBody

              说明 @ResponseBody 返回的值如果是字符会转换成 text/html,如果返回的是对象会转换成 application/json 返回给前端。

              @ResponseBody 可以用来修饰方法或者是修饰类,修饰类表示类中的所有方法都会返回 html 或者 json,而不是视图。

              6. 组合注解:@RestController

              @RestController = @Controller + @ResponseBody


              分享到此,感谢大家观看!!!

              如果你喜欢这篇文章,请点赞关注吧,或者如果你对文章有什么困惑,可以私信我。

              🏓🏓🏓

              相关文章
              |
              1天前
              |
              SQL Java 数据库连接
              对Spring、SpringMVC、MyBatis框架的介绍与解释
              Spring 框架提供了全面的基础设施支持,Spring MVC 专注于 Web 层的开发,而 MyBatis 则是一个高效的持久层框架。这三个框架结合使用,可以显著提升 Java 企业级应用的开发效率和质量。通过理解它们的核心特性和使用方法,开发者可以更好地构建和维护复杂的应用程序。
              43 26
              |
              2月前
              |
              设计模式 前端开发 Java
              步步深入SpringMvc DispatcherServlet源码掌握springmvc全流程原理
              通过对 `DispatcherServlet`源码的深入剖析,我们了解了SpringMVC请求处理的全流程。`DispatcherServlet`作为前端控制器,负责请求的接收和分发,处理器映射和适配负责将请求分派到具体的处理器方法,视图解析器负责生成和渲染视图。理解这些核心组件及其交互原理,有助于开发者更好地使用和扩展SpringMVC框架。
              62 4
              |
              3月前
              |
              前端开发 Java 开发者
              Spring MVC中的请求映射:@RequestMapping注解深度解析
              在Spring MVC框架中,`@RequestMapping`注解是实现请求映射的关键,它将HTTP请求映射到相应的处理器方法上。本文将深入探讨`@RequestMapping`注解的工作原理、使用方法以及最佳实践,为开发者提供一份详尽的技术干货。
              201 2
              |
              4月前
              |
              JSON 前端开发 Java
              SSM:SpringMVC
              本文介绍了SpringMVC的依赖配置、请求参数处理、注解开发、JSON处理、拦截器、文件上传下载以及相关注意事项。首先,需要在`pom.xml`中添加必要的依赖,包括Servlet、JSTL、Spring Web MVC等。接着,在`web.xml`中配置DispatcherServlet,并设置Spring MVC的相关配置,如组件扫描、默认Servlet处理器等。然后,通过`@RequestMapping`等注解处理请求参数,使用`@ResponseBody`返回JSON数据。此外,还介绍了如何创建和配置拦截器、文件上传下载的功能,并强调了JSP文件的放置位置,避免404错误。
              |
              4月前
              |
              前端开发 Java 应用服务中间件
              【Spring】Spring MVC的项目准备和连接建立
              【Spring】Spring MVC的项目准备和连接建立
              76 2
              |
              XML 设计模式 Java
              SPRING03_为什么要学习源码、基础的接口、SPRING工作流程详解
              ①. 为什么要学习源码? ②. Spring基础接口 ③. Spring的工作流程详解
              143 0
              SPRING03_为什么要学习源码、基础的接口、SPRING工作流程详解
              |
              11天前
              |
              XML Java 应用服务中间件
              Spring Boot 两种部署到服务器的方式
              本文介绍了Spring Boot项目的两种部署方式:jar包和war包。Jar包方式使用内置Tomcat,只需配置JDK 1.8及以上环境,通过`nohup java -jar`命令后台运行,并开放服务器端口即可访问。War包则需将项目打包后放入外部Tomcat的webapps目录,修改启动类继承`SpringBootServletInitializer`并调整pom.xml中的打包类型为war,最后启动Tomcat访问应用。两者各有优劣,jar包更简单便捷,而war包适合传统部署场景。需要注意的是,war包部署时,内置Tomcat的端口配置不会生效。
              105 17
              Spring Boot 两种部署到服务器的方式
              |
              11天前
              |
              Dart 前端开发 JavaScript
              springboot自动配置原理
              Spring Boot 自动配置原理:通过 `@EnableAutoConfiguration` 开启自动配置,扫描 `META-INF/spring.factories` 下的配置类,省去手动编写配置文件。使用 `@ConditionalXXX` 注解判断配置类是否生效,导入对应的 starter 后自动配置生效。通过 `@EnableConfigurationProperties` 加载配置属性,默认值与配置文件中的值结合使用。总结来说,Spring Boot 通过这些机制简化了开发配置流程,提升了开发效率。
              46 17
              springboot自动配置原理
              |
              16天前
              |
              XML JavaScript Java
              SpringBoot集成Shiro权限+Jwt认证
              本文主要描述如何快速基于SpringBoot 2.5.X版本集成Shiro+JWT框架,让大家快速实现无状态登陆和接口权限认证主体框架,具体业务细节未实现,大家按照实际项目补充。
              62 11
              |
              18天前
              |
              缓存 安全 Java
              Spring Boot 3 集成 Spring Security + JWT
              本文详细介绍了如何使用Spring Boot 3和Spring Security集成JWT,实现前后端分离的安全认证概述了从入门到引入数据库,再到使用JWT的完整流程。列举了项目中用到的关键依赖,如MyBatis-Plus、Hutool等。简要提及了系统配置表、部门表、字典表等表结构。使用Hutool-jwt工具类进行JWT校验。配置忽略路径、禁用CSRF、添加JWT校验过滤器等。实现登录接口,返回token等信息。
              202 12