第一个SpringMVC程序

一、SpringMVC简介

SpringMVC:是基于spring的一个框架, 实际上就是spring的一个模块, 专门是做web开发的,理解是servlet的一个升级

web开发底层是servlet , 框架是在servlet基础上面加入一些功能,让你做web开发方便

SpringMVC就是一个Spring

Spring是容器,ioc能够管理对象,使用<bean>,@Component,@Repository,@Service,@Controller
SpringMVC能够创建对象, 放入到容器中(SpringMVC容器), springmvc容器中放的是控制器对象,我们要做的是 使用@Contorller创建控制器对象, 把对象放入到springmvc容器中, 把创建的对象作为控制器使用这个控制器对象能接收用户的请求, 显示处理结果,就当做是一个servlet使用

  • 使用@Controller注解创建的是一个普通类的对象, 不是Servlet。 springmvc赋予了控制器对象一些额外的功能

web开发底层是servlet, springmvc中有一个对象是Servlet : DispatherServlet(中央调度器)

DispatherServlet: 负责接收用户的所有请求, 用户把请求给了DispatherServlet, 之后DispatherServlet把请求转发给我们的Controller对象, 最后是Controller对象处理请求

二、第一个注解的SpringMVC程序

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

完成功能:用户提交一个请求,服务器处理器在接收到这个请求后,给出一条欢迎信息,在响应页面中显示该信息

1. 新建maven web项目

可以看之前写的完整建项目过程

https://www.cnblogs.com/mengd/p/13436355.html

或这样,先建立一个空的项目

然后在这个空项目里建立module

创建成功:

由于文件目录有缺少,这时哦我们自己添加必要的目录,并转换为对应的

2. pom.xml

加入Servlet依赖和SpringMVC依赖

下面是完整的pom.xml文件

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.md</groupId>
  <artifactId>01-hello-springmvc</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>



  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>

    <!-- servlet的依赖-->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>


    <!-- springmvc的依赖-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>5.2.5.RELEASE</version>
    </dependency>

  </dependencies>

  <build>

  </build>
</project>

3. 注册中央调度器

打开web.xml文件,默认的是这样的

由于这个版本太低了,所以需要换成这样的,可以直接复制之前写的,粘贴到这就可以了

主要内容看下面写的注释

在web.xml文件里

<?xml version="1.0" encoding="UTF-8"?>
<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_4_0.xsd"
         version="4.0">


    <!-- 声明,注册springmvc的核心对象DispatcherServlet
        需要是tomcat服务器启动之后,创建DispatcherServlet对象的实例
        why?
        因为DispatcherServlet在它创建的过程中,会同时创建springmvc容器对象,
        读取springmvc的配置文件,把这个配置文件中的对象都创建好,
        当用户发起请求的时候就可以直接的调用对象了


        原理:
          servlet的初始化会执行init()方法。 DispatcherServlet在init()中{
           //创建容器,读取配置文件
           WebApplicationContext ctx = new ClassPathXmlApplicationContext("springmvc.xml");
           //把容器对象放入到ServletContext中
           getServletContext().setAttribute(key,ctx);
        }


        启动tomcat报错,读取这个文件 /WEB-INF/springmvc-servlet.xml(/WEB-INF/myweb-servlet.xml)
        springmvc创建容器对象时,读取的配置文件默认是/WEB-INF/<servlet-name>-servlet.xml .
     -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>


        <!--自定义springmvc的配置文件的位置-->
        <init-param>
            <!--springmvc的配置文件的位置属性-->
            <param-name>contextConfigLocation</param-name>
            <!--指定自定义文件的位置,也就是resources目录下-->
            <param-value>classpath:springmvc.xml</param-value>
        </init-param>



        <!-- 在Tomcat启动后,创建Servlet对象

        load-on-startup:表示tomcat启动后创建对象的顺序,值是整数,
                        值越小(>=0),tomcat创建对象的时间越早,

        -->
        <load-on-startup>1</load-on-startup>
    </servlet>


    <!--用户使用.do的请求都经过这里 -->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>

        <!--
            使用框架时,url-pattern可以有两种值
            1. 扩展名  *.xxx , xxx是扩展名,例如:*.do,*.action等,(建议)

            2. 使用 "/"
        -->
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>



    <!-- 以上内容几乎每个项目都要用,需要改的就是自定义文件的位置和url-pattern-->



</web-app>

4. 创建SpringMVC配置文件

在工程的类路径即 src 目录下resources下创建 SpringMVC 的配置文件 springmvc.xml,

该文件名可以任意命名,但由于我们在注册中央调度器的指定了名字,所以这里用springmvc.xml

5. 创建处理器

在类上与方法上添加相应注解即可
@Controller:表示当前类为处理器
@RequestMapping:表示当前方法为处理器方法。该方法要对 value 属性所指定的 URI进行处理与响应。被注解的方法的方法名可以随意

在src/main/java/com.md.controller的下面建立MyController类作为处理器

package com.md.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

/**
 * @author MD
 * @create 2020-08-12 9:21
 */

// @Controller:创建处理器对象,放在了springmvc的容器中

@Controller
public class MyController {

    // 处理用户提交的请求,springmvc中使用方法来处理
    // 方法是自定义的,可以有多种返回值,多种参数,方法名称自定义

