跳到主要内容
SpringMVC 核心原理与实战应用详解 | 极客日志
Java java
SpringMVC 核心原理与实战应用详解 系统讲解 SpringMVC 框架,涵盖 MVC 设计模式、核心组件(DispatcherServlet、HandlerMapping 等)及执行流程。内容包括基于 Spring Boot 的环境搭建、请求参数绑定、视图解析(Thymeleaf)、拦截器、异常处理、文件上传等实战技巧,以及 SpringMVC 与 MyBatis 的集成方案,帮助开发者掌握 Web 层开发核心技术。
虚拟内存 发布于 2026/3/30 更新于 2026/5/27 25 浏览前言
在 Java EE 企业级开发领域,SpringMVC 作为轻量级的 Web 层开发框架,凭借其清晰的架构设计、灵活的配置方式以及与 Spring 生态的无缝集成,成为了当前主流的 Web 开发技术选型之一。它基于 MVC(Model-View-Controller)设计模式,通过分离模型、视图和控制器的职责,有效降低了代码耦合度,提升了项目的可维护性和扩展性。本文将从 SpringMVC 的基础概念出发,逐步深入其核心原理、核心组件、实战应用、高级特性等关键知识点,结合理论讲解与代码示例,帮助读者系统掌握 SpringMVC 技术栈。
一、SpringMVC 概述
1.1 MVC 设计模式简介
MVC(Model-View-Controller)是一种经典的软件架构设计模式,其核心思想是将应用程序的功能划分为三个独立的模块,通过明确的职责划分实现代码解耦。
Model(模型) :负责封装应用程序的核心数据和业务逻辑,是应用程序的数据层和业务层的结合体。模型不依赖于视图和控制器,仅专注于数据的处理和业务规则的实现。常见的模型组件包括实体类(Entity)、服务类(Service)、数据访问类(DAO)等。
View(视图) :负责向用户展示数据,是用户与应用程序交互的界面。视图仅负责数据的呈现,不涉及业务逻辑的处理。常见的视图技术包括 JSP、Thymeleaf、Freemarker 等。
Controller(控制器) :负责接收用户的请求,协调模型和视图完成用户需求。控制器接收请求后,调用模型进行业务逻辑处理,获取处理结果后,选择合适的视图向用户展示数据。
MVC 设计模式的优势在于实现了功能模块的分离,使得代码结构清晰,便于团队协作开发和后期维护。当需求发生变化时,只需修改对应的模块,不会影响其他模块的功能。
1.2 SpringMVC 的定义与核心优势
SpringMVC 是 Spring 框架的一个重要模块,是基于 Java 实现 MVC 设计模式的轻量级 Web 框架。它并非对 MVC 设计模式的全新实现,而是在 Spring 生态的基础上,对 MVC 架构进行了优化和封装,提供了一套简洁、高效的 Web 开发解决方案。
SpringMVC 的核心优势主要体现在以下几个方面:
与 Spring 无缝集成 :SpringMVC 是 Spring 框架的一部分,能够直接使用 Spring 的 IOC 容器、AOP 等核心特性,无需额外的整合配置,降低了框架集成的复杂度。
灵活的配置方式 :支持 XML 配置和注解配置两种方式,注解配置简化了开发流程,提高了开发效率;XML 配置则便于对全局配置进行统一管理,适用于复杂的项目场景。
清晰的架构设计 :基于 MVC 设计模式,职责划分明确,各组件之间耦合度低,便于代码的维护和扩展。
强大的功能支持 :提供了请求参数绑定、数据验证、视图解析、异常处理、文件上传等一系列完善的功能,满足企业级 Web 开发的各种需求。
良好的扩展性 :支持自定义拦截器、转换器、格式化器等组件,能够根据项目的特殊需求进行功能扩展。
1.3 SpringMVC 的应用场景
SpringMVC 适用于各种规模的 Java Web 项目开发,尤其是企业级应用项目。无论是中小型的管理系统、电商平台,还是大型的分布式 Web 应用,SpringMVC 都能凭借其灵活的架构和强大的功能满足开发需求。此外,由于 SpringMVC 与 Spring Boot、Spring Cloud 等主流技术的无缝集成,它也成为了微服务架构中 Web 层开发的首选技术。
二、SpringMVC 核心原理与执行流程
2.1 SpringMVC 核心组件
SpringMVC 的核心功能是通过一系列组件协同工作实现的,每个组件都有明确的职责。了解这些核心组件是掌握 SpringMVC 原理的关键。
2.1.1 前端控制器(DispatcherServlet)
DispatcherServlet 是 SpringMVC 的核心控制器,负责接收所有用户的请求,并协调其他组件完成请求的处理。它是整个 SpringMVC 流程的入口,相当于一个'中央处理器'。DispatcherServlet 的主要职责包括:
接收 HTTP 请求,解析请求 URL 和请求参数;
根据请求信息查找对应的处理器(Handler);
调用处理器适配器(HandlerAdapter)执行处理器;
接收处理器的处理结果(ModelAndView);
调用视图解析器(ViewResolver)解析视图,渲染并返回响应结果。
2.1.2 处理器映射器(HandlerMapping) HandlerMapping 的职责是根据用户请求的 URL,查找对应的处理器(Handler)和拦截器(Interceptor)。SpringMVC 提供了多种 HandlerMapping 实现,例如:
RequestMappingHandlerMapping:支持@RequestMapping 注解的处理器映射,是当前最常用的映射器;
BeanNameUrlHandlerMapping:根据 Bean 的名称作为 URL 进行映射;
SimpleUrlHandlerMapping:通过 XML 配置的方式,将 URL 与处理器进行直接映射。
当 DispatcherServlet 接收到请求后,会调用 HandlerMapping 获取对应的 HandlerExecutionChain(包含处理器和拦截器)。
2.1.3 处理器适配器(HandlerAdapter) HandlerAdapter 的职责是适配不同类型的处理器,使得 DispatcherServlet 无需关心处理器的具体实现,能够统一调用处理器的处理方法。由于 SpringMVC 支持多种类型的处理器(如注解式处理器、控制器接口实现类等),不同处理器的调用方式不同,HandlerAdapter 通过适配模式解决了这一问题。
RequestMappingHandlerAdapter:适配使用@RequestMapping 注解的处理器;
SimpleControllerHandlerAdapter:适配实现 Controller 接口的处理器;
SimpleServletHandlerAdapter:适配实现 Servlet 接口的处理器。
2.1.4 处理器(Handler) Handler 即业务处理器,是 SpringMVC 中处理具体业务逻辑的组件,相当于 MVC 架构中的 Controller。处理器接收请求参数,调用业务层服务完成数据处理,最终返回处理结果(ModelAndView)。在实际开发中,处理器通常是一个使用@RequestMapping 注解的 Controller 类中的方法。
2.1.5 视图解析器(ViewResolver) ViewResolver 的职责是根据处理器返回的 ModelAndView 中的视图名称,解析出具体的视图对象(View)。它将逻辑视图名转换为物理视图路径,例如将'index'解析为'/WEB-INF/views/index.jsp'。
InternalResourceViewResolver:解析 JSP 视图,是最常用的视图解析器;
ThymeleafViewResolver:解析 Thymeleaf 视图;
FreeMarkerViewResolver:解析 Freemarker 视图。
2.1.6 视图(View) View 是视图组件,负责将处理器返回的数据(Model)渲染为用户可查看的界面。View 接收 Model 中的数据,通过特定的视图技术(如 JSP、Thymeleaf)将数据展示出来。不同的视图技术对应不同的 View 实现类。
2.1.7 模型和视图(ModelAndView) ModelAndView 是处理器返回的结果对象,包含了视图名称和需要展示的数据(Model)。其中,Model 是一个键值对集合,用于存储需要传递给视图的数据;ViewName 是逻辑视图名,用于视图解析器解析具体的视图。
2.2 SpringMVC 执行流程详解 SpringMVC 的请求处理流程是一个标准化的流程,各组件按照固定的顺序协同工作。以下是 SpringMVC 完整的执行流程,结合核心组件的交互进行说明:
用户发送 HTTP 请求 :用户通过浏览器向服务器发送请求,请求 URL 例如'http://localhost:8080/springmvc/user/list'。
请求到达前端控制器(DispatcherServlet) :服务器接收到请求后,根据 Web.xml 中的配置(或 Spring Boot 的自动配置),将请求转发给 DispatcherServlet。DispatcherServlet 是 SpringMVC 的入口,负责统一处理所有请求。
DispatcherServlet 调用处理器映射器(HandlerMapping) :DispatcherServlet 将请求 URL 传递给 HandlerMapping,HandlerMapping 根据 URL 查找对应的处理器(Handler)和拦截器(Interceptor),返回 HandlerExecutionChain 对象(包含处理器和拦截器列表)。
DispatcherServlet 调用处理器适配器(HandlerAdapter) :DispatcherServlet 根据 HandlerMapping 返回的处理器类型,选择对应的 HandlerAdapter。HandlerAdapter 负责适配处理器,调用处理器的处理方法(如 Controller 中的@RequestMapping 注解方法)。
处理器执行业务逻辑并返回 ModelAndView :处理器(Controller 方法)接收请求参数,调用业务层(Service)的方法完成数据处理,将处理结果(数据)存入 Model,设置逻辑视图名,最终返回 ModelAndView 对象。
DispatcherServlet 调用视图解析器(ViewResolver) :DispatcherServlet 将 ModelAndView 中的逻辑视图名传递给 ViewResolver,ViewResolver 解析出具体的物理视图路径(如'/WEB-INF/views/user/list.jsp'),返回 View 对象。
视图渲染数据 :View 对象接收 Model 中的数据,通过视图技术(如 JSP)将数据渲染为 HTML 页面。
返回响应结果 :渲染后的 HTML 页面通过 HTTP 响应返回给用户浏览器,用户看到最终的页面效果。
注意:在整个执行流程中,拦截器会在处理器执行前后进行拦截处理,实现权限控制、日志记录等功能。拦截器的执行顺序是:preHandle(处理器执行前)→ 处理器执行 → postHandle(处理器执行后,视图渲染前)→ afterCompletion(视图渲染后)。
三、SpringMVC 入门实战
3.1 环境搭建(基于 Spring Boot) Spring Boot 提供了自动配置功能,能够快速搭建 SpringMVC 项目,无需繁琐的 XML 配置。以下是基于 Spring Boot 的 SpringMVC 环境搭建步骤:
3.1.1 创建 Maven 项目 使用 IDEA 或 Eclipse 创建一个 Maven 项目,选择'Spring Initializr'模板(IDEA 内置),填写项目基本信息(Group、Artifact、Version 等)。
3.1.2 引入依赖 在 pom.xml 文件中引入 Spring Boot Web 依赖(包含 SpringMVC 核心依赖):
<dependency >
<groupId > org.springframework.boot</groupId >
<artifactId > spring-boot-starter-web</artifactId >
</dependency >
Spring Boot Starter Web 依赖会自动引入 SpringMVC 的核心组件(DispatcherServlet、HandlerMapping、ViewResolver 等)以及 Tomcat 服务器依赖,实现开箱即用。
3.1.3 编写主启动类 创建 Spring Boot 主启动类,使用@SpringBootApplication 注解标识:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringMvcDemoApplication {
public static void main (String[] args) {
SpringApplication.run(SpringMvcDemoApplication.class, args);
}
}
@SpringBootApplication 注解包含了@ComponentScan(组件扫描)、@EnableAutoConfiguration(自动配置)、@Configuration(配置类)三个核心注解,能够自动扫描当前包及其子包下的组件,并完成 SpringMVC 的自动配置。
3.2 第一个 SpringMVC 程序:Hello World 编写一个简单的 Controller,实现'Hello World'功能,验证 SpringMVC 环境是否搭建成功。
3.2.1 创建 Controller 类 在 com.example.springmvcdemo.controller 包下创建 HelloController 类,使用@Controller 注解标识控制器,使用@RequestMapping 注解映射请求路径:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class HelloController {
@RequestMapping("/hello")
@ResponseBody
public String hello () {
return "Hello SpringMVC!" ;
}
}
@Controller:标识该类为 SpringMVC 的控制器组件,Spring 会自动扫描并将其纳入 IOC 容器管理;
@RequestMapping("/hello"):映射 HTTP 请求路径'/hello'到该方法;
@ResponseBody:表示该方法的返回值直接作为 HTTP 响应体返回,不经过视图解析器解析视图。如果不使用该注解,SpringMVC 会将返回值作为逻辑视图名进行解析。
3.2.2 启动项目并测试
3.3 请求参数绑定 SpringMVC 提供了强大的请求参数绑定功能,能够自动将 HTTP 请求参数绑定到 Controller 方法的参数上。常见的参数绑定场景包括基本类型参数、引用类型参数、集合类型参数等。
3.3.1 基本类型参数绑定 请求参数名与 Controller 方法参数名一致时,SpringMVC 会自动完成参数绑定。例如:
@RequestMapping("/user/find")
@ResponseBody
public String findUserById (Integer id, String name) {
return "id: " + id + ", name: " + name;
}
如果请求参数名与方法参数名不一致,可以使用@RequestParam 注解指定请求参数名:
@RequestMapping("/user/findByParam")
@ResponseBody
public String findByParam (@RequestParam("user_id") Integer id, @RequestParam("user_name") String name) {
return "id: " + id + ", name: " + name;
}
3.3.2 引用类型参数绑定 当请求参数较多时,可以将参数封装为引用类型(如实体类),SpringMVC 会自动将请求参数绑定到实体类的属性上(要求请求参数名与实体类属性名一致)。
public class User {
private Integer id;
private String name;
private Integer age;
public User () {}
public User (Integer id, String name, Integer age) {
this .id = id;
this .name = name;
this .age = age;
}
@Override
public String toString () {
return "User{id=" + id + ", name='" + name + "', age=" + age + "}" ;
}
}
@RequestMapping("/user/add")
@ResponseBody
public String addUser (User user) {
return "添加用户:" + user.toString();
}
3.3.3 集合类型参数绑定 当需要传递多个同类型参数时(如批量删除用户的 ID 列表),可以使用集合类型(List、Map)接收参数。此时需要将集合参数封装到一个 VO(Value Object)类中,或者使用@RequestParam 注解指定参数名。
@RequestMapping("/user/deleteBatch")
@ResponseBody
public String deleteBatch (@RequestParam("ids") List<Integer> ids) {
return "批量删除的 ID:" + ids.toString();
}
示例 2:使用 VO 类封装集合参数(适用于复杂场景):
public class UserVO {
private List<User> userList;
public List<User> getUserList () {
return userList;
}
public void setUserList (List<User> userList) {
this .userList = userList;
}
}
@RequestMapping("/user/addBatch")
@ResponseBody
public String addBatch (UserVO userVO) {
return "批量添加用户:" + userVO.getUserList().toString();
}
前端传递参数时,需要按照'userList[0].id=1&userList[0].name=zhangsan&userList[1].id=2&userList[1].name=lisi'的格式传递。
3.4 视图解析与页面跳转 在实际开发中,除了返回 JSON 数据(使用@ResponseBody),还经常需要返回页面视图。SpringMVC 通过视图解析器(ViewResolver)完成逻辑视图名到物理视图路径的解析。以下是基于 Thymeleaf 视图技术的页面跳转示例(Thymeleaf 是 Spring Boot 推荐的视图技术,比 JSP 更灵活、更强大)。
3.4.1 引入 Thymeleaf 依赖 <dependency >
<groupId > org.springframework.boot</groupId >
<artifactId > spring-boot-starter-thymeleaf</artifactId >
</dependency >
3.4.2 配置视图解析器 Spring Boot 对 Thymeleaf 提供了自动配置,默认的视图解析规则如下:
模板文件路径:classpath:/templates/
模板文件后缀:.html
逻辑视图名'index'会被解析为:classpath:/templates/index.html
如果需要自定义配置,可以在 application.properties 文件中添加以下配置:
# thymeleaf 模板前缀(默认 classpath:/templates/)
spring.thymeleaf.prefix=classpath:/templates/pages/
# thymeleaf 模板后缀(默认.html)
spring.thymeleaf.suffix=.html
# 编码格式
spring.thymeleaf.encoding=UTF-8
# 模板模式
spring.thymeleaf.mode=HTML5
3.4.3 编写视图页面 在 classpath:/templates/目录下创建 index.html 文件:
<!DOCTYPE html >
<html lang ="en" xmlns:th ="http://www.thymeleaf.org" >
<head >
<meta charset ="UTF-8" >
<title > 首页</title >
</head >
<body >
<h1 th:text ="${message}" > 欢迎访问首页</h1 >
<a href ="@{/user/list}" > 查看用户列表</a >
</body >
</html >
在 classpath:/templates/目录下创建 user/list.html 文件:
<!DOCTYPE html >
<html lang ="en" xmlns:th ="http://www.thymeleaf.org" >
<head >
<meta charset ="UTF-8" >
<title > 用户列表</title >
</head >
<body >
<h1 > 用户列表</h1 >
<table border ="1" >
<tr >
<th > ID</th >
<th > 姓名</th >
<th > 年龄</th >
</tr >
<tr th:each ="user : ${userList}" >
<td th:text ="${user.id}" > </td >
<td th:text ="${user.name}" > </td >
<td th:text ="${user.age}" > </td >
</tr >
</table >
</body >
</html >
3.4.4 编写 Controller 方法实现页面跳转 @RequestMapping("/index")
public String toIndex (Model model) {
model.addAttribute("message" , "Hello SpringMVC + Thymeleaf!" );
return "index" ;
}
@RequestMapping("/user/list")
public String userList (Model model) {
List<User> userList = new ArrayList <>();
userList.add(new User (1 , "zhangsan" , 22 ));
userList.add(new User (2 , "lisi" , 23 ));
userList.add(new User (3 , "wangwu" , 24 ));
model.addAttribute("userList" , userList);
return "user/list" ;
}
四、SpringMVC 高级特性
4.1 拦截器(Interceptor) SpringMVC 的拦截器类似于 Servlet 的过滤器(Filter),用于在请求处理的不同阶段对请求进行拦截和处理。拦截器可以实现权限控制、日志记录、参数校验、性能监控等功能。与 Filter 不同的是,拦截器是 SpringMVC 框架内部的组件,能够访问 Spring 的 IOC 容器,而 Filter 是 Servlet 规范的组件,作用范围更广。
4.1.1 拦截器的工作原理 拦截器通过实现 HandlerInterceptor 接口或继承 HandlerInterceptorAdapter 类(已过时,推荐实现接口)来定义。HandlerInterceptor 接口提供了三个方法,对应拦截器的三个执行时机:
preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) :在处理器(Handler)执行前执行。返回 true 表示放行,继续执行后续的拦截器和处理器;返回 false 表示拦截,不再执行后续操作。
postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) :在处理器执行后、视图渲染前执行。可以通过 ModelAndView 对象对视图和数据进行修改。
afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) :在视图渲染后、请求完成后执行。通常用于资源清理、日志记录等操作。
4.1.2 自定义拦截器实现 第一步:创建自定义拦截器类,实现 HandlerInterceptor 接口:
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle (HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
Object user = request.getSession().getAttribute("user" );
if (user == null ) {
response.sendRedirect(request.getContextPath() + "/login.html" );
return false ;
}
return true ;
}
@Override
public void postHandle (HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
if (modelAndView != null ) {
modelAndView.addObject("interceptorMsg" , "来自 LoginInterceptor 的消息" );
}
}
@Override
public void afterCompletion (HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("请求处理完成,执行资源清理..." );
}
}
4.1.3 配置拦截器 在 SpringMVC 中,需要通过配置类(实现 WebMvcConfigurer 接口)来注册拦截器,并指定拦截的请求路径和排除的请求路径。
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors (InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor ())
.addPathPatterns("/**" )
.excludePathPatterns("/login.html" , "/user/login" );
}
}
addPathPatterns("/**"):表示拦截所有请求路径;
excludePathPatterns("/login.html", "/user/login"):表示排除对'/login.html'页面和'/user/login'接口的拦截,允许未登录用户访问这些资源。
4.2 异常处理 在 Web 应用开发中,异常处理是不可或缺的一部分。SpringMVC 提供了多种异常处理方式,能够统一捕获和处理 Controller 层的异常,避免异常直接暴露给用户,提升用户体验。常用的异常处理方式包括:@ExceptionHandler 注解、@ControllerAdvice 注解、实现 HandlerExceptionResolver 接口等。
4.2.1 @ExceptionHandler 注解(局部异常处理) @ExceptionHandler 注解用于在 Controller 内部定义异常处理方法,只能处理当前 Controller 中的异常,属于局部异常处理。
@Controller
public class UserController {
@RequestMapping("/user/get")
@ResponseBody
public String getUserById (Integer id) {
if (id == null ) {
throw new NullPointerException ("用户 ID 不能为空" );
}
if (id <= 0 ) {
throw new IllegalArgumentException ("用户 ID 必须为正数" );
}
return "用户 ID:" + id;
}
@ExceptionHandler(NullPointerException.class)
@ResponseBody
public String handleNullPointerException (NullPointerException e) {
return "错误:" + e.getMessage();
}
@ExceptionHandler(IllegalArgumentException.class)
@ResponseBody
public String handleIllegalArgumentException (IllegalArgumentException e) {
return "错误:" + e.getMessage();
}
}
4.2.2 @ControllerAdvice + @ExceptionHandler(全局异常处理) @ControllerAdvice 注解用于定义全局异常处理类,结合@ExceptionHandler 注解可以捕获所有 Controller 中的异常,实现全局异常统一处理。
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(NullPointerException.class)
@ResponseBody
public String handleNullPointerException (NullPointerException e) {
return "全局错误:" + e.getMessage();
}
@ExceptionHandler(IllegalArgumentException.class)
@ResponseBody
public String handleIllegalArgumentException (IllegalArgumentException e) {
return "全局错误:" + e.getMessage();
}
@ExceptionHandler(Exception.class)
@ResponseBody
public String handleException (Exception e) {
return "系统异常:" + e.getMessage();
}
}
使用全局异常处理后,所有 Controller 中抛出的异常都会被 GlobalExceptionHandler 中的对应方法捕获并处理,无需在每个 Controller 中单独定义异常处理方法。
4.3 文件上传 SpringMVC 提供了便捷的文件上传功能,基于 Apache Commons FileUpload 组件实现(Spring Boot 已自动整合相关依赖)。以下是文件上传的实现步骤:
4.3.1 引入文件上传依赖 Spring Boot 的 spring-boot-starter-web 依赖已包含文件上传所需的依赖,无需额外引入。如果是传统 SpringMVC 项目,需要手动引入以下依赖:
<dependency >
<groupId > commons-fileupload</groupId >
<artifactId > commons-fileupload</artifactId >
<version > 1.4</version >
</dependency >
4.3.2 配置文件上传解析器 Spring Boot 会自动配置 MultipartResolver(文件上传解析器),默认的最大上传文件大小为 1MB。如果需要自定义配置,可以在 application.properties 文件中添加以下配置:
# 单个文件最大上传大小
spring.servlet.multipart.max-file-size=10MB
# 单次请求最大上传大小(多文件上传时)
spring.servlet.multipart.max-request-size=50MB
# 文件上传临时目录(默认在系统临时目录)
spring.servlet.multipart.location=${java.io.tmpdir}
4.3.3 实现文件上传功能 第一步:编写文件上传页面(upload.html):
<!DOCTYPE html >
<html lang ="en" >
<head >
<meta charset ="UTF-8" >
<title > 文件上传</title >
</head >
<body >
<form action ="/file/upload" method ="post" enctype ="multipart/form-data" >
选择文件:<input type ="file" name ="file" > <br >
<input type ="submit" value ="上传" >
</form >
</body >
</html >
注意:form 表单的 enctype 属性必须设置为'multipart/form-data',否则无法正确上传文件。
4.3.4 编写文件上传 Controller 方法 import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
import java.util.UUID;
@RestController
public class FileUploadController {
private static final String UPLOAD_PATH = "D:/upload/" ;
@PostMapping("/file/upload")
public String uploadFile (@RequestParam("file") MultipartFile file) {
if (file.isEmpty()) {
return "文件不能为空" ;
}
String originalFilename = file.getOriginalFilename();
String fileName = UUID.randomUUID().toString() + originalFilename.substring(originalFilename.lastIndexOf("." ));
File uploadDir = new File (UPLOAD_PATH);
if (!uploadDir.exists()) {
uploadDir.mkdirs();
}
try {
file.transferTo(new File (UPLOAD_PATH + fileName));
return "文件上传成功!文件名:" + fileName;
} catch (IOException e) {
e.printStackTrace();
return "文件上传失败:" + e.getMessage();
}
}
}
五、SpringMVC 与其他技术的集成
5.1 SpringMVC 与 Spring 的集成 SpringMVC 本身就是 Spring 框架的一部分,因此与 Spring 的集成非常简单。在 Spring Boot 项目中,通过@SpringBootApplication 注解的@ComponentScan 功能,会自动扫描 Controller、Service、Repository 等组件,实现 Spring IOC 容器与 SpringMVC 的无缝集成。
在传统 SpringMVC 项目中,需要在 Web.xml 中配置 Spring 的 ContextLoaderListener,加载 Spring 的配置文件,实现 Spring IOC 容器的初始化。配置示例如下:
<listener >
<listener-class > org.springframework.web.context.ContextLoaderListener</listener-class >
</listener >
<context-param >
<param-name > contextConfigLocation</param-name >
<param-value > classpath:spring.xml</param-value >
</context-param >
集成后,SpringMVC 的 Controller 可以直接通过@Autowired 注解注入 Spring IOC 容器中的 Service、DAO 等组件,实现业务逻辑的调用。
5.2 SpringMVC 与 MyBatis 的集成 MyBatis 是一款优秀的持久层框架,SpringMVC 与 MyBatis 的集成是企业级开发的常见组合。集成步骤如下:
5.2.1 引入依赖
<dependency >
<groupId > org.mybatis</groupId >
<artifactId > mybatis</artifactId >
<version > 3.5.9</version >
</dependency >
<dependency >
<groupId > org.mybatis</groupId >
<artifactId > mybatis-spring</artifactId >
<version > 2.0.7</version >
</dependency >
<dependency >
<groupId > mysql</groupId >
<artifactId > mysql-connector-java</artifactId >
<version > 8.0.30</version >
</dependency >
<dependency >
<groupId > com.alibaba</groupId >
<artifactId > druid</artifactId >
<version > 1.2.11</version >
</dependency >
5.2.2 配置数据源和 SqlSessionFactory 在 Spring 配置文件中配置数据源(Druid)、SqlSessionFactoryBean、MapperScannerConfigurer 等组件:
<bean id ="dataSource" class ="com.alibaba.druid.pool.DruidDataSource" destroy-method ="close" >
<property name ="driverClassName" value ="com.mysql.cj.jdbc.Driver" />
<property name ="url" value ="jdbc:mysql://localhost:3306/test?useSSL=false&serverTimezone=UTC" />
<property name ="username" value ="root" />
<property name ="password" value ="123456" />
</bean >
<bean id ="sqlSessionFactory" class ="org.mybatis.spring.SqlSessionFactoryBean" >
<property name ="dataSource" ref ="dataSource" />
<property name ="mapperLocations" value ="classpath:mapper/*.xml" />
<property name ="configLocation" value ="classpath:mybatis-config.xml" />
</bean >
<bean class ="org.mybatis.spring.mapper.MapperScannerConfigurer" >
<property name ="basePackage" value ="com.example.dao" />
<property name ="sqlSessionFactoryBeanName" value ="sqlSessionFactory" />
</bean >
5.2.3 编写 Mapper 接口和映射文件 public interface UserMapper {
User selectUserById (Integer id) ;
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace ="com.example.dao.UserMapper" >
<select id ="selectUserById" parameterType ="java.lang.Integer" resultType ="com.example.entity.User" >
select id, name, age from user where id = #{id}
</select >
</mapper >
5.2.4 在 Service 中注入 Mapper 接口 @Service
public class UserService {
@Autowired
private UserMapper userMapper;
public User getUserById (Integer id) {
return userMapper.selectUserById(id);
}
}
5.2.5 在 Controller 中调用 Service @Controller
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("/user/get/{id}")
@ResponseBody
public User getUserById (@PathVariable("id") Integer id) {
return userService.getUserById(id);
}
}
六、总结与扩展
6.1 本文知识点总结 本文围绕 SpringMVC 知识点展开,采用总分总的编写模式,从基础到进阶,系统讲解了 SpringMVC 的核心内容。首先介绍了 MVC 设计模式和 SpringMVC 的基本概念、核心优势及应用场景,帮助读者建立对 SpringMVC 的整体认知;其次深入剖析了 SpringMVC 的核心组件(DispatcherServlet、HandlerMapping、HandlerAdapter 等)和执行流程,让读者理解 SpringMVC 的工作原理;然后通过基于 Spring Boot 的实战案例,讲解了 SpringMVC 的环境搭建、请求参数绑定、视图解析与页面跳转等基础应用;接着介绍了 SpringMVC 的高级特性,包括拦截器、异常处理、文件上传等,提升读者的实战能力;随后讲解了 SpringMVC 与 Spring、MyBatis 等技术的集成,满足企业级开发的需求;最后通过总结与扩展,梳理全文知识点,并提供进一步学习的阅读资料。
MVC 设计模式:模型(Model)、视图(View)、控制器(Controller)的职责划分;
SpringMVC 核心组件:DispatcherServlet(前端控制器)、HandlerMapping(处理器映射器)、HandlerAdapter(处理器适配器)等的作用;
SpringMVC 执行流程:从接收请求到返回响应的完整步骤,各组件的协同工作机制;
基础实战:环境搭建、请求参数绑定(基本类型、引用类型、集合类型)、视图解析与页面跳转;
高级特性:拦截器(权限控制、日志记录)、异常处理(局部异常、全局异常)、文件上传;
技术集成:与 Spring 的无缝集成、与 MyBatis 的持久层集成。
6.2 知识点扩展 除了本文讲解的核心知识点,SpringMVC 还有一些进阶内容值得深入学习,以应对更复杂的开发场景:
RESTful 风格 API 开发 :RESTful 是一种软件架构风格,通过 HTTP 方法(GET、POST、PUT、DELETE)对应 CRUD 操作,实现资源的统一管理。SpringMVC 通过@RequestMapping、@GetMapping、@PostMapping、@PutMapping、@DeleteMapping 等注解实现 RESTful 风格 API 开发。
相关免费在线工具 Keycode 信息 查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
Escape 与 Native 编解码 JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
JavaScript / HTML 格式化 使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
JavaScript 压缩与混淆 Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online