百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

一、SpringMVC概述和请求处理流程

ccwgpt 2024-11-22 11:34 17 浏览 0 评论

一、SpringMVC概述和请求处理流程

1、 SpringMVC简介

  • SpringMVC是基于Spring的一个框架,实际上就是Spring的一个模块,专门用来做web开发的。
  • web开发底层是servlet, springmvc中有一个对象是Servlet : DispatherServlet(中央调度器)
    DispatherServlet: 负责接收用户的所有请求, 用户把请求给了DispatherServlet, 之后DispatherServlet把请求转发给我们的Controller对象, 最后是Controller对象处理请求。
  • Spring是容器,ioc能够管理对象,使用< bean >, @Component, @Repository, @Service, @Controller,SpringMVC能够创建对象, 放入到容器中(SpringMVC容器), SpringMVC容器中放的是控制器对象, 我们要做的是使用@Contorller创建控制器对象, 把对象放入到SpringMVC容器中, 把创建的对象作为控制器使用。这个控制器对象能接收用户的请求, 显示处理结果,就当做是一个servlet使用。而使用@Controller注解创建的是一个普通类的对象,不是Servlet。 SpringMVC赋予了控制器对象一些额外的功能。

2、第一个注解的SpringMVC程序

  • 所谓 SpringMVC 的注解式开发是指,在代码中通过对类与方法的注解,便可完成处理器在SpringMVC 容器的注册

(1)在pom.xml文件中加入依赖和插件

<dependencies>
  <dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.11</version>
    <scope>test</scope>
  </dependency>
  <dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
  </dependency>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.5.RELEASE</version>
  </dependency>
</dependencies>

<build>
  <plugins>
    <!-- 编码和编译和JDK版本 -->
    <plugin>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.1</version>
      <configuration>
        <source>1.8</source>
        <target>1.8</target>
      </configuration>
    </plugin>
  </plugins>
</build>
123456789101112131415161718192021222324252627282930313233

(2)在web.xml文件中注册中央调度器

<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>*.do</url-pattern>
</servlet-mapping>
1234567891011

A、< load-on-startup/ >

在< servlet/ >中添加< load-on-startup/ >的作用是,标记是否在Web服务器(这里是Tomcat)启动时会创建这个 Servlet 实例,即是否在 Web 服务器启动时调用执行该 Servlet 的 init()方法,而不是在真正访问时才创建。 它的值必须是一个整数。
? 当值大于等于 0 时,表示容器在启动时就加载并初始化这个 servlet,数值越小,该 Servlet
的优先级就越高,其被创建的也就越早;
? 当值小于 0 或者没有指定时,则表示该 Servlet 在真正被使用时才会去创建。
? 当值相同时,容器会自己选择创建顺序。

B、< url-pattern/ >

可以使用两个值:
1、使用扩展名方式,语法:*.xxx,xxx是自定义的扩展名。常用方式 *. html , *.do等等
http://localhost:8080/springmvc/add.html
http://localhost:8080/springmvc/index.html
2、使用斜杆方式,“/”

(3)配置文件位置与名称

  • 中央调度器注册完毕后,可直接在服务器上发布运行。此时,访问浏览器页面,控制台均会抛出 FileNotFoundException 异常。即默认要从项目根下的 WEB-INF 目录下找名称为 Servlet 名称 -servlet.xml 的配置文件。这里的“Servlet 名称”指的是注册中央调度器标签中指定的 Servlet 的 name 值。本例配置文件名springmvc-servlet.xml。
  • 而一般情况下,配置文件是放在类路径下,即 resources 目录下。所以,在注册中央调
    度器时,还需要为中央调度器设置查找 SpringMVC 配置文件路径,及文件名。
<servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <!--自定义springmvc读取配置文件的位置-->
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:springmvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>*.do</url-pattern>
</servlet-mapping>
12345678910111213141516