    /**
     * 准备使用doSome方法处理some.do的请求
     * @RequestMapping:请求映射,
     *       作用是把一个请求的地址和一个方法绑定在一起
     *       一个请求指定一个方法处理
     * 属性:
     *  1. value:是一个String,就是页面的请求地址,value的值必须唯一,使用时,推荐"/"开头
     *
     * 位置:
     *  1. 在方法的上面:使用@RequestMapping修饰的方法叫做处理器方法或者控制器方法
     *  2. 在类的上面
     *
     *
     *
     * 返回值:ModelAndView
     * Model:数据,请求处理完成之后,要显示给用户的数据
     * View:视图,比如jsp
     */


//    还可以让多个地址执行这一个方法
//     @RequestMapping(value = {"/some.do","/other.do"})

    @RequestMapping(value = "/some.do")
    public ModelAndView doSome(){
        // 在这个方法中就可以处理some.do的请求了

        //  通常这个时候该调用service了,这里就相当于service的调用完成了

        // 添加数据,框架在请求的最后把数据放入到request作用域中
        // 相当于request.serAttribute("msg","欢迎使用springmvc");
        
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","欢迎使用springmvc");
        mv.addObject("fun","执行的是doSome方法");

        // 指定视图
        // 相当于请求转发
      	mv.setViewName("/show.jsp");
        
        return mv;
    }

}

Model 中的数据存储在 request 作用域中,SringMVC 默认采用转发的方式跳转到视图,本次请求结束,模型中的数据被销毁

6. 声明组件扫描器

在 springmvc.xml 中注册组件扫描器

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">


    <!--声明组件扫描器
		base-package:处理器所在的包
	-->
    <context:component-scan base-package="com.md.controller"/>

</beans>

7. 定义目标页面

在 webapp 目录新建一个 jsp 页面 show.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

    <h1>show.jsp</h1>

    这些都是从request作用域获取到的数据
    <h2>msg:${msg}</h2>

    <h2>fun: ${fun}</h2>

</body>
</html>

这里的数据就是通过处理器转发过来获取到的数据

8. 修改视图解析器的注册

SpringMVC 框架为了避免对于请求资源路径与扩展名上的冗余,在视图解析器InternalResouceViewResolver 中引入了请求的前辍与后辍。而 ModelAndView中只需给出要跳转页面的文件名即可,对于具体的文件路径与文件扩展名,视图解析器会自动完成拼接

在springmvc.xml中

主要注意前缀和后缀

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">

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



    <!--声明springmvc框架中的视图解析器,帮助开发人员设置视图文件路径-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--前缀:视图文件的路径-->
        <property name="prefix" value="/WEB-INF/view/" />

        <!--后缀:视图文件的扩展名-->
        <property name="suffix" value=".jsp"/>

    </bean>
</beans>

此时把目标页面放入到/WEB-INF/view/下面

此时项目的目录是这样的

9. 修改处理器

这个时候直接写目标页面的名字即可,不用写路径和后缀

@Controller
public class MyController {

    @RequestMapping(value = "/some.do")
    public ModelAndView doSome(){
   
        ModelAndView mv = new ModelAndView();
        mv.addObject("msg","执行的是doSome方法");

        // 指定视图
        // 相当于请求转发
      	//mv.setViewName("/show.jsp");
        mv.setViewName("show");
        
        return mv;
    }
}

10. 主页面

也就是index.jsp页面,

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

    <p>第一个springmvc项目</p>
    <p> <a href="some.do">发起some.do的请求</a> </p>
</body>
</html>

此时,配置一下Tomcat这个程序就能运行了,点击 发起some.do的请求 就会跳转到show.jsp页面,并且还可以看到下面的页面

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

四、SpringMVC执行流程

1. 流程图

2. 执行流程简单分析

  1. 浏览器提交请求到中央调度器
  2. 中央调度器直接将请求转给处理器映射器
  3. 处理器映射器会根据请求,找到处理该请求的处理器,并将其封装为处理器执行链后返回给中央调度器
  4. 中央调度器根据处理器执行链中的处理器,找到能够执行该处理器的处理器适配器
  5. 处理器适配器调用执行处理器
  6. 处理器将处理结果及要跳转的视图封装到一个对象 ModelAndView 中,并将其返回给处理器适配器
  7. 处理器适配器直接将结果返回给中央调度器
  8. 中央调度器调用视图解析器,将 ModelAndView 中的视图名称封装为视图对象
  9. 视图解析器将封装了的视图对象返回给中央调度器
  10. 中央调度器调用视图对象,让其自己进行渲染,即进行数据填充,形成响应对象
  11. 中央调度器响应浏览器

相关文章

开发过程中是不可避免地会出现各种异常情况的,例如网络连接...
说明:使用注解方式实现AOP切面。 什么是AOP? 面向切面编程...
Spring MVC中的拦截器是一种可以在请求处理过程中对请求进行...
在 JavaWeb 中,共享域指的是在 Servlet 中存储数据,以便在...
文件上传 说明: 使用maven构建web工程。 使用Thymeleaf技术...
创建初始化类,替换web.xml 在Servlet3.0环境中,Web容器(To...