SpringMVC概述和请求处理流程_springmvc中的对象由谁来处理_卑微-程序员的博客-程序员秘密

技术标签: java  后端  

SpringMVC简介

SpringMVC是基于Spring的一个框架,实际上是Spring的一个模块,专门用来进行web开发。
web开发的底层是servlet,springmvc中有一个对象是Servlet:DispatherServlet(中央调度器),中央调度器负责接收用户的所有请求,用户把请求给调度器,调度器再把请求转发给我们的Controller对象,最后Controller对象处理请求。
Spring是容器,ioc能够管理对象,使用注解SpringMVC能够创建对象,放入容器中,SpringMVC容器中放的是控制器对象,,使用@Controller创建控制器对象,把对象放入SpringMVC容器,此时,可以用创建的对象来接收用户的请求,显示处理结果,当作一个servlet使用。

一个注解的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>

(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>

load-on-startup标签是标记启动web项目时,是否启动这个servlet实例,也就是是否调用执行该servlet的init()方法,而不是在真正访问时创建,它是一个整值。

值大于0的时候,容器启动就加载并初始化这个servlet,数值越小,该servlet的启动优先级就越高;
当值小于0或者没有指定的时候,只有servlet在真正使用的时候才会去创建;
当值相同的时候,容器会自动选择创建顺序。

url-pattern可以使用两个值,一个是扩展名方式,可以使用*.html,*.do等;另外一个则是使用斜杆方式“/”
(3)配置文件位置和名称
中央调度器注册完毕之后,可以在服务器上发布运行,访问浏览器页面控制器会抛出FileNotFoundException异常,默认找WEB-INF目录下的名为-servlet.xml的配置文件,这里的servlet名称指的是注册中央调度器标签中指定的servlet的name值。
一般情况下,配置文件应该在类路径下,也就是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>

(4)创建处理器
在类和方法上添加注解,@Controller表示当前类为处理器。@RequestMapping表示当前方法的处理器方法,该方法应该对value属性所指定的url进行处理和响应。

@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. 有多个请求路径匹配处理器方法的执行,value可以写上一个数组。
  2. ModelAndView类中的addObject()方法用于向Model中添加数据,Model底层是一个HashMap。
  3. Model中的数据存储在request作用域中,SpringMVC默认采用转发跳转到视图,本次请求结束,模型中的数据会被销毁。

(5)创建SpringMVC配置文件:

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

(6)定义目标页面:
在webapp目录下新建一个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>

(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>

使用springmvc框架web请求处理程序

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

SpringMVC执行流程

  1. 浏览器发起请求some.do到中央调度器
  2. 中央调度器接受请求,把请求交给处理器映射器(springmvc框架的一种对象,框架实现了HadlerMapping接口的类叫映射器)(处理映射器会根据请求,从springmvc容器对象中获取处理器对象)(Mycontroller controller = ctx.getBean(“some.do”),框架把找到的处理器对象放入到一个叫处理器执行链(HandlerExceptionChain)的类中保存)(处理器执行链的类保存着处理器对象,项目中的拦截器)
  3. 中央调度器把执行链的处理器对象交给处理器的适配器(springmvc框架中的对象,需要实现HandlerAdapt接口)(执行处理器方法会得到返回值)
  4. 中央处理器把ModelAndView交给视图解析器对象
  5. 中央处理器把创建好的View对象获取到,调用View类自己的方法,把Model数据放入到request作用域中,执行forward,请求结束

执行过程分析

  1. 通过load-on-start标签指定的1,创建DisaptcherServlet对象
  2. DisaptcherServlet它的父类是继承HttpServlet,在被创建时,会执行init方法
  3. 在init方法中,创建容器,读取配置文件:WebApplicationContext ctx = new ClassPathXmlApplicationContext("springmvc.xml");
  4. 把容器放入到ServletContext中:getServletContext().setAttribute(key, ctx);
  5. 容器创建完成后,创建@controller注解所在类的对象,把创建的对象放入到springmvc容器(map)中,类似map.put(“myController”,MyController对象)
  6. 请求处理过程):执行servlet的service()
protected void service(HttpServletRequest request, HttpServletResponse response)

       protected void doService(HttpServletRequest request, HttpServletResponse response)


      DispatcherServlet.doDispatch(request, response){
    

          调用MyController的.addUser( )方法
      }

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/UNknowmer/article/details/113984588

智能推荐

埃里克雷蒙德_关于雷蒙德·钱德勒的著作_cunbei2644的博客-程序员秘密

埃里克雷蒙德I've never been into crime fiction. I mean I've read The Hound of the Baskervilles, but that's about it. I like Douglas Adams, Terry Pratchett, looove Kurt Vonnegut, enjoyed On the Road, Catch-2...

8 种架构设计模式优缺点大曝光 | 原力计划_CSDN资讯的博客-程序员秘密

作者 | 程序员Tony责编 | 王晓曼出品 | 程序员秘密什么是架构我想这个问题,十个人回答得有十一个答案,因为另外的那一个是大家妥协的结果,哈哈,我理解,架构就是骨架。人类的身体的...

OpenCV中随机颜色_Ladd7的博客-程序员秘密

OpenCV中随机颜色、随机数发生器 cv::RNG

棋牌游戏算法——麻将系列总结_棋牌服务器算法_Snovi-的博客-程序员秘密

麻将的胡牌算法,各种不同的麻将类型分析,总结。麻将的查表法,回溯法。

APEX 压枪练习记录_可爱多多白的博客-程序员秘密

背景在领导教育一番"做事要认真"后,周末的游戏也要认真玩一玩。练一下最喜欢的两把中远火力。喷火轻机枪喷火轻机枪 无弹匣 35发子弹,630点伤害35 -&gt; 28,共126点伤害,向右下方向用力拉枪28 -&gt; 25 , 累计180点伤害,向左 稍稍拉枪25 -&gt; 11,累计432点伤害,向右下用力拉枪,最后11发,向左用力拉枪。R301卡宾枪R301卡宾枪 无弹匣 18发子弹,共252点伤害前14发子弹,196点伤害,用力向6点半方向拉枪最后4发子弹,向右稍稍收枪。

自动窗宽窗位的一些思路_普放窗宽窗位自动_天地有道的博客-程序员秘密

自动窗宽窗位可以找到合理的灰度值区间段,在这个区间段最大程度的保留所关注的内容或者整张图像的主要内容。窗宽是灰度值区间的宽度,窗位一般是灰度值区间的中点位置,窗宽窗位的设置是为了最大程度的展现观察者所需要的内容。窗宽窗位是为了展现图像上的内容,在图像的灰度域上能够反映这种程度的工具是直方图,因此设计合理的窗宽窗位就需要在直方图上做文章。自动窗宽窗位的思路是基于直方图,根据自动阈值分割计算出阈值,根据该阈值往两边延拓,是该区间尽可能的包含图像的主要部分。值得注意的是,往左/右方向延拓的大小不一定相同。延拓

随便推点

种植巴旦木树苗栽种间距多少合适?耐干旱吗?_巴旦木一直放在水里吗_普通网友的博客-程序员秘密

巴旦木,作为“四大坚果”之首。因其外形貌似杏仁,所以它还有一个别名叫“巴旦杏”。如果了解巴旦木的人都知道,关于巴旦木有着很多的美誉。像是“千果之王”、“维E之王”。  巴旦木作为世界上有名的果实,那“千果之王”巴旦木到底长什么样的呢?巴旦木鲜果,外表上形似核桃。但在整体的形状上,却又有点偏,所以俗称“偏桃”。巴旦木仁 ,也就是我们常吃的巴旦木坚果。在形状上确实和杏仁有点相似之处,但也有不同的地方。巴旦木仁整体呈扁状,长度上要比杏仁长。  想要种植巴旦木苗木该怎么做?巴旦木树苗适合在什么地方种.

mysql查询优化实例一则_mysql 查询优化 案例_gunsmoke的博客-程序员秘密

原sqlselect * from sys_user WHERE create_date is not null LIMIT 0,10优化后的sqlSELECT *FROM sys_user main_table RIGHT JOIN ( SELECT id FROM sys_user WHERE create_date is not NULL LIMIT 0,10 ) temp_table ON temp_table.id = mai

机器学习算法一览表附opencv机器学习模块_u012507022的博客-程序员秘密

机器学习算法一览表(中英对照)附opencv机器学习模块

2019-3-15-uwp-ScrollViewer-content-out-of-panel-when-set-the-long-width_lindexi_gd的博客-程序员秘密

title author date CreateTime categories uwp ScrollViewer content out of panel when set the long width lindexi 2019-03-15 14:14:24 +0800 2019-03-15 13:...

创新微MinewSemi高精准低功耗UWB模块有哪些优势_MinewSemi创新微的博客-程序员秘密

随着物联网的技术的发展,物联网的应用也越来越广泛。智能家居是物联网的一个发展方向,它以现代的传统家居为基础,运用传感器技术、通信技术、自动化控制技术等形成智能家居。现在,人们的生活水平不断提高,人们开始追求高水平的生活品质,家居环境成为人们首要考虑的问题,同时,现在越来越多的智能设备比如uwb模块的出现,使得测距和定位等问题在物联网发展中得到解决,也促进了智能家居的发展。

METATRADER 5 中的订单、持仓和成交_MetaTrade的博客-程序员秘密

交易术语交易者的终极目标是通过交易操作从金融市场中盈利。本文介绍MetaTrader 5交易平台的术语和流程,这些知识是正确理解 MQL5 语言的交易函数的作用所必不可少的。订单— 交易服务器接收到的交易操作请求,依据 MetaTrader 5 平台要求构成。如果请求不正确,则不会以订单的形式出现在交易平台中。订单可以在指定金融工具中按当前市场价立即执行,例如买入或卖出一定数量。另一类型的订单为挂单,包含承诺在满足一定的条件下进行交易操作的订单。挂单也可以包含对它们的操作的时间限制 - 订单到...

推荐文章

热门文章

相关标签