SpringMVC【入门篇】

一、什么是SpringMVC

SpringMVC(Spring Model-View-Controller)是Spring框架的一个模块,用于开发Web应用程序。它是一个基于请求驱动的框架,负责处理用户的请求,分发请求到合适的处理方法,并返回响应。SpringMVC遵循了经典的MVC设计模式,将Web应用分为三个部分:

  • Model(模型):主要是业务逻辑部分,用来保存数据或与数据库进行交互。
  • View(视图):用于显示数据,通常是JSP、Thymeleaf、FreeMarker等模板。
  • Controller(控制器):接受用户的请求,处理业务逻辑,调用模型层,返回数据,最终选择合适的视图进行展示。

SpringMVC的主要作用是实现请求的分发与业务逻辑的处理,同时与Spring框架其他部分(如Spring的依赖注入、事务管理等)配合,提供完整的Web开发解决方案。

二、SpringMVC执行原理流程

要深入理解SpringMVC的执行原理,我们需要从请求的接收到响应的过程来分析。SpringMVC的工作流程大致可以分为以下几个步骤:

  1. 客户端请求(浏览器发起请求)

    • 用户在浏览器中输入URL或点击某个链接发起HTTP请求。
  2. 前端控制器(DispatcherServlet)

    • 所有的请求都会首先到达SpringMVC的核心组件——DispatcherServlet(前端控制器)。
    • DispatcherServlet负责请求的分发和协调,它是整个SpringMVC的入口。
  3. 请求映射(HandlerMapping)

    • DispatcherServlet会根据请求的URL,使用HandlerMapping来确定哪个控制器(Controller)的方法来处理这个请求。
    • HandlerMapping会查找符合请求的映射关系,通常通过注解(如@RequestMapping)来定义。
  4. 控制器适配器

HandlerAdapter经过适配调用具体的处理器(Handler/Controller)

  1. 控制器处理请求(Controller)

    • 找到对应的Controller后,DispatcherServlet会调用该控制器的处理方法(比如@RequestMapping标注的方法)。
    • 控制器方法处理业务逻辑、数据查询等,并将结果返回给DispatcherServlet
  2. 视图解析(ViewResolver)

    • 控制器方法的返回值一般是一个视图名称,SpringMVC会通过ViewResolver来解析出具体的视图(比如JSP文件、Thymeleaf模板等)。
    • ViewResolver根据视图名称和配置的前后缀规则(如/WEB-INF/jsp/ + viewName + .jsp)找到对应的视图资源。
  3. 返回响应(返回给客户端)

    • 解析得到的视图会将数据渲染成HTML(或其他格式),然后响应给客户端(浏览器)。

整个流程的关键是DispatcherServlet,它起到了“调度”和“分发”的作用,其他组件(如HandlerMappingHandlerAdapterViewResolver等)各司其职,确保请求的高效处理。

三、SpringMVC工作流程图(自上而下阅读)

springMVC工作流程

分阶段详细流程

阶段 1:请求到达 DispatcherServlet
  • 入口类DispatcherServlet#doDispatch()(核心调度方法)
  • 关键操作

    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) {
        // 1. 获取HandlerExecutionChain(包含拦截器链)
        HandlerExecutionChain mappedHandler = getHandler(request);
        
        // 2. 获取HandlerAdapter
        HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
        
        // 3. 执行拦截器preHandle
        if (!mappedHandler.applyPreHandle(request, response)) return;
        
        // 4. 实际调用Controller方法
        ModelAndView mv = ha.handle(request, response, mappedHandler.getHandler());
        
        // 5. 处理视图渲染
        applyDefaultViewName(request, mv);
        mappedHandler.applyPostHandle(request, response, mv);
        processDispatchResult(request, response, mappedHandler, mv, dispatchException);
    }
阶段 2:路由匹配(HandlerMapping)
  • 核心实现类

    • RequestMappingHandlerMapping:处理@RequestMapping注解
    • BeanNameUrlHandlerMapping:基于Bean名称映射
  • 匹配逻辑

    // RequestMappingHandlerMapping#getHandlerInternal()
    protected HandlerMethod getHandlerInternal(HttpServletRequest request) {
        String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
        this.mappingRegistry.getMappingsByUrl(lookupPath); // 从注册表查询
    }
阶段 3:参数绑定(HandlerAdapter)
  • 核心类RequestMappingHandlerAdapter
  • 关键步骤

    1. 参数解析:通过HandlerMethodArgumentResolver解析@RequestParam@RequestBody
    2. 数据转换:使用HttpMessageConverter处理JSON/XML等格式
    3. 验证:执行@Valid参数校验
阶段 4:拦截器(Interceptor)执行
  • 执行顺序

    preHandle → Controller → postHandle → 视图渲染 → afterCompletion
  • 源码入口

    // HandlerExecutionChain#applyPreHandle()
    boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) {
        for (int i = 0; i < this.interceptorList.size(); i++) {
            if (!interceptor.preHandle(request, response, this.handler)) {
                triggerAfterCompletion(request, response, null);
                return false;
            }
        }
    }
