SpringMVC基础之工作流程

文章目录

  • SpringMVC 的工作流程
    • 1. 总图
    • 2. DispatcherServlet
    • 3. 必需的配置
    • 4. 加载配置文件的两个时机
    • 5. 定义控制器
    • 6. 创建 JSP 视图

SpringMVC 的工作流程

1. 总图

SpringMVC工作流程

如上图,Spring MVC 程序的完整执行流程如下:

  1. 用户通过浏览器发送请求,请求会被 Spring MVC 的『前端控制器』DispatcherServlet 接收。

  2. DispatcherServlet 拦截到请求后,会调用『处理器映射器』HandlerMapping

  3. 『处理器映射器』根据请求 URL 找到具体的『处理器』Handler ,生成『处理器』对象(如果有,还会生成拦截器对象)并返回给 DispatcherServlet

  4. DispatcherServlet 根据返回信息Handler选择合适的『处理器适配器』HandlerAdapter

  5. HandlerAdapter 会调用并指定 Handler此处和上述所说的处理器 Handler ,就是我们所编写的 Controller 类。

  6. Controller 执行完成后,会返回一个 ModelAndView 对象,该对象中会包含『视图名』和『模型对象』。

  7. HandlerAdapterModelAndView 返回给 DispatcherServlet

  8. DispatcherServlet 会根据返回信息ModelAndView选择一个合适的『视图解析器』ViewResolver

  9. 视图解析器 ViewResolver 解析视图后,会向 DispatcherServlet 返回具体的 View 对象。

  10. DispatcherServletView 进行渲染。即,将『模型数据』填充至『视图』中。

  11. DispatcherServlet 将渲染后的结果返回、发送给客户端浏览器。

在上述执行过程中,DispatcherServletHandlerMappingHandlerAdapterViewResolver 对象的工作都是在框架内部执行的,开发人员并不需要关心这些对象内部实现过程。

和程序员有关的内容只有 Handler(即,代码中的 Controller,和 ModelAndView 对象。

2. DispatcherServlet

Spring Web 的『模型 - 视图 - 控制器(MVC)框架是围绕 DispatcherServlet 设计的,它处理所有的 HTTP 请求和响应。

以下是对应于到 DispatcherServlet 的传入 HTTP 请求的事件顺序:

  • 在接收到 HTTP 请求后,DispatcherServlet 会查询 HandlerMapping,并通过 Adapter 调用相应的 Controller

  • Controller 接受请求并根据使用的 GETPOST 方法调用相应的服务方法。 服务方法将基于定义的业务逻辑设置模型数据,并将视图名称返回给 DispatcherServlet

  • DispatcherServlet 将从 ViewResolver 获取请求的定义视图。当视图完成,DispatcherServlet 将模型数据传递到最终的视图,并在浏览器上呈现。

3. 必需的配置

需要通过使用 web.xml 文件中的 URL 映射来映射希望 DispatcherServlet 处理的请求。

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee 
        http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
    version="3.1">

    ...

    <!-- 配置 SpringMVC 前端控制器 -->
    <servlet>
        <servlet-name>HelloWeb</servlet-name>
        <servlet-class>
            org.springframework.web.servlet.DispatcherServlet
        </servlet-class>
        ...
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>HelloWeb</servlet-name>
        <url-pattern>*.do</url-pattern> <!-- 后缀拦截 -->
    </servlet-mapping>

</web-app>

4. 加载配置文件的两个时机

SpringMVC 有两次加载 Spring 配置文件的时机:

首先在 SpringMVC 项目启动时,会依据 web.xml 配置文件中所配置的监听器:ContextLoaderListener 去加载对应位置下的 Spring 配置文件。

  • Spring 配置文件版:web.xml

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            classpath:spring-dao.xml,
            classpath:spring-service.xml
        </param-value>
    </context-param>
    
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>
    
  • Spring 代码配置版:web.xml

    <context-param>
        <param-name>contextClass</param-name>
        <param-value> <!-- 相较于 XML 配置,Java 代码配置『多』一个这个 -->
            org.springframework.web.context.support.AnnotationConfigWebApplicationContext
        </param-value>
    </context-param>
    
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            com.example.config.SpringServiceConfig,
            com.example.config.SpringDaoConfig
        </param-value>
    </context-param>
    
    <listener>
        <listener-class>
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
    </listener>
    

无论你有没有利用第一次加载时机(配置 ContextLoadListener),那么 Spring MVC 都会继续进入第二个加载配置文件时机:根据 DispatcherServlet 的初始化配置<init-param>加载对应位置的 Spring 配置。

  • Spring 配置文件版:web.xml

    <servlet>
        <servlet-name>sampleServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-web.xml</param-value>
        </init-param>
    </servlet>
    
    <servlet-mapping>
        ...
    </servlet-mapping>
    
  • Spring 代码配置版:web.xml

    <servlet>
        <servlet-name>sampleServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param><!-- 相较于 XML 配置,Java 代码配置『多』一个这个 -->
            <param-name>contextClass</param-name>
            <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
        </init-param>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>com.example.config.SpringWebConfig</param-value>
        </init-param>
    </servlet>
    
    <servlet-mapping>
        ...
    </servlet-mapping>
    

如果是 XML 配置文件,这里的 Spring 配置文件的路径如果是以 classpath: 开始,则表示配置文件是在 classpath 路径下。否则,就是在项目的工程根目录webapp>下。

SpringMVC 首先加载的是 <context-param> 配置的内容,而并不会去初始化 servlet。只有进行了网站的跳转,经过了 DispatcherServlet 的导航的时候,才会初始化 Servlet,从而加载 <init-param> 中的内容。

一般而言,

  • <context-param> 配置的 Spring 配置文件,习惯性叫 applicationContext ,或 webApplicationContext ,表示全局性 Spring 配置。

  • <init-param> 配置的 Spring 配置文件可以叫 SpringWebApplicationContext ,表示 spirng-webmvc(web 层)相关的 Spring 配置。

现在来看看 SpringWebConfig.java 文件的必需配置:

@Configuration
@EnableWebMvc
@ComponentScan("com.example.inlet.controllers")
public class SpringWebConfig implements WebMvcConfigurer {
    ...
}

Spring MVC 配置类的关键,除了实现 WebMvcConfigurer 接口之外,还有就是需要标注 @EnableWebMvc 注解。

因为 @EnableWebMvc 注解的存在,Spring MVC 会自动创建、激活使用 19 个 Bean,这 19 个 Bean 在各个场景、环境中默默地支持着 Spring MVC 框架的的工作。

当然,如果也可以不使用 @EnableWebMvc 注解,这样的话,你需要直接(或间接地)去声明这 19 个 Bean(或其等价的替代品)。否则,Spring MVC 就不会以你想当然地方式运行。

另外,你也无须担心这默认的 19 个 Bean 是否符合你的需求,在合适的常见中,当你觉得其中的某个所提供的功能并非你所需要,你可以自定义 Bean 去覆盖、替代它(们)

5. 定义控制器

DispatcherServlet 将请求委派给控制器以执行特定于其的功能。 @Controller 注释指示特定类充当控制器的角色。@RequestMapping 注释用于将 URL 映射到整个类或特定处理程序方法。

@Controller
public class HelloController {

  @RequestMapping(value="/hello", method=RequestMethod.GET)
  public ModelAndView printHello() {
    ModelAndView mav = new ModelAndView();
    mav.addObject("message", "Hello Spring MVC Framework!");
    mav.setViewName("/WEB-INF/jsp/hello.jsp");
    return mav;
  }
}

@Controller 注释将类定义为 Spring MVC 控制器。

@RequestMapping 的第一个用法表示此控制器上的所有处理方法都与 /hello 路径相关。

@RequestMapping(method = RequestMethod.GET) 用于声明 printHello 方法作为控制器的默认服务方法来处理 HTTP GET 请求。可以定义另一个方法来处理同一 URL 的任何 POST 请求。

value 属性指示处理程序方法映射到的 URL,method 属性定义处理 HTTP GET 请求的服务方法。关于以上定义的控制器,需要注意以下几点:

  • 在服务方法中定义所需的业务逻辑。可以根据需要在此方法内调用其他方法。

  • 基于定义的业务逻辑,将在此方法中创建一个模型。可以设置不同的模型属性,这些属性将被视图访问以呈现最终结果。此示例创建且有属性 message 的模型。

  • 定义的服务方法可以返回一个 String,它包含要用于渲染模型的视图的名称。此示例将 "hello" 返回为逻辑视图名称。

6. 创建 JSP 视图

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/jsp/" />
    <property name="suffix" value=".jsp" />
</bean>

Spring MVC 支持许多类型的视图用于不同的表示技术。包括 JSP,HTML,PDF,Excel 工作表,XML,Velocity 模板,XSLT,JSON,Atom 和 RSS 源,JasperReports 等。这里使用的是 JSP 模板,并在 /WEB-INF/hello/hello.jsp 中写一个简单的 hello 视图:

<html>
    <head>
        <title>Hello Spring MVC</title>
    </head>
    <body>
        <h2>${message}</h2>
    </body>
</html>

这里 ${message} 是在 Controller 中设置的属性。可以在视图中显示多个属性。

另一张图,表达了同样的逻辑:

SpringMVC工作流程

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

怎样提升小程序日活?签到抽奖可行吗?

一、 日活运营策略 小程序应该是即用即走的&#xff0c;每个小程序都在用户中有自己的独特定位&#xff0c;可能是生活日常必备&#xff08;美食、团购、商城&#xff09;&#xff0c;也可能是工作办公必备&#xff08;文档、打卡、工具&#xff09;。 如果你想要让自己的小程…

sqllab第十九关通关笔记

知识点&#xff1a; 错误注入 最大长度为32位&#xff1b;如果目标长度>32时&#xff0c;需要利用截取函数进行分段读取referer注入 insert语句update语句 通过admin admin进行登录发现页面打印除了referer字段的信息 这应该是一个referer注入 首先进行测试一下 构造payl…

实现elasticsearch和数据库的数据同步

1. 数据同步 elasticsearch中的酒店数据来自于mysql数据库&#xff0c;因此mysql数据发生改变时&#xff0c;elasticsearch也必须跟着改变&#xff0c;这个就是elasticsearch与mysql之间的数据同步。 1.1. 思路分析 常见的数据同步方案有三种&#xff1a; 同步调用 异步通知…

在macOS上安装Homebrew教程

1.打开终端&#xff1a; 打开Finder&#xff0c;转到应用程序 > 实用工具文件夹&#xff0c;然后双击终端.app。 或者&#xff0c;使用Spotlight搜索&#xff08;按下 Command(⌘) Spacebar&#xff09;并输入“终端”&#xff0c;然后回车以打开。 也可以像我一样把终端…

【SQL Server】实验五 视图

1 实验目的 掌握SQL视图语句的基本使用方法&#xff0c;如CREATE VIEW、DROP VIEW。掌握视图更新、WITH CHECK OPTION等高级功能的使用。 2 实验内容 2.1 掌握SQL视图语句的基本使用方法 创建视图&#xff08;省略视图列名&#xff09;。创建视图&#xff08;不能省略列名的…

(三)丶RabbitMQ的四种类型交换机

前言&#xff1a;四大交换机工作原理及实战应用 1.交换机的概念 交换机可以理解成具有路由表的路由程序&#xff0c;仅此而已。每个消息都有一个称为路由键&#xff08;routing key&#xff09;的属性&#xff0c;就是一个简单的字符串。最新版本的RabbitMQ有四种交换机类型&a…

专业无网设备如何远程运维?向日葵远程控制能源场景案例解析

清洁能源领域&#xff0c;拥有庞大的上下游产业链&#xff0c;涉及的相关工业设备门类多、技术覆盖全、行业应用广。在这一领域内&#xff0c;相关专业设备的供应商的核心竞争力除了本身产品的技术能力之外&#xff0c;服务也是重要的一环。 某企业作为致力于节能环保方向的气…

XML语言的学习记录1

学习笔记&#xff1a; xml&#xff08;可扩展标记语言&#xff09;语言没有预定义的标签&#xff0c;都是使用者自定义&#xff1b;xml是纯文本&#xff0c;是不作为的&#xff1b;语法 每个标签必须有关闭标签&#xff1b;对大小写敏感&#xff1b;最外层必须有根元素&#x…

使用FFmpeg源码配置程序configure查看所有支持的编码器/解码器/封装/解封装及网络协议

查看支持编码器: configure --list-encoders 查看支持编码器: configure --list-decoders 查看所有支持的封装: configure --list-muxers 查看所有支持的解封装: configure --list-demuxers 查看所有支持的网络通信协议: configure --list-protocols

微服务学习day02 -- nacos配置管理 -- Feign远程调用 -- Gateway服务网关

0.学习目标 1.Nacos配置管理 Nacos除了可以做注册中心&#xff0c;同样可以做配置管理来使用。 1.1.统一配置管理 当微服务部署的实例越来越多&#xff0c;达到数十、数百时&#xff0c;逐个修改微服务配置就会让人抓狂&#xff0c;而且很容易出错。我们需要一种统一配置管理…

K8S CNI

OCI概念 OCI&#xff0c;Open Container Initiative&#xff0c;开放容器标准&#xff0c;是一个轻量级&#xff0c;开放的治理结构&#xff08;项目&#xff09;&#xff0c;在 Linux 基金会的支持下成立&#xff0c;致力于围绕容器格式和运行时创建开放的行业标准。 OCI 项目…

Unity中的网格创建和曲线变形

Unity中的网格创建和曲线变形 3D贝塞尔曲线变形贝塞尔曲线基础线性公式二次方公式三次方公式 Unity 实现3D贝塞尔曲线变形准备工作脚本概述变量定义 变量解析函数解析 获取所有子节点GetAllChildren 获取所有子节点UpdateBezierBend 控制点更新CalculateBezier Bezier 曲线公式…

JumpServer部署使用

1. 简介 JumpServer 是全球首款开源的堡垒机&#xff0c;使用 GNU GPL v3.0 开源协议&#xff0c;是符合 4A 规范的运维安全审计系统&#xff0c;使用 Python 开发&#xff0c;遵循 Web 2.0 规范&#xff0c;配备了业界领先的 Web Terminal 方案&#xff0c;交互界面美观、用户…

常见的实时操作系统(RTOS)(嵌入式和物联网操作系统)介绍

在嵌入式系统和物联网&#xff08;IoT&#xff09;设备中&#xff0c;实时操作系统&#xff08;RTOS&#xff09;是至关重要的&#xff0c;因为它们负责管理有限的硬件资源&#xff0c;并提供确保任务在特定时间内完成的机制。开源实时操作系统&#xff08;RTOS&#xff09;允许…

【Python】清理conda缓存的常用命令

最近发现磁盘空间不足&#xff0c;很大一部分都被anaconda占据了&#xff0c;下面是一些清除conda缓存的命令 清理所有环境的Anaconda包缓存 删除所有未使用的包以及缓存的索引和临时文件 conda clean --all清理某一特定环境的Anaconda包缓存 conda clean --all -n 环境名清…

离线安装docker、docker-compose、Mysql镜像

离线安装docker docker-compose mysql镜像 一、下载docker docker-compose mysql 镜像文件 1、首先下载docker镜像 博主所用文件版本号&#xff1a; docker-23.0.6.tgz 下载docker 地址 &#xff1a;https://blog.csdn.net/xiaohanshasha/article/details/135489623?spm1001…

Vue前端开发记录(一)

本篇文章中的图片均为深色背景&#xff0c;请于深色模式下观看 说明&#xff1a;本篇文章的内容为vue前端的开发记录&#xff0c;作者在这方面的底蕴有限&#xff0c;所以仅作为参考 文章目录 一、安装配置nodejs,vue二、vue项目目录结构三、前期注意事项0、组件1、数不清的报…

移远通信亮相AWE 2024,以科技力量推动智能家居产业加速发展

科技的飞速发展&#xff0c;为我们的生活带来了诸多便利&#xff0c;从传统的家电产品到智能化的家居设备&#xff0c;我们的居家生活正朝着更智能、更便捷的方向变革。 3月14日&#xff0c;中国家电及消费电子博览会&#xff08;Appliance&electronics World Expo&#xf…

腾讯云对象存储的在Java使用步骤介绍

腾讯云对象存储的在Java使用步骤介绍 创建一个腾讯云的账户 这个自己去创建&#xff0c;然后开通对象存储服务&#xff0c;如下 有了账号就要创建一个对象存储的桶&#xff0c;也就是存储对象的一个容器 如果你想只有自己放存放的就设置 私有读写 &#xff0c;如果想用网络直…

fs模块 练习题

编写程序&#xff1a; 在文件夹data里有文件a.txt和文件b.txt。将文件a.txt和文件b.txt的内容读取后写入文件c.txt中。 一、同步读取 const fs require(fs); let datas1fs.readFileSync(./data/a.txt); let datas2fs.readFileSync(./data/b.txt); let datas3datas1datas2;//对…