Spring MVC的前端控制器配置(servlet+DispatcherServlet)

一、概述

1、springMVC是Spring框架内置的MVC的实现。SpringMVC就是一个Spring内置的MVC子框架,也就是说SpringMVC的相关包都在Spring框架里面。

MVC设计模式?

M(Molde模型)、V(View视图)、C(Control控制器),MVC设计模式是一种解决页面代码和后台代码分离的设计思想。这也是SpringMVC的设计理念。

2、SpringMVC的作用?

支持方法和请求一一对应、支持数据的自动封装、自动支持上传组件、自动支持JSON的转成、...

3、MVC的 "作用域"

配置流程图:

在流程控制图中我们为什么要有一个核心控制器呢?(DispatcherServlet)

因为我们必须要有一个核心控制器(也可以叫拦截器)拦截请求过来的方法,从而实现了请求与方法一一对应

二、前端控制器配置方式(servlet单一配置+DispatcherServlet集中配置)

1、web.xml的作用:

服务器(Tomcat)启动 Web 项目时,自动读取 WEB-INF/web.xml; 用来配置整个 Web 应用的全局规则、过滤器、监听器、Servlet、启动参数、欢迎页面、错误页面等,指导 Tomcat 如何加载、运行当前 web 工程。

2、前端控制器servlet单一管理

传统方式写多个 Servlet,一个功能对应一个 Servlet

xml 复制代码
<!--servlet地址找后台controller-->
    <!--servlet-name:servlet别名-->
<servlet>
    <servlet-name>springmvc2</servlet-name>
    <!--servlet-class:servlet完整类名-->
    <servlet-class>com.controller.HelloController2</servlet-class>
    </servlet>



    <servlet>
    <servlet-name>springmvc1</servlet-name>
    <!--servlet-class:servlet完整类名-->
    <servlet-class>com.controller.HelloController1</servlet-class>
    </servlet>


<servlet-mapping>
        <!--前端url和后台servlet的映射-->
        <!--servlet-name:servlet别名-->
        <servlet-name>springmvc1</servlet-name>
        <url-pattern>/</url-pattern>
        <!--url-pattern定义哪些请求地址  交给对应的 Servlet 处理-->
    </servlet-mapping>



<servlet-mapping>
        <!--前端url和后台servlet的映射-->
        <!--servlet-name:servlet别名-->
        <servlet-name>springmvc2</servlet-name>
        <url-pattern>/</url-pattern>
        <!--url-pattern定义哪些请求地址  交给对应的 Servlet 处理-->
    </servlet-mapping>

后台代码:

java 复制代码
//<servlet-class>com.controller.HelloController1</servlet-class>入口找到HelloController1 


public class HelloController1 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //1.获取前端请求的参数
         String method = req.getParameter("msg");
     //2.对前端的数据进行判断处理
     ......
     //3、调用业务代码
     ......
     //4、视图转发
         req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req,resp);


    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
java 复制代码
//<servlet-class>com.controller.HelloController2</servlet-class>入口找到HelloController1 
public class HelloController2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    //1.获取前端请求的参数
         String method = req.getParameter("msg");
     //2.对前端的数据进行判断处理
     ......
     //3、调用业务代码
     ......
     //4、视图转发
         req.getRequestDispatcher("/WEB-INF/jsp/test.jsp").forward(req,resp);


    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

执行思路:

1、根据映射中名称找到中的servlet-name名称然后定位到具体的com.controller.HelloController1(类的全路径),

2、根据映射别名找到servlet名字在定位到具体的类

3、单一的servlet每次通过外部访问需要配置大量的servlet,一个功能对应一个 Servlet

3、前端控制器DispatcherServlet集中管理(xml+注解)

DispatcherServlet(前端控制器 / 分发器 Servlet)

