什么是Spring MVC

Spring MVC是Spring Framework的一部分,是基于Java实现MVC的轻量级Web框架。

官方文档:https://docs.spring.io/spring-framework/docs/4.3.24.RELEASE/spring-framework-reference/html/mvc.html

Spring MVC的特点:

  • 轻量级,简单、灵活、易用。
  • 高效,基于请求响应的MVC框架(发送一个请求,就会响应一个视图)
  • 作为Spring的一部分,享受了Spring的所有便利。
  • 约定大于配置。
  • 功能强大:RESTful、数据验证(手机号码,邮箱格式验证等)、格式化、本地化、主题等。

Spring MVC原理

官方原理图如下:

java mvc工作原理 spring spring mvc原理图_mvc

中文版原理图:

java mvc工作原理 spring spring mvc原理图_xml_02

SpringMVC框架是围绕DispatcherServlet设计的,对应原理图中的前端控制器。

  • DispatcherServlet本质上是一个调度Servlet。
  • DispatcherServlet的作用是将请求分发到不同的处理器。
  • Spring2.5开始,基于注解形式开发,十分简洁。

java mvc工作原理 spring spring mvc原理图_spring_03

Spring MVC执行流程如下:

java mvc工作原理 spring spring mvc原理图_spring_04

实线表示Spring MVC已经实现好的,只有虚线是需要自己实现的。

执行流程:

1、DispatcherServlet表示前端控制器

DispatcherServlet是整个Spring MVC的控制中心,用户发出请求,DispatcherServlet接收并拦截请求。

  • http://localhost:8080:服务器域名
  • springmvc_war:部署在web服务器上的工程站点。
  • /hello:表示控制器Controller
  • 如上url表示:请求位于服务器http://localhost:8080 上的 springmvc_war 站点的 hello控制器。

2、HandlerMapping为处理器映射

DispatcherServlet调用HandlerMapping,后者根据请求url查找Handler。

3、HandlerExecution是具体的Handler

  • 主要作用是根据url查找控制器
  • url:http://localhost:8080/springmvc_war/hello,查找的控制器是:/hello
  • HandlerExecution将解析后的信息传递给DispatcherServlet。如解析后的控制器映射等。

4、HandlerAdapter为处理器适配器

  • 按照特定的规则去执行Handler
  • Handler让具体的Controller执行。
  • Controller将执行结果,包括数据和视图信息,封装到ModelAndView。并返回给HandlerAdapter。
  • HandlerAdapter将ModelAndView传递给DispatcherServlet。

5、ViewResolver视图解析器

  • DispatcherServlet调用视图解析器ViewResolver来解析ModelAndView中的视图名
  • 将解析后的视图名传递给DispatcherServlet。
  • DispatcherServlet根据视图名,调用具体的视图。
  • 渲染视图,返回呈现。

HelloSpringMVC

Spring2.5以后,使用注解开发SpringMVC功能十分强大。但是为了更清楚了解SpringMVC原理,最佳实践是动手实现。

1、web.xml配置

  • 在web.xml中配置DispatcherServlet
<?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">

    <!--注册DispatcherServlet-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--关联一个springmvc的配置文件,命名规则为:【servlet-name】-servlet.xml-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!--/ 匹配所有的请求:不包括.jsp-->
    <!--/* 匹配所有的请求:包括.jsp-->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

2、DispatcherServlet对应sping bean文件配置

  • 一个DispatcherServlet需要关联一个spring bean配置文件。
  • 根据官方命名规则:【servlet-name】-servlet.xml,此处为springmvc-servlet.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--添加处理器映射-->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
    <!--添加处理器适配-->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
     <!--添加视图解析器:解析DispatcherServlet给它的ModelAndView
      1、获得ModelAndView中的数据
      2、解析ModelAndView中的视图名字
      3、拼接视图完整文件名,找到视图 /WEB-INF/jsp/XXX.jsp
      4、将数据渲染到这个视图上
      -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="internalResourceViewResolver">
        <!--前缀-->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!--后缀-->
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

3、编写Controller

Controller负责解析用户请求,进行业务处理,并返回一个模型。

Controller通过实现接口和注解定义两种方法实现。

实现了Controller接口的类就是控制器,这是较老的方法。

一个控制器类只能有一个方法。多个方法要写多个controller。

public class MyController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
        //ModelAndView 模型和视图
        ModelAndView mv=new ModelAndView();
        //封装对象,放在ModelAndView中
        mv.addObject("msg", "Hello!SpringMVC!~~");
        //封装要跳转的视图,放在ModelAndView中。
        mv.setViewName("hello"); //WEB-INF/jsp/hello.jsp
        return mv;
    }
}

4、把Controller注册到Spring

由于处理器映射使用了BeanNameUrlHandlerMapping,必须要在Spring文件中注册Controller。

  • bean的id属性值为:斜杠/+控制器Controller。此处为"/hello"。
  • Controller的id与服务器域名http://localhost:8080,工程包/springmvc_war,一起组成完整的请求url。
  • 在浏览器输入url:http://localhost:8080/springmvc_war/hello
  • 请求/hello,直接映射到"controller.MyController"控制器。
<!--id为斜杠/+控制器Controller,HandlerMapping根据url映射到controller-->
<bean id="/hello" class="controller.MyController" />

5、编写要跳转的.jsp页面文件

此处跳转到hello.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Zuka</title>
</head>
<body>
${msg}
</body>
</html>

6、启动Tomcat测试

  • 在 Tomcat部署工程

点击运行后,默认页面弹出,展示index.jsp内容。对应链接:http://localhost:8080/springmvc_war

java mvc工作原理 spring spring mvc原理图_mvc_05

在链接末尾加上hello,对应链接:http://localhost:8080/springmvc_war/hello 。

该URL映射到MyController处理。返回页面展示hello.jsp内容。也就是MyController中 msg字段值。

java mvc工作原理 spring spring mvc原理图_spring_06