(4)创建处理器

  • 在类上与方法上添加相应注解即可。
  • @Controller:表示当前类为处理器
  • @RequestMapping:表示当前方法为处理器方法。该方法要对 value 属性所指定的 URI 进行处理与响应,被注解的方法的方法名可以随意。
@Controller
public class MyController {
    /**
     * 处理用户提交的请求,springmvc中是使用方法来处理的
     * 方法是自定义的,可以有多种返回值
     */

    /**
     * @RequestMapping:请求映射,作用是把一个请求地址和一个方法绑定在一起
     *                  一个请求指定一个方法处理
     * 属性:
     *  1、value是一个String类型的,表示请求的地址(addUser.html)
     *
     * 说明:使用RequestMapping修饰的方法叫做处理器方法或者控制器方法,
     *          它作用类似Servlet中的doGet(),doPost()方法
     *
     * 返回值:ModelAndView,表示请求的处理结果
     *          Model:请求处理完显示给用户的数据
     *          View:视图,比如jsp等等
     */
    @RequestMapping(value = "/addUser.do")
    public ModelAndView addUser(){
        //该方法addUser.html的请求,这里不在调用service请求处理了,
        // 直接相当于service调用处理完成了
        ModelAndView mv = new ModelAndView();

        //添加数据
        //框架在请求的最后把数据放入到request作用域中
        //request.setAttribute("zs","张三");
        mv.addObject("zs","张三");
        mv.addObject("lisi","李四");

        //指定视图的完整路径
        //框架对视图执行的转发操作
        //request.getRequestDispather("/jsp/show.jsp").forward(request,response);
        //mv.setViewName("/jsp/show.jsp");
        //mv.setViewName("/WEB-INF/jsp/show.jsp");

        //当配置了视图解析器
        //框架会使用视图解析器的(前缀+文件名+后缀)组成完整路径
        //   /WEB-INF/jsp/+show+.jsp
        mv.setViewName("show");
        //返回视图
        return mv;
    }

    @RequestMapping(value = {"/remove.html","/remove1.html"})
    public ModelAndView removeUser(){
        ModelAndView mv = new ModelAndView();
        mv.addObject("zs","删除张三");
        mv.addObject("lisi","删除李四");
        mv.setViewName("show");
        return mv;
    }
}
 

1、若有多个请求路径均可匹配该处理器方法的执行,则@RequestMapping 的 value 属性中可以写上一个数组。
2、ModelAndView 类中的 addObject()方法用于向其 Model 中添加数据。Model 的底层为一个 HashMap。
3、Model 中的数据存储在 request 作用域中,SringMVC 默认采用转发的方式跳转到视图,本次请求结束,模型中的数据被销毁

(5)创建SpringMVC配置文件

<!--声明组件扫描器-->
<context:component-scan base-package="com.hcz.controller"/>

123

(6)定义目标页面

  • 在 webapp 目录下新建一个子目录 jsp,在其中新建一个 jsp 页面 show.jsp。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
    <head>
        <title>显示页面</title>
    </head>
    <body>
        <h3>显示用户姓名</h3><br>
        <p>姓名:${zs}</p><br>
        <p>姓名:${lisi}</p>
    </body>
</html>
1234567891011

(7)修改SpringMVC配置文件

  • SpringMVC 框架为了避免对于请求资源路径与扩展名上的冗余,在视图解析器
    InternalResouceViewResolver 中引入了请求的前辍与后辍。而 ModelAndView 中只需给出要跳转页面的文件名即可,对于具体的文件路径与文件扩展名,视图解析器会自动完成拼接。
<!--声明视图解析器-->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <!--前缀:视图文件路径-->
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <!--后缀:视图文件扩展名-->
    <property name="suffix" value=".jsp"/>
</bean>
1234567