DispatcherServlet 本身是一个 HttpServlet(建立在 Servlet 规范之上,SpringMVC 的入口核心)

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

    <!-- 1.注册前端控制器 DispatcherServlet -->
    <servlet>
        <servlet-name>dispatcherServlet</servlet-name>
        <!-- SpringMVC核心前端控制器全类名 -->
        <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:服务器启动时实例化Servlet
             数值越小,优先级越高;不配置则第一次访问才创建 -->
        <load-on-startup>1</load-on-startup>
    </servlet>

    <!-- 2.请求映射:指定哪些请求交给DispatcherServlet处理 -->
    <servlet-mapping>
        <servlet-name>dispatcherServlet</servlet-name>
        <!-- 重要:使用 / ,不要写 /* -->
        <url-pattern>/</url-pattern>
    </servlet-mapping>

</web-app>

DispatcherServlet 模型:一对多

所有请求统一进入这唯一的 Servlet DispatcherServlet 内部依靠 HandlerMapping、HandlerAdapter,再分发到各个@Controller

2、web.xml:传统开启DispatcherServlet入口
xml 复制代码
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>

</servlet>
<!--实例化参数-->
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc-servlet.xml</param-value>
        </init-param>


<servlet-mapping>
        <servlet-name>springmvc</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

springmvc-servlet.xml:

通过反射机制直接拿到类BeanNameUrlHandlerMapping、SimpleControllerHandlerAdapter,InternalResourceViewResolver-

1、HandlerMapping:URL → 找到处理器 Controller

xml 复制代码
 <!--1、处理器映射器:找到controller-->
 <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>

2、HandlerAdapter:调用执行 Controller 方法

xml 复制代码
 <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>

3、ViewResolver:逻辑视图名 → 真实页面视图

xml 复制代码
 <!--3、视图解析器:真实的页面视图-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
        <!--属性标签property类中的属性:获取类中的属性名name,并赋值value-->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!--<property> → 给对象 set 赋值
        等价
       传统的 对象名.setAdd(String name){this.name=name}进行赋值
        -->
        <!--后缀-->
        <property name="suffix" value=".jsp"/>
!--bean注册定义的对象-->
   <bean id="/hello" class="com.controller.HelloController"/>
    <!-- 根据<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
    找到class="com.controller.HelloController自定义的controller控制层
    -->

后台:HelloController mplements Controller

java 复制代码
public  class HelloController implements Controller {
    public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
        //ModelAndView 模型和视图
        //模型存储数据  视图:跳转页面
        ModelAndView mv = new ModelAndView();
        //调用业务层--业务代码
        //封装对象,放在ModelAndView中。Model
        mv.addObject("msg","HelloSpringMVC!");//存数据
        //封装数据要跳转的视图并显示,放在ModelAndView中
        mv.setViewName("hello"); //: /WEB-INF/jsp/hello.jsp
        System.out.println(mv.getView());
        return mv;
    }
}
3、注解:开启DispatcherServlet入口
xml 复制代码
!--1.注册servlet、配置前端控制器的入口DispatcherServlet-->
    <servlet>
        <servlet-name>SpringMVC</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!--DispatcherServlet前端控制器集中管理-->
        <!--通过初始化参数指定SpringMVC配置文件的位置,进行关联-->
        <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>
    <!--所有请求都会被springmvc拦截 -->
    <servlet-mapping>
        <servlet-name>SpringMVC</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

springmvc-servlet.xml:

xml 复制代码
 <!--找servlet<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>-->
<context:component-scan base-package="com.kuang.controller"/>
    <!--默认的资源过滤-->
<mvc:default-servlet-handler/>
    <!--<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>-->
    <mvc:annotation-driven/>
    <!---->
    <!--3、视图解析器:真实的页面视图-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" id="InternalResourceViewResolver">
        <!--属性标签property类中的属性:获取类中的属性名name,并赋值value-->
        <property name="prefix" value="/WEB-INF/jsp/"/>
        <!--<property> → 给对象 set 赋值
        等价
       传统的 对象名.setAdd(String name){this.name=name}进行赋值
        -->
        <!--后缀-->
        <property name="suffix" value=".jsp"/>

后台:

java 复制代码
@Controller
public class HelloController {
    @RequestMapping("/hello")//请求urlhttp://localhost:8080/hello作用:建立请求 URL 和 Controller 方法 / 类之间的映射关系,用来接收浏览器请求。
    public String hello(Model model) {
        System.out.println("-------------------");
        //封装数据
        model.addAttribute("c", "springmvc");//attribute = 属性
        return "hello";//被视图解析器处理

    }

三、DispatcherServlet 核心:

1、DispatcherServlet执行思路(重点、难点)

DispatcherServlet:总指挥(不干活,分配任务) HandlerMapping:找控制器 HandlerAdapter:运行控制器 ViewResolver:解析页面地址

HandlerMapping查找处理器:URL → 找到处理器 Controller
HandlerAdapter处理器适配器:调用执行 Controller 方法
ViewResolver:逻辑视图名 → 真实页面视图

1.DispatcherServlet 前端控制器(入口,所有请求统一拦截)

2.请求到达后,调用 HandlerMapping:根据 URL 找到对应的 Controller 处理器

3.HandlerAdapter:适配执行 Controller 方法(反射调用)

4.执行 Controller(@RequestMapping 注解方法),返回 ModelAndView

5.ViewResolver 视图解析器:拼接页面真实路径(前缀 + 逻辑视图名 + 后缀)

6.渲染视图,把 Model 数据填充到页面,最终响应浏览器

极简一句话:DispatcherServlet 统领全局,映射器找方法,适配器执行方法,解析器跳页面

4、springmvc核心标签

SpringMVC xml 配置 核心标签汇总:

context:component-scan:组件扫描,扫描 @Controller、@Service 等注解

<context:component-scan base-package="com.controller"/>

mvc:annotation-driven:开启 SpringMVC 注解驱动!处理器映射器、处理器适配器、消息转换器(json 转换)、数据绑定、日期格式化、@RequestMapping 支持、@RequestBody、@ResponseBody

mvc:annotation-driven/

mvc:resources 静态资源放行

mvc:default-servlet-handler/:启用 Tomcat 默认 Servlet 处理静态资源,和mvc:resources二选一。 作用:所有静态资源交给 tomcat 处理,不需要逐个配置资源路径

 通用 Bean 标签用来手动装配组件,最常用:视图解析器

mvc:view-controller 页面跳转控制器,不需要写 Controller,直接通过 URL 跳转页面

<mvc:view-controller path="/toLogin" view-name="login"/>访问 /toLogin → 直接跳转到 login 视图

mvc:interceptors 拦截器配置

Srevlet的xml配置标签和springmvc框架核心标签的区别:

web.xml(tomcat 配置) 标签:、、、 作用:注册 DispatcherServlet 前端控制器,和 SpringMVC 容器无关。

 springmvc.xml(SpringMVC 容器配置) 上面所有 mvc:xxx、context:component-scan、 都写在这里

5、springmvc常用注解
相关推荐
XS0301061 小时前
Spring AI:两种内置 Advisor 快速实现 RAG
java·人工智能·spring
不爱说话郭德纲1 小时前
我只给了 TRAE Work 一张差评截图,它最后却把自己的 P0 结论推翻了?
前端·后端·架构
用户938515635072 小时前
从 DOM 编程到声明式 UI:React useRef 与 useState 底层全解析
前端·javascript·react.js
kisshyshy2 小时前
前端路由进化史:从刷新白屏到SPA,手写一个Hash路由就懂了!
前端·javascript·react.js
Sterting2 小时前
第 8 节:表单 — 前端校验的第一道防线
前端·javascript
保加利亚的风2 小时前
Docker 学习文档(Mac + Docker Desktop 版)
前端·后端
java1234_小锋3 小时前
Vue3专题 - 条件渲染
前端·javascript·vue.js
明月_清风3 小时前
🚀 AI Agent 完全入门指南:从 LLM 到生产落地,新手必懂的 34 个核心概念
前端·后端·ai编程
鸽鸽3 小时前
Vue 3 API 完全指南:从 Options 到 Composition 的进阶之路
前端·vue.js