一、Spring Web MVC核心概念
Spring Web MVC是Spring框架的Web模块,基于MVC设计模式构建,通过DispatcherServlet作为前端控制器统一处理请求,实现了Web层的职责解耦。其核心优势包括:清晰的角色划分、强大的扩展性、与Spring生态的无缝集成、支持RESTful风格以及灵活的数据绑定机制。
1.1 核心组件架构
Spring MVC的核心架构包括以下关键组件:
- DispatcherServlet:前端控制器,接收所有HTTP请求并分发到对应的处理器
- HandlerMapping:请求映射器,根据URL路径匹配对应的控制器方法
- HandlerAdapter:处理器适配器,支持多种类型的控制器
- Controller:页面控制器,处理业务逻辑并返回模型数据
- ViewResolver:视图解析器,将逻辑视图名解析为实际视图对象
- ModelAndView:封装模型数据和视图名称的容器
1.2 请求处理流程
Spring MVC处理请求的完整流程如下:
- 用户发送请求到DispatcherServlet
- DispatcherServlet委托HandlerMapping查找处理器
- HandlerMapping返回HandlerExecutionChain(包含处理器和拦截器)
- DispatcherServlet调用HandlerAdapter适配处理器
- HandlerAdapter执行控制器方法并返回ModelAndView
- ViewResolver解析逻辑视图名得到具体视图
- 视图渲染并将响应返回给用户
二、开发环境搭建
2.1 Maven项目配置
创建Maven Web项目,在pom.xml中添加核心依赖:
<dependencies>
<!-- Spring MVC核心依赖 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.25</version>
</dependency>
<!-- Servlet API -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- JSTL标签库 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
2.2 web.xml配置
配置DispatcherServlet作为前端控制器:
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
2.3 Spring MVC配置文件
创建spring-mvc.xml配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 包扫描配置 -->
<context:component-scan base-package="com.example.controller"/>
<!-- 注解驱动 -->
<mvc:annotation-driven/>
<!-- 静态资源处理 -->
<mvc:default-servlet-handler/>
<!-- 视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
</beans>
三、控制器开发
3.1 控制器注解
Spring MVC提供了丰富的注解来简化控制器开发:
@Controller
@RequestMapping("/user")
public class UserController {
// GET请求映射
@GetMapping("/list")
public String listUsers(Model model) {
List<User> users = userService.getAll();
model.addAttribute("users", users);
return "user/list";
}
// POST请求映射
@PostMapping("/add")
public String addUser(@Valid User user, BindingResult result) {
if (result.hasErrors()) {
return "user/form";
}
userService.save(user);
return "redirect:/user/list";
}
// RESTful风格API
@GetMapping("/{id}")
@ResponseBody
public ResponseEntity<User> getUserById(@PathVariable Long id) {
User user = userService.findById(id);
return ResponseEntity.ok(user);
}
}
3.2 常用注解说明
- @Controller:标识该类为控制器
- @RestController:@Controller + @ResponseBody的组合,适用于REST API
- @RequestMapping:映射请求路径,可指定HTTP方法
- @GetMapping/@PostMapping:特定HTTP方法的快捷方式
- @PathVariable:获取URL路径参数
- @RequestParam:获取请求参数
- @RequestBody:获取请求体中的JSON数据
- @ResponseBody:将返回值直接作为响应体
四、数据绑定与验证
4.1 数据绑定方式
Spring MVC支持多种数据绑定方式:
@PostMapping("/register")
public String register(
@RequestParam("username") String username, // 获取单个参数
@RequestParam String password, // 参数名与方法参数名一致
@ModelAttribute User user, // 绑定到POJO对象
@RequestBody UserDTO userDTO // 绑定JSON请求体
) {
// 业务逻辑
return "success";
}
4.2 数据验证
使用Bean Validation进行数据校验:
@Data
public class User {
@NotBlank(message = "用户名不能为空")
@Size(min = 3, max = 20, message = "用户名长度3-20位")
private String username;
@NotBlank(message = "密码不能为空")
@Size(min = 6, max = 20, message = "密码长度6-20位")
private String password;
@Email(message = "邮箱格式不正确")
private String email;
}
@PostMapping("/save")
public String saveUser(@Valid User user, BindingResult result) {
if (result.hasErrors()) {
return "user/form";
}
userService.save(user);
return "redirect:/user/list";
}
五、视图技术
5.1 JSP视图
配置视图解析器后,控制器返回逻辑视图名:
@GetMapping("/detail/{id}")
public String userDetail(@PathVariable Long id, Model model) {
User user = userService.findById(id);
model.addAttribute("user", user);
return "user/detail"; // 对应/WEB-INF/views/user/detail.jsp
}
5.2 Thymeleaf集成
添加Thymeleaf依赖:
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.15.RELEASE</version>
</dependency>
配置Thymeleaf视图解析器:
<bean id="templateResolver" class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
<property name="prefix" value="/WEB-INF/templates/"/>
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML5"/>
<property name="characterEncoding" value="UTF-8"/>
</bean>
<bean id="templateEngine" class="org.thymeleaf.spring5.SpringTemplateEngine">
<property name="templateResolver" ref="templateResolver"/>
</bean>
<bean class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
<property name="templateEngine" ref="templateEngine"/>
<property name="characterEncoding" value="UTF-8"/>
</bean>
六、拦截器与过滤器
6.1 拦截器实现
自定义拦截器实现HandlerInterceptor接口:
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception {
// 前置处理,返回true放行,false拦截
String token = request.getHeader("Authorization");
if (token == null || !token.startsWith("Bearer ")) {
response.sendError(HttpStatus.UNAUTHORIZED.value(), "未授权");
return false;
}
return true;
}
@Override
public void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler, ModelAndView modelAndView) throws Exception {
// 后置处理,视图渲染前执行
}
@Override
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler, Exception ex) throws Exception {
// 最终处理,请求完成后执行
}
}
6.2 拦截器配置
在Spring配置文件中注册拦截器:
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/api/**"/>
<mvc:exclude-mapping path="/api/auth/**"/>
<bean class="com.example.interceptor.AuthInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
6.3 过滤器与拦截器区别
| 特性 | 过滤器(Filter) | 拦截器(Interceptor) |
|---|---|---|
| 归属 | Servlet规范 | Spring MVC框架 |
| 作用范围 | 所有请求 | 仅Spring MVC请求 |
| 执行时机 | 请求前/响应后 | 控制器方法前后 |
| 依赖容器 | 依赖Servlet容器 | 不依赖Servlet容器 |
| 访问能力 | 不能访问Spring Bean | 可以访问Spring Bean |
七、异常处理
7.1 全局异常处理器
使用@ControllerAdvice实现全局异常处理:
@ControllerAdvice
public class GlobalExceptionHandler {
// 处理参数校验异常
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseStatus(HttpStatus.BAD_REQUEST)
public ResponseEntity<ErrorResponse> handleValidationException(
MethodArgumentNotValidException ex) {
List<String> errors = ex.getBindingResult()
.getFieldErrors()
.stream()
.map(error -> error.getField() + ": " + error.getDefaultMessage())
.collect(Collectors.toList());
ErrorResponse response = new ErrorResponse(
"VALIDATION_FAILED",
"参数校验失败",
errors
);
return ResponseEntity.badRequest().body(response);
}
// 处理业务异常
@ExceptionHandler(BusinessException.class)
public ResponseEntity<ErrorResponse> handleBusinessException(BusinessException ex) {
ErrorResponse response = new ErrorResponse(
ex.getCode(),
ex.getMessage()
);
return ResponseEntity.status(ex.getStatus()).body(response);
}
// 处理其他异常
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
public ResponseEntity<ErrorResponse> handleException(Exception ex) {
ErrorResponse response = new ErrorResponse(
"INTERNAL_ERROR",
"系统内部错误"
);
return ResponseEntity.internalServerError().body(response);
}
}
7.2 自定义异常
定义业务异常类:
public class BusinessException extends RuntimeException {
private final int code;
private final HttpStatus status;
public BusinessException(int code, String message) {
super(message);
this.code = code;
this.status = HttpStatus.BAD_REQUEST;
}
public BusinessException(int code, String message, HttpStatus status) {
super(message);
this.code = code;
this.status = status;
}
// getter方法
}
八、RESTful API开发
8.1 RESTful设计原则
- 资源标识:使用URI标识资源,如/users/{id}
- HTTP方法:GET获取、POST创建、PUT更新、DELETE删除
- 状态码:使用合适的HTTP状态码表示请求结果
- 无状态:每个请求包含足够信息,不依赖会话状态
8.2 RESTful控制器
@RestController
@RequestMapping("/api/users")
public class UserApiController {
@Autowired
private UserService userService;
// 获取所有用户
@GetMapping
public ResponseEntity<List<User>> getAllUsers() {
List<User> users = userService.findAll();
return ResponseEntity.ok(users);
}
// 根据ID获取用户
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
User user = userService.findById(id);
return ResponseEntity.ok(user);
}
// 创建用户
@PostMapping
public ResponseEntity<User> createUser(@RequestBody User user) {
User savedUser = userService.save(user);
return ResponseEntity.created(URI.create("/api/users/" + savedUser.getId()))
.body(savedUser);
}
// 更新用户
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User user) {
user.setId(id);
User updatedUser = userService.update(user);
return ResponseEntity.ok(updatedUser);
}
// 删除用户
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
userService.deleteById(id);
return ResponseEntity.noContent().build();
}
}
九、文件上传与下载
9.1 文件上传
配置MultipartResolver:
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10485760"/> <!-- 10MB -->
<property name="defaultEncoding" value="UTF-8"/>
</bean>
控制器处理文件上传:
@PostMapping("/upload")
public String uploadFile(@RequestParam("file") MultipartFile file) {
if (file.isEmpty()) {
return "redirect:/upload?error=文件为空";
}
try {
// 获取文件名
String fileName = file.getOriginalFilename();
// 保存文件
file.transferTo(new File("/uploads/" + fileName));
return "redirect:/upload?success=上传成功";
} catch (IOException e) {
return "redirect:/upload?error=上传失败";
}
}
9.2 文件下载
@GetMapping("/download/{fileName}")
public ResponseEntity<Resource> downloadFile(@PathVariable String fileName) {
try {
// 加载文件
Resource resource = new FileSystemResource("/uploads/" + fileName);
// 设置响应头
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=\"" + fileName + "\"");
headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE);
return ResponseEntity.ok()
.headers(headers)
.contentLength(resource.contentLength())
.body(resource);
} catch (Exception e) {
return ResponseEntity.notFound().build();
}
}
十、性能优化
10.1 启动优化
- 减少Bean数量:使用@Lazy进行懒加载
- 缩小包扫描范围:精确指定@ComponentScan的basePackage
- 开启预加载:使用spring-context-indexer加速启动
10.2 响应优化
- 启用缓存:使用@Cacheable缓存热点数据
- 异步处理:使用@Async处理耗时操作
- 连接池优化:配置数据库连接池参数
- 静态资源缓存:配置Cache-Control响应头
10.3 数据库优化
- 读写分离:主从数据库架构
- 分库分表:大数据量场景
- 索引优化:合理设计数据库索引
- 批量操作:使用batchUpdate减少事务提交次数
十一、实战项目:用户管理系统
11.1 项目结构
src/main/java/
├── com.example
│ ├── config/ # 配置类
│ ├── controller/ # 控制器层
│ ├── service/ # 服务层
│ ├── repository/ # 数据访问层
│ ├── model/ # 实体类
│ ├── dto/ # 数据传输对象
│ ├── exception/ # 异常类
│ └── interceptor/ # 拦截器
src/main/resources/
├── application.yml # 配置文件
├── static/ # 静态资源
└── templates/ # 模板文件
11.2 核心功能实现
用户控制器:
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping
public ResponseEntity<PageResult<User>> getUsers(
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "10") int size) {
Page<User> userPage = userService.findAll(page, size);
return ResponseEntity.ok(PageResult.of(userPage));
}
@PostMapping
public ResponseEntity<User> createUser(@Valid @RequestBody User user) {
User savedUser = userService.save(user);
return ResponseEntity.created(URI.create("/api/users/" + savedUser.getId()))
.body(savedUser);
}
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id,
@Valid @RequestBody User user) {
user.setId(id);
User updatedUser = userService.update(user);
return ResponseEntity.ok(updatedUser);
}
@DeleteMapping("/{id}")
public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
userService.deleteById(id);
return ResponseEntity.noContent().build();
}
}
全局异常处理:
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ErrorResponse> handleValidationException(
MethodArgumentNotValidException ex) {
List<String> errors = ex.getBindingResult()
.getFieldErrors()
.stream()
.map(error -> error.getField() + ": " + error.getDefaultMessage())
.collect(Collectors.toList());
ErrorResponse response = new ErrorResponse(
"VALIDATION_FAILED",
"参数校验失败",
errors
);
return ResponseEntity.badRequest().body(response);
}
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorResponse> handleResourceNotFound(
ResourceNotFoundException ex) {
ErrorResponse response = new ErrorResponse(
"NOT_FOUND",
ex.getMessage()
);
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response);
}
}
十二、总结
Spring Web MVC作为企业级Java Web开发的首选框架,通过本文的系统学习,您已经掌握了从基础概念到实战项目的完整知识体系。关键要点包括:
- 核心架构:理解DispatcherServlet、HandlerMapping、HandlerAdapter等核心组件的工作原理
- 控制器开发:熟练掌握@Controller、@RequestMapping等注解的使用
- 数据绑定:掌握@RequestParam、@RequestBody、@PathVariable等参数绑定方式
- 异常处理:使用@ControllerAdvice实现全局异常统一处理
- RESTful API:遵循RESTful设计原则开发规范的API接口
- 性能优化:掌握启动优化、响应优化、数据库优化等技巧
通过实际项目实践,您可以将理论知识转化为实际开发能力,构建出高性能、可维护的企业级Web应用。
若内容若侵犯到您的权益,请发送邮件至:platform_service@jienda.com我们将第一时间处理!
所有资源仅限于参考和学习,版权归JienDa作者所有,更多请访问JienDa首页。