3、使用SpringMVC框架web请求处理顺序

  • (1)用户发起addUser.do请求
  • (2)Tomcat服务器通过 web.xml配置文件中的DispatcherServlet的url-pattern将后缀名为 .do的文件交给DispatcherServlet
  • (3)DispatcherServlet根据spring.xml配置文件组件扫描器知道@RequestMapping(value=“addUser.do”)
  • (4)DispatcherServlet把addUser.do转发给MyController的addUser()方法处理
  • (5)框架执行addUser()方法把得到ModelAndView进行处理, 转发到show.jsp

下图是请求的处理顺序图:

SpringMVC的MVC组件图:

4、SpringMVC执行流程图

流程分析:

(1)浏览器发起请求some.do到中央调度器DispatcherServlet

(2)DispatcherServlet接收请求some.so,把请求交给处理器映射器
处理器映射器:springmvc框架中的一种对象,框架把实现了HandlerMapping接口的类都叫做映射器(多个)
处理器映射器的作用:根据请求,从springmvc容器对象中获取处理器对象
MyController controller = ctx.getBean(“some.do”);
框架把找到的处理器对象放入到一个叫做处理器执行链(HandlerExecutionChain)的类中保存
HandlerExecutionChain:类中保存着
1)处理器对象(MyController)
2)项目中的所有的拦截器List< HandlerInterceptor >

(3)DispatcherServlet把(2)中的HandlerExceptionChain中的处理器对象交给了处理器适配器对象(多个)
处理器适配器:springmvc框架中的对象,需要实现HandlerAdapt接口
处理器适配器作用:执行处理器方法(调用MyController.doSome()得到返回值ModelAndView)

(4)DispatcherServlet把(3)中获取的ModelAndView交给视图解析器对象
视图解析器:springmvc框架中的对象,需要交给ViewResoler接口(多个)
视图解析器作用:组成视图完整路径,使用前缀和后缀,并创建view对象
InternalResourceView:视图类,表示jsp文件,视图解析器会创建InternalResourceView对象,这个对象里有一个属性url=/WEB-INF/view/show.jsp

(5)DispatcherServlet把(4)中创建好的View对象获取到,调用View类自己的方法,把Model数据放入到request作用域中,执行对象视图forward,请求结束。

5、SpringMVC执行过程源码分析

(1)创建容器过程

A、通过load-on-start标签指定的1,创建DisaptcherServlet对象

B、DisaptcherServlet它的父类是继承HttpServlet的, 它是一个serlvet, 在被创建时,会执行init()方法。

C、 在init()方法中,创建容器,读取配置文件

 WebApplicationContext ctx = new ClassPathXmlApplicationContext("springmvc.xml");
1

D、把容器对象放入到ServletContext中

getServletContext().setAttribute(key, ctx);
1

E、创建好容器后,创建@controller注解所在的类的对象, 创建MyController对象,这个对象放入到 springmvc的容器中,容器是map ,类似 map.put(“myController”,MyController对象)

(2)请求处理过程

1)执行servlet的service()

protected void service(HttpServletRequest request, HttpServletResponse response)

       protected void doService(HttpServletRequest request, HttpServletResponse response)


      DispatcherServlet.doDispatch(request, response){

          调用MyController的.addUser( )方法
      }
123456789

doDispatch:springmvc中DispatcherServlet的核心方法, 所有的请求都在这个方法中完成的。

文章来源于 微信公众号

相关推荐

VUE3前端开发入门系列教程二:使用iView框架辅助开发

1、安装iView新框架,支持VUE3npminstallview-ui-plus2、编辑src/main.js,添加以下内容,导入js和css到项目importViewUIPlusfrom...

万能前端框架uni app初探03:底部导航开发

前言本节我们使用uniapp的底部导航功能,点击不同tab会显示不同页面,这个功能在实际项目开发中几乎是必备的。一、基础知识1.tabBar如果应用是一个多tab应用,可以通过tabBar配...

Rust Web 开发框架,前端你可以选择哪个?

