SpringMVC核心原理 之 MVC初体验

177 阅读4分钟

MVC框架是什么?要做什么?

MVC是一套设计规范。

M(Model):数据模型层。包括Dao层(数据持久层)和Service层(业务层)。完成用户数据的封装,保存数据状态;实现业务逻辑。

V(View):视图层。显示页面。

C(Controller):控制器。取得表单数据;调用业务逻辑;转向指定的页面(重定向或转发)。

MVC框架要做的事情主要是:

  1. 将url映射到java类或java类的方法;
  2. 封装用户提交的数据;
  3. 处理请求-->调用相关的业务逻辑-->封装相应数据;
  4. 将响应的数据渲染到页面

官方文档

SpringMVC原理

Spring的框架是围绕DispatcherServlet设计的。本质就是一个Servlet,接收请求、分派请求、提供业务功能。

SpringMVC的一个完整流程图如下:

image-20220602211350094.png

客户发起请求被前置控制器拦截;控制器根据请求参数生成代理请求;找到请求对应的实际控制器;控制器处理请求,创建数据模型,访问数据库,将模型响应给中心控制器;控制器使用模型与视图渲染视图结果;将结果返回给中心控制器;最后将结果返回给请求者。

简要分析其中的流程步骤:

  1. DispatcherServlet是前置控制器,也是整个SpringMVC的控制中心。 用户发出的请求,会被DispatcherServlet拦截并接收。 假设请求的url为:http://localhost:8080/SpringMVC/hello,该url可以被拆分为三部分:

    1. http://localhost:8080:服务器域名
    2. SpringMVC:部署在服务器上的web站点
    3. hello:控制器

    因此这个url表示:请求位于服务器localhost:8080上的SpringMVC站点的hello控制器。

  2. HandlerMapping为处理器映射。由DispatcherServlet调用。根据请求url查找Handler。

  3. HandlerExecution根据url查找控制器,如上url被查找控制器为:hello。

  4. HandlerExecution将解析后的信息传递给DispatcherServlet,如解析控制器映射等。

  5. HandlerAdapter表示处理器适配器,其按照特定的规则去执行Handler(可以是Controller或Servlet,还可以是Controller中的一个方法)。

  6. Handler让具体的Controller执行。

  7. Controller将具体的执行信息返回给HandlerAdapter,如ModelAndView。

  8. HandlerAdapter将视图逻辑名或模型传递给DispatcherServlet。

  9. DispatcherServlet调用视图解析器(ViewResolver)来解析HandlerAdapter传递的视图逻辑名。

  10. 视图解析器将解析的逻辑视图名传给DispatcherServlet。

  11. DispatcherServlet根据视图解析器解析的视图结果,调用具体的视图。

  12. 将视图呈现给用户。

参考:遇见狂神说

“Special Beans”

上面出现的奇怪名词到底是什么?

Special Beans是一类帮助DispatcherServlet来处理请求并呈现合理响应的特定实例对象。

说人话就是DispatcherServlet是一个派任务的boss,special beans是一群真正在干活的小弟。

HandlerMapping:处理器映射

解析url,并对应到Handler进行处理。

Handler可以是Controller里的一个方法,也可以是Servlet或Controller等。

参考:blog.csdn.net/qq_38262266…

HandlerAdapter:处理器适配器

调用具体的方法对用户请求进行处理。

Controller有很多种不同的类型。当HandlerMapping获取到执行请求的Controller时,DispatcherServlte会根据该Controller对应的Controller类型来调用相应的HandlerAdapter来进行处理。

例如,对于带有注解的Controller,就要调用注解类处理器。

HandlerAdapter的主要作用是对DispatcherServlet屏蔽这类操作。

参考:blog.csdn.net/weixin_3839…

ViewResolver:视图解析器

Controller根据请求执行完业务逻辑之后,返回一个ModelAndView。ModelAndView顾名思义就是一个Model(模型:处理之后的结果数据)和View(视图)。

ViewResolver的任务就是从ModelAndView中将View解析出来。

MVC初体验

试着写一个原生态的SpringMVC项目,发送请求并显示“HelloMVC!”。

一、导入依赖

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
​
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.18</version>
        </dependency>
​
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
        </dependency>
​
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
            <scope>provided</scope>
        </dependency>
​
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
    </dependencies>

一定要确保项目的maven文件中,以及最后jar包的lib目标中都已经成功包含依赖,否则无法运行成功。

IDEA不会自动添加lib依赖,手动加一下。

二、配置web.xml,注册DispatcherServlet

    <!--配置DispatcherServlet:请求分发器,前端控制器。SpringMVC的核心-->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--DispatcherServlet要绑定Spring的配置文件-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-servlet.xml</param-value>
        </init-param>
        <!--设置启动级别:1(服务器启动的时候就同时启动)-->
        <load-on-startup>1</load-on-startup>
    </servlet>
​
​
    <!--在SpringMVC中,/与/*的区别:
        /:只匹配所有的请求,不匹配jsp
        /*:匹配所有的请求,包括jsp页面
    -->
    <servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

三、配置Servlet

新建[servlet_Name]-servlet.xml。(其实就是一个Spring配置文件)

三件事情:

  1. 配置HandlerMapping(Spring提供);
  2. 配置HandlerAdapter(Spring提供);
  3. 配置ViewResolver(Spring提供)。
    <!--Servlet的配置文件,其实就是一个Spring配置文件-->
    <!--SpringMVC核心三要素:-->
    <!--处理器映射器-->
    <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
    <!--处理器适配器-->
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
​
    <!--视图解析器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <property name="suffix" value=".jsp"/>
    </bean>

四、编写Controller处理业务

创建一个Controller,要么实现Controller接口,要么添加注解(对应不同的HandlerAdapter)。

处理具体的业务,并指定返回视图。最后返回一个ModelAndView。

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
​
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
​
public class HelloController implements Controller {
    @Override
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        ModelAndView mv = new ModelAndView();
​
        //业务代码
        //Model。封装数据。
        String result = "HelloMVC!";
        mv.addObject("msg", result);
​
        //视图跳转
        //View。
        mv.setViewName("test"); //:/WEB-INF/jsp/test.jsp
​
        return mv;
    }
}

五、注册bean,将Controller交给Spring托管

在[servlet_Name]-servlet.xml里面把刚刚写的Controller,bean一下。

<!--BeanNameUrlHandlerMapping: bean-->
<bean id="/hello" class="com.chriss.controller.HelloController"/>

六、编写即将跳转的jsp页面

显示“HelloMVC!”

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

七、启动汤姆猫!

image-20220602223927625.png

总结起来说,实际需要编写的只有Controller而已,并且要去相应的配置文件里面注册一下。剩下了其实Spring都帮我们做完了。

对应到开头的流程图,其实只有虚线是需要我们实现的