阶段 5:视图渲染
  • 核心流程

    1. 视图解析ViewResolver#resolveViewName() → 生成View对象
    2. 模型填充View#render()合并Model数据
    3. 输出响应:通过HttpServletResponse写入HTML/JSON

关键设计模式

模式应用场景实现类示例
前端控制器统一请求入口DispatcherServlet
策略模式可插拔的组件HandlerMapping实现类
适配器模式兼容多种Controller类型HandlerAdapter
责任链模式拦截器链执行HandlerInterceptor

与Spring Boot的集成差异

  • 自动配置类WebMvcAutoConfiguration

    • 默认注册的组件:

      @Bean
      public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
          // 默认配置JSON转换器、参数解析器等
      }
  • 定制扩展

    @Configuration
    public class WebConfig implements WebMvcConfigurer {
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new AuthInterceptor());
        }
    }

常见问题排查技巧

  1. 404 错误

    • 检查@Controller是否被扫描到
    • 确认URL路径与@RequestMapping匹配
  2. 参数绑定失败

    • 调试HandlerMethodArgumentResolver实现类
  3. 视图解析失败

    • 检查ViewResolver配置和模板路径
  4. 拦截器不生效

    • 确认Interceptor注册顺序和excludePathPatterns

四、SpringMVC的入门案例

以下是一个结合 Spring BootSpring MVC 的简单入门案例,包含详细步骤和代码,帮助你快速搭建一个基础的 Web 应用。


1. 环境准备

  • JDK 17+
  • Maven 3.6+
  • IDE(推荐 IntelliJ IDEA 或 VS Code)

2. 创建 Spring Boot 项目

使用 Spring Initializr 快速生成项目:

  1. 访问 start.spring.io
  2. 选择以下配置:

    • Project: Maven
    • Language: Java
    • Spring Boot: 3.2.x
    • Packaging: Jar
    • Dependencies:

      • Spring Web(集成 Spring MVC)
      • Thymeleaf(可选,用于模板引擎)
  3. 点击 Generate 下载项目,解压后用 IDE 打开。

3. 项目结构

src/
├── main/
│   ├── java/
│   │   └── com/example/demo/
│   │       ├── DemoApplication.java      # Spring Boot 启动类
│   │       └── controller/
│   │           └── HelloController.java  # MVC 控制器
│   └── resources/
│       ├── static/                       # 静态资源(CSS/JS)
│       ├── templates/                    # 视图模板(HTML)
│       └── application.properties        # 配置文件

4. 编写代码

(1) 控制器类 `HelloController.java`

package com.example.demo.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class HelloController {

    // 返回 HTML 视图(需要 Thymeleaf)
    @GetMapping("/hello")
    public String hello(Model model) {
        model.addAttribute("message", "Hello, Spring MVC!");
        return "hello"; // 对应 templates/hello.html
    }

    // 返回 JSON 数据
    @GetMapping("/api/hello")
    @ResponseBody
    public String apiHello() {
        return "{\"message\": \"Hello, Spring Boot!\"}";
    }
}

(2) 视图模板 templates/hello.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Spring MVC Demo</title>
</head>
<body>
    <h1 th:text="${message}">Default Message</h1>
</body>
</html>

(3) 配置文件 application.properties

# 设置端口
server.port=8080

# Thymeleaf 配置(关闭缓存,开发时使用)
spring.thymeleaf.cache=false

5. 运行应用

  1. 打开启动类 DemoApplication.java,运行 main 方法。
  2. 访问以下 URL:


6. 关键注解说明

注解说明
@Controller声明为 MVC 控制器,处理 HTTP 请求
@GetMapping映射 HTTP GET 请求到指定方法
@ResponseBody直接返回数据(JSON/文本),不经过视图解析
Model向视图传递数据的容器

7. 扩展功能

(1) 静态资源访问

将 CSS/JS 文件放在 src/main/resources/static/ 下,直接通过 URL 访问:
例如:http://localhost:8080/css/style.css

(2) 使用 RESTful API

@RestController // = @Controller + @ResponseBody
@RequestMapping("/api")
public class UserController {

    @GetMapping("/users/{id}")
    public User getUser(@PathVariable Long id) {
        return new User(id, "Alice");
    }
}

(3) 连接数据库

添加依赖 Spring Data JPA + H2 Database,编写 RepositoryEntity 类。


8. 常见问题

  1. 404 错误:检查 URL 路径和控制器方法是否匹配。
  2. Thymeleaf 模板不生效:确保 templates/ 目录正确,且依赖已添加。
  3. 端口冲突:在 application.properties 中修改 server.port

通过这个案例,你可以快速掌握 Spring Boot + Spring MVC 的基础用法,后续介绍springmvc的全局异常处理!

打赏
评论区
头像
文章目录

本网站由提供CDN加速/云存储服务