Rust构建一切。在如今流行的语言中,Rust可谓是将构建和高效作为自己优美的身姿在大众视野中脱颖而出。它是一门赋予每个人构建可靠且高效软件能力的语言。它有什么特性呢?高性能。Rust速度惊人且内...

连载:前端开发中纠结的Javascript框架(上)

如今,前端开发有着许许多多的框架和库。其中一些好用,一些却不尽人意。通常我们会习惯性运用某一概念,模块或句法。事实上,并没有什么万能工具。这篇文章是关于未来框架的发展趋势——那就是没有框架!我从以下几...

前端开发框架的演进架构:提升用户体验和开发效率

前端开发框架是现代Web应用开发的重要工具,它不仅可以帮助开发者构建复杂的用户界面,还能够提升用户体验和开发效率。随着Web技术的不断发展,前端开发框架也在不断演进,为开发者提供了更丰富、更高效的工具...

Google应用Mesh-TensorFlow框架,让CNN也能处理超高分辨率图像

为了要处理超高分辨率医疗图像数据,Google开发了一种空间数据分区(SpatialPartition)技术,在不牺牲图像分辨率的条件下,分析超高分辨率图像。Google使用Mesh-TensorF...

大模型安全挑战加剧:框架层漏洞成新靶心

近日,360数字安全集团发布了一份关于大模型安全漏洞的报告,揭示了当前大模型及围绕其构建的框架和应用中存在的严重安全问题。报告显示,360近期研究发现了近40个大模型相关的安全漏洞,其中既包括二进制内...

Keras 3.0正式发布:可用于TensorFlow、JAX和PyTorch

机器之心报道编辑:陈萍经过5个月的更新迭代,Keras3.0终于来了。「大新闻:我们刚刚发布了Keras3.0版本!」Keras之父FrancoisChollet在X上激动的...

TensorFlow和Keras入门必读教程(tensorflow与keras版本对应)

导读:本文对TensorFlow的框架和基本示例进行简要介绍。作者:本杰明·普朗什(BenjaminPlanche)艾略特·安德烈斯(EliotAndres)来源:华章科技01TensorFlo...

谷歌官方回应“TensorFlow遭弃”:还在投资开发,将与JAX并肩作战

鱼羊发自凹非寺量子位|公众号QbitAI终于,谷歌出面回应“TensorFlow遭弃”传闻:我们将继续致力于将TensorFlow打造为一流机器学习平台,与JAX并肩推动机器学习研究。这段时...

2025 年的PHP :现代 Web 开发的强大引擎

程序员还在吐槽PHP过时?2025年的PHP8.4直接封神了。看看最近更新的属性钩子、强类型系统,加上Laravel这些框架,老语言早就脱胎换骨。十年前说PHP弱类型容易崩代码的,现在脸疼不?联合类...

前端内卷终结者?htmx如何让开发者告别200行JS只做一个按钮

当你用React写一个点赞按钮需要引入3个状态管理库、编写80行JSX和120行钩子函数时,htmx只需要一行HTML:<buttonhx-post="/like"hx-sw...

NativePHP桌面版V1.0正式发布(元气桌面电脑版下载)

导读:各位小伙伴,使用PHP构建桌面级系统的利器,NativePHP来了。概述NativePHP是一个用于使用PHP构建桌面应用的框架。它允许PHP开发人员使用熟悉的工具和技术创建跨平台的原生应用...

PHP Laravel框架底层机制(php基本框架)

当然可以,Laravel是最受欢迎的PHP框架之一,以优雅的语法和丰富的生态而闻名。尽管开发体验非常“高端”,它的底层其实是由一系列结构清晰、职责分明的组件构成的。下面我从整体架构、核心流程、...

PHP框架之Laravel框架教程:2. 控制器、路由、视图简单介绍

2.控制器、路由、视图简单介绍我们先建立控制器,目录是:app/Http/Controllers,新建控制器Ding.php,代码如下:Ding.php:<?phpnamespaceA...

取消回复欢迎 发表评论: