第五篇 SpringMVC

SpringMVC 概述

SpringMVC 是基于 Spring 框架的 Web 模块,用于构建灵活、松耦合的 Web 应用程序。它采用模型-视图-控制器(MVC)设计模式,通过注解和配置简化开发流程。

核心组件

  • DispatcherServlet:前端控制器,负责请求的分发和响应处理。
  • HandlerMapping:将请求映射到对应的处理器(Controller)。
  • Controller:处理业务逻辑并返回模型数据。
  • ViewResolver:解析视图名称,渲染最终的响应(如 JSP、Thymeleaf)。

Spring MVC 执行流程

Spring MVC 的执行流程可以分为多个阶段,从请求发出到响应返回的完整过程如下:

1. 客户端发送请求 客户端(浏览器或其他前端应用)发送 HTTP 请求到 DispatcherServlet(前端控制器)。

2. DispatcherServlet 接收请求 DispatcherServlet 是 Spring MVC 的核心组件,负责接收所有请求并协调其他组件处理请求。

3. 调用 HandlerMapping DispatcherServlet 通过 HandlerMapping 查找请求对应的处理器(Controller 或 Handler)。HandlerMapping 根据请求的 URL 或其他条件确定具体的 Controller 方法。

4. 执行 HandlerAdapter HandlerAdapter 负责调用具体的 Controller 方法,并处理方法的参数绑定、返回值等逻辑。Spring MVC 提供了多种 HandlerAdapter 实现,如 RequestMappingHandlerAdapter。

5. 执行 Controller 方法 Controller 方法处理业务逻辑,可能涉及调用 Service 层或其他组件,最终返回 ModelAndView 或其他类型的返回值(如 JSON 数据)。

6. 处理视图(ViewResolver) 如果返回的是视图名称(如字符串或 ModelAndView),DispatcherServlet 会调用 ViewResolver 解析视图名称,找到对应的视图模板(如 JSP、Thymeleaf 等)。

7. 渲染视图 视图(View)根据 Model 数据渲染最终的 HTML 或其他格式的响应内容。

8. 返回响应 DispatcherServlet 将渲染后的响应返回给客户端,完成整个请求-响应周期。

关键组件说明

DispatcherServlet 前端控制器,负责请求的分发和协调,是 Spring MVC 的核心入口。

HandlerMapping 负责将请求映射到具体的处理器(Controller 方法),常见的实现包括 RequestMappingHandlerMapping。

HandlerAdapter 负责调用具体的处理器方法,并处理参数绑定和返回值转换。

ViewResolver 负责解析视图名称,找到对应的视图模板。

View 负责渲染最终的响应内容,如生成 HTML 或 JSON 数据。

示例流程

假设一个请求 /user/list 的流程:

  1. 请求到达 DispatcherServlet。
  2. HandlerMapping 找到 @RequestMapping("/user/list") 对应的 Controller 方法。
  3. HandlerAdapter 调用该方法,执行业务逻辑并返回 "userList"(视图名称)。
  4. ViewResolver 解析 "userList"/WEB-INF/views/userList.jsp
  5. JSP 视图渲染 Model 数据,生成 HTML。
  6. DispatcherServlet 将 HTML 返回给客户端。

异步请求处理

对于异步请求(如返回 DeferredResultCallable),流程略有不同:

  1. DispatcherServlet 释放线程池资源,等待异步结果。
  2. 异步任务完成后,重新派发请求完成后续流程(视图渲染等)。

Spring MVC 的执行流程清晰且模块化,通过组件化的设计实现了灵活性和可扩展性。

配置 SpringMVC

  1. XML 配置
    web.xml 中配置 DispatcherServlet
XML 复制代码
<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring-mvc-config.xml</param-value>
    </init-param>
</servlet>
<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>
  1. 注解驱动配置
    使用 @EnableWebMvc 和 Java 配置类:
java 复制代码
@Configuration
@EnableWebMvc
@ComponentScan("com.example.controller")
public class WebConfig implements WebMvcConfigurer {
    // 配置视图解析器、静态资源等
}

控制器开发

通过 @Controller@RequestMapping 定义处理器方法:

java 复制代码
@Controller
@RequestMapping("/user")
public class UserController {
    @GetMapping("/info")
    public String getUserInfo(Model model) {
        model.addAttribute("user", new User("Alice", 25));
        return "user-info";
    }
}

数据绑定与验证

使用 @ModelAttribute 绑定表单数据,结合 @Valid 进行校验:

java 复制代码
@PostMapping("/register")
public String registerUser(@Valid @ModelAttribute User user, BindingResult result) {
    if (result.hasErrors()) {
        return "register-form";
    }
    // 保存用户逻辑
    return "redirect:/success";
}

RESTful 支持

通过 @RestController@ResponseBody 返回 JSON/XML 数据:

java 复制代码
@RestController
@RequestMapping("/api/users")
public class UserApiController {
    @GetMapping("/{id}")
    public ResponseEntity<User> getUserById(@PathVariable Long id) {
        User user = userService.findById(id);
        return ResponseEntity.ok(user);
    }
}

异常处理

使用 @ControllerAdvice 全局处理异常:

java 复制代码
@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(UserNotFoundException.class)
    public ResponseEntity<String> handleUserNotFound(UserNotFoundException ex) {
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(ex.getMessage());
    }
}

常用注解

  • @RequestMapping:定义请求映射路径。
  • @GetMapping/@PostMapping:限定 HTTP 方法。
  • @PathVariable:从 URL 中提取变量。
  • @RequestParam:获取查询参数或表单数据。
  • @ResponseBody:直接返回数据而非视图。

性能优化建议

  • 使用 @Async 实现异步请求处理。
  • 配置静态资源缓存(通过 WebMvcConfigurer)。
  • 启用 GZIP 压缩减少响应体积。

SpringMVC 通过高度模块化和注解驱动的方式,显著提升了 Web 开发的效率和可维护性。

相关推荐
程序员清风15 小时前
程序员兼职必看:靠谱软件外包平台挑选指南与避坑清单!
java·后端·面试
皮皮林55116 小时前
利用闲置 Mac 从零部署 OpenClaw 教程 !
java
NE_STOP19 小时前
springMVC-HTTP消息转换器与文件上传、下载、异常处理
spring
洋洋技术笔记21 小时前
Spring Boot配置管理最佳实践
spring boot
华仔啊21 小时前
挖到了 1 个 Java 小特性:var,用完就回不去了
java·后端
SimonKing1 天前
SpringBoot整合秘笈:让Mybatis用上Calcite,实现统一SQL查询
java·后端·程序员
日月云棠2 天前
各版本JDK对比:JDK 25 特性详解
java
用户8307196840822 天前
Spring Boot 项目中日期处理的最佳实践
java·spring boot
JavaGuide2 天前
Claude Opus 4.6 真的用不起了!我换成了国产 M2.5,实测真香!!
java·spring·ai·claude code
IT探险家2 天前
Java 基本数据类型:8 种原始类型 + 数组 + 6 个新手必踩的坑
java