Skip to main content

Spring MVC 详解

Spring MVC是Spring框架的核心Web模块,基于MVC(Model-View-Controller)设计模式构建,提供了灵活、强大的Web应用开发解决方案。它是构建企业级Web应用的标准选择。

核心价值

Spring MVC = 松耦合架构 + 灵活配置 + 强大扩展 + 企业级支持

  • 🏗️ 松耦合架构:基于MVC设计模式,实现各层分离
  • ⚙️ 灵活配置:多种配置方式,适应不同需求
  • 🔌 强大扩展:丰富的拦截器和视图技术
  • 🔒 企业级支持:认证、安全、性能优化等特性

1. Spring MVC基础概念

1.1 什么是Spring MVC?

Spring MVC是一个基于Java的Web框架,实现了MVC设计模式,用于构建Web应用程序。它提供了完整的Web开发解决方案,包括请求处理、视图渲染、数据绑定等功能。

MVC架构模式

java
1// Model(模型)- 数据和业务逻辑
2@Entity
3public class User {
4 @Id
5 @GeneratedValue(strategy = GenerationType.IDENTITY)
6 private Long id;
7 private String name;
8 private String email;
9
10 // getter和setter方法
11 public Long getId() { return id; }
12 public void setId(Long id) { this.id = id; }
13 public String getName() { return name; }
14 public void setName(String name) { this.name = name; }
15 public String getEmail() { return email; }
16 public void setEmail(String email) { this.email = email; }
17}

1.2 Spring MVC核心组件

Spring MVC框架由多个核心组件组成,它们协同工作处理web请求并生成响应。

组件作用实现类
DispatcherServlet前端控制器,统一处理请求org.springframework.web.servlet.DispatcherServlet
HandlerMapping处理器映射,根据URL找到HandlerRequestMappingHandlerMapping
HandlerAdapter处理器适配器,执行HandlerRequestMappingHandlerAdapter
ViewResolver视图解析器,解析视图名称InternalResourceViewResolver
Handler处理器,执行业务逻辑@Controller注解的类
View视图,渲染响应JSP、Thymeleaf等
组件协作

Spring MVC通过这些核心组件的协作,实现了请求的统一处理和响应的统一返回,提供了松耦合的Web开发架构。

2. Spring MVC请求处理流程

2.1 请求处理流程详解

Spring MVC的请求处理流程是一个完整的责任链模式实现:

请求处理流程示例代码
请求处理流程
java
1public class RequestProcessingFlow {
2
3 public void processRequest(HttpServletRequest request, HttpServletResponse response) {
4 try {
5 // 1. 请求进入DispatcherServlet
6 DispatcherServlet dispatcher = new DispatcherServlet();
7
8 // 2. 获取HandlerMapping
9 HandlerMapping handlerMapping = getHandlerMapping();
10
11 // 3. 根据请求URL找到对应的Handler
12 Object handler = handlerMapping.getHandler(request);
13
14 // 4. 获取HandlerAdapter
15 HandlerAdapter handlerAdapter = getHandlerAdapter(handler);
16
17 // 5. 执行Handler方法
18 ModelAndView mv = handlerAdapter.handle(request, response, handler);
19
20 // 6. 处理视图
21 if (mv != null) {
22 processView(request, response, mv);
23 }
24
25 } catch (Exception e) {
26 // 异常处理
27 handleException(request, response, e);
28 }
29 }
30
31 private HandlerMapping getHandlerMapping() {
32 return new RequestMappingHandlerMapping();
33 }
34
35 private HandlerAdapter getHandlerAdapter(Object handler) {
36 return new RequestMappingHandlerAdapter();
37 }
38
39 private void processView(HttpServletRequest request, HttpServletResponse response, ModelAndView mv) {
40 ViewResolver viewResolver = new InternalResourceViewResolver();
41 View view = viewResolver.resolveViewName(mv.getViewName(), Locale.getDefault());
42 view.render(mv.getModel(), request, response);
43 }
44}

详细流程说明

  1. 请求接收:客户端发送HTTP请求到DispatcherServlet
  2. Handler映射:通过HandlerMapping找到对应的Handler
  3. Handler适配:通过HandlerAdapter适配并执行Handler
  4. 业务处理:Handler执行业务逻辑,返回ModelAndView
  5. 视图解析:通过ViewResolver解析视图名称
  6. 视图渲染:渲染视图并返回响应

2.2 核心接口详解

java
1// HandlerMapping接口
2public interface HandlerMapping {
3 Object getHandler(HttpServletRequest request) throws Exception;
4}
5
6// 实现类
7public class RequestMappingHandlerMapping implements HandlerMapping {
8 @Override
9 public Object getHandler(HttpServletRequest request) throws Exception {
10 // 根据请求URL找到对应的Handler
11 String uri = request.getRequestURI();
12 // 查找映射关系
13 return findHandler(uri);
14 }
15}

3. 控制器开发

3.1 控制器基础

控制器是Spring MVC的核心组件,负责处理HTTP请求并返回响应。

基础控制器
java
1@Controller
2@RequestMapping("/api/users")
3public class UserController {
4
5 @Autowired
6 private UserService userService;
7
8 // GET请求 - 获取用户列表
9 @GetMapping
10 public ResponseEntity<List<User>> getUsers() {
11 List<User> users = userService.findAll();
12 return ResponseEntity.ok(users);
13 }
14
15 // GET请求 - 获取单个用户
16 @GetMapping("/{id}")
17 public ResponseEntity<User> getUser(@PathVariable Long id) {
18 User user = userService.findById(id);
19 if (user != null) {
20 return ResponseEntity.ok(user);
21 }
22 return ResponseEntity.notFound().build();
23 }
24
25 // POST请求 - 创建用户
26 @PostMapping
27 public ResponseEntity<User> createUser(@RequestBody User user) {
28 User savedUser = userService.save(user);
29 return ResponseEntity.status(HttpStatus.CREATED).body(savedUser);
30 }
31
32 // PUT请求 - 更新用户
33 @PutMapping("/{id}")
34 public ResponseEntity<User> updateUser(@PathVariable Long id, @RequestBody User user) {
35 user.setId(id);
36 User updatedUser = userService.update(user);
37 return ResponseEntity.ok(updatedUser);
38 }
39
40 // DELETE请求 - 删除用户
41 @DeleteMapping("/{id}")
42 public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
43 userService.deleteById(id);
44 return ResponseEntity.noContent().build();
45 }
46}

3.2 请求映射注解

Spring MVC提供了丰富的请求映射注解,支持各种HTTP方法和参数绑定:

java
1// @RequestMapping - 通用映射
2 @RequestMapping(value = "/users", method = RequestMethod.GET)
3 public String getUsers() {
4 return "user/list";
5 }
6
7// 可以在类级别使用
8@Controller
9@RequestMapping("/users")
10public class UserController {
11 // 方法映射会相对于类映射
12 @RequestMapping("/{id}") // 实际路径为/users/{id}
13 public String getUser(@PathVariable Long id) {
14 return "user/detail";
15 }
16}
注解选择
  • 使用具体的HTTP方法注解(@GetMapping、@PostMapping等)比@RequestMapping更清晰
  • 对于RESTful API,推荐使用@RestController注解
  • 对于传统Web应用,使用@Controller注解

3.3 参数绑定注解

Spring MVC提供了多种参数绑定注解,支持各种参数类型的自动绑定:

java
1// @PathVariable - 路径变量
2 @GetMapping("/users/{id}/orders/{orderId}")
3 public String getUserOrder(@PathVariable Long id, @PathVariable Long orderId) {
4 return "user/order";
5 }

4. 拦截器机制

4.1 拦截器基础

拦截器是Spring MVC的重要特性,允许在请求处理的不同阶段进行拦截和处理。

拦截器实现
java
1// 实现HandlerInterceptor接口
2public class LoggingInterceptor implements HandlerInterceptor {
3
4 private static final Logger logger = LoggerFactory.getLogger(LoggingInterceptor.class);
5
6 @Override
7 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
8 logger.info("请求开始: {} {}", request.getMethod(), request.getRequestURI());
9 request.setAttribute("startTime", System.currentTimeMillis());
10 return true; // 返回true继续执行,返回false中断请求
11 }
12
13 @Override
14 public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
15 logger.info("请求处理完成: {} {}", request.getMethod(), request.getRequestURI());
16 }
17
18 @Override
19 public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
20 long startTime = (Long) request.getAttribute("startTime");
21 long endTime = System.currentTimeMillis();
22 logger.info("请求完成: {} {} 耗时: {}ms", request.getMethod(), request.getRequestURI(), endTime - startTime);
23 }
24}

拦截器方法说明

方法执行时机用途能否中断请求
preHandle控制器方法执行前前置检查、认证授权可以
postHandle控制器方法执行后,视图渲染前模型数据修改、视图选择不可以
afterCompletion视图渲染完成后清理资源、日志记录不可以

4.2 拦截器应用

认证拦截器
java
1public class AuthenticationInterceptor implements HandlerInterceptor {
2
3 @Override
4 public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
5 String token = request.getHeader("Authorization");
6
7 if (token == null || !isValidToken(token)) {
8 response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
9 return false;
10 }
11
12 // 设置用户信息到请求属性
13 User user = getUserFromToken(token);
14 request.setAttribute("currentUser", user);
15
16 return true;
17 }
18
19 private boolean isValidToken(String token) {
20 return token != null && token.startsWith("Bearer ");
21 }
22
23 private User getUserFromToken(String token) {
24 // 从token中获取用户信息
25 return new User();
26 }
27}

5. 异常处理

5.1 全局异常处理

Spring MVC提供了全局异常处理机制,可以统一处理应用中的异常:

方法级异常处理
java
1@Controller
2public class UserController {
3
4 // 控制器内的异常处理
5 @ExceptionHandler(UserNotFoundException.class)
6 public ResponseEntity<ErrorResponse> handleUserNotFoundException(UserNotFoundException ex) {
7 ErrorResponse error = new ErrorResponse();
8 error.setMessage(ex.getMessage());
9 error.setStatus(HttpStatus.NOT_FOUND.value());
10
11 return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
12 }
13
14 @GetMapping("/users/{id}")
15 public ResponseEntity<User> getUser(@PathVariable Long id) {
16 User user = userService.findById(id);
17 if (user == null) {
18 throw new UserNotFoundException("用户不存在: " + id);
19 }
20 return ResponseEntity.ok(user);
21 }
22}

5.2 自定义异常

自定义异常类
java
1// 用户不存在异常
2public class UserNotFoundException extends RuntimeException {
3 public UserNotFoundException(String message) {
4 super(message);
5 }
6}
7
8// 验证异常
9public class ValidationException extends RuntimeException {
10 private List<String> errors;
11
12 public ValidationException(String message, List<String> errors) {
13 super(message);
14 this.errors = errors;
15 }
16
17 public List<String> getErrors() {
18 return errors;
19 }
20}

6. 数据验证

6.1 Bean校验

Spring MVC集成了Bean Validation API,支持声明式数据验证:

Bean验证示例
java
1// 验证模型
2public class UserDTO {
3 @NotBlank(message = "用户名不能为空")
4 @Size(min = 4, max = 50, message = "用户名长度必须在4-50之间")
5 private String username;
6
7 @NotBlank(message = "密码不能为空")
8 @Pattern(regexp = "^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d]{8,}$", message = "密码至少8位,包含字母和数字")
9 private String password;
10
11 @NotBlank(message = "电子邮件不能为空")
12 @Email(message = "电子邮件格式不正确")
13 private String email;
14
15 @Min(value = 18, message = "年龄必须大于等于18")
16 private int age;
17
18 // getter和setter方法
19}
20
21// 控制器中使用
22@RestController
23@RequestMapping("/api/users")
24public class UserController {
25
26 @PostMapping("/register")
27 public ResponseEntity<?> register(@Valid @RequestBody UserDTO userDTO, BindingResult result) {
28 if (result.hasErrors()) {
29 Map<String, String> errors = new HashMap<>();
30 result.getFieldErrors().forEach(err ->
31 errors.put(err.getField(), err.getDefaultMessage())
32 );
33 return ResponseEntity.badRequest().body(errors);
34 }
35
36 // 业务处理
37 return ResponseEntity.ok("用户注册成功");
38 }
39}

6.2 常用校验注解

注解说明示例
@NotNull不能为null@NotNull(message = "不能为空")
@NotEmpty不能为空字符串或集合@NotEmpty(message = "不能为空")
@NotBlank不能为空白字符串@NotBlank(message = "不能为空白")
@Size长度或大小限制@Size(min = 2, max = 10)
@Min/@Max最小/最大值@Min(value = 18)
@Pattern正则表达式校验@Pattern(regexp = "\\d+")
@Email电子邮件格式@Email(message = "邮箱格式不正确")
@Future/@Past日期在当前时间之后/之前@Future(message = "必须是将来时间")
@AssertTrue必须为true@AssertTrue(message = "必须接受协议")

6.3 分组校验

分组校验示例
java
1// 定义验证组
2public interface Create {}
3public interface Update {}
4
5// 模型使用分组
6public class UserDTO {
7 @NotNull(groups = {Update.class})
8 private Long id;
9
10 @NotBlank(groups = {Create.class, Update.class})
11 private String username;
12
13 @NotBlank(groups = {Create.class})
14 @Null(groups = {Update.class})
15 private String password;
16
17 // getter和setter方法
18}
19
20// 控制器使用分组
21@RestController
22@RequestMapping("/api/users")
23public class UserController {
24
25 @PostMapping
26 public ResponseEntity<?> create(@Validated(Create.class) @RequestBody UserDTO user, BindingResult result) {
27 if (result.hasErrors()) {
28 return ResponseEntity.badRequest().body(getErrors(result));
29 }
30 return ResponseEntity.ok("用户创建成功");
31 }
32
33 @PutMapping("/{id}")
34 public ResponseEntity<?> update(@Validated(Update.class) @RequestBody UserDTO user, BindingResult result) {
35 if (result.hasErrors()) {
36 return ResponseEntity.badRequest().body(getErrors(result));
37 }
38 return ResponseEntity.ok("用户更新成功");
39 }
40
41 private Map<String, String> getErrors(BindingResult result) {
42 Map<String, String> errors = new HashMap<>();
43 result.getFieldErrors().forEach(err ->
44 errors.put(err.getField(), err.getDefaultMessage())
45 );
46 return errors;
47 }
48}

7. 文件上传

7.1 文件上传配置

Spring MVC提供了内置的文件上传支持,可以轻松处理文件上传请求:

上传配置
java
1@Configuration
2public class FileUploadConfig {
3
4 @Bean
5 public MultipartResolver multipartResolver() {
6 CommonsMultipartResolver resolver = new CommonsMultipartResolver();
7 resolver.setMaxUploadSize(10 * 1024 * 1024); // 10MB
8 resolver.setMaxUploadSizePerFile(5 * 1024 * 1024); // 5MB
9 resolver.setDefaultEncoding("UTF-8");
10 return resolver;
11 }
12}
13
14// 或使用SpringBoot中的配置
15@SpringBootApplication
16public class Application {
17
18 public static void main(String[] args) {
19 SpringApplication.run(Application.class, args);
20 }
21}
22
23// application.yml
24/*
25spring:
26 servlet:
27 multipart:
28 max-file-size: 5MB
29 max-request-size: 10MB
30 enabled: true
31*/

7.2 文件上传视图

文件上传表单
html
1<!-- upload/form.html -->
2<!DOCTYPE html>
3<html xmlns:th="http://www.thymeleaf.org">
4<head>
5 <title>文件上传</title>
6</head>
7<body>
8 <h1>文件上传</h1>
9
10 <div th:if="${message}">
11 <p th:text="${message}"></p>
12 </div>
13
14 <form method="POST" action="/upload" enctype="multipart/form-data">
15 <div>
16 <label for="file">选择文件:</label>
17 <input type="file" id="file" name="file" />
18 </div>
19 <div>
20 <button type="submit">上传</button>
21 </div>
22 </form>
23
24 <h2>多文件上传</h2>
25 <form method="POST" action="/upload/multi" enctype="multipart/form-data">
26 <div>
27 <label for="files">选择文件:</label>
28 <input type="file" id="files" name="files" multiple />
29 </div>
30 <div>
31 <button type="submit">上传</button>
32 </div>
33 </form>
34</body>
35</html>

8. 视图技术

8.1 视图解析器

Spring MVC支持多种视图技术,通过视图解析器将逻辑视图名解析为实际的视图对象:

JSP视图解析器
java
1@Configuration
2public class WebConfig implements WebMvcConfigurer {
3
4 @Bean
5 public ViewResolver jspViewResolver() {
6 InternalResourceViewResolver resolver = new InternalResourceViewResolver();
7 resolver.setPrefix("/WEB-INF/views/");
8 resolver.setSuffix(".jsp");
9 resolver.setViewClass(JstlView.class);
10 return resolver;
11 }
12}
13
14// 控制器
15@Controller
16public class UserController {
17
18 @GetMapping("/users")
19 public String listUsers(Model model) {
20 // 逻辑视图名 "user/list" 解析为 "/WEB-INF/views/user/list.jsp"
21 return "user/list";
22 }
23}

8.2 视图内容协商

Spring MVC支持内容协商,可以根据请求的Accept头或URL参数返回不同格式的响应:

内容协商配置
java
1@Configuration
2public class ContentNegotiationConfig implements WebMvcConfigurer {
3
4 @Override
5 public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
6 // 通过URL参数进行内容协商
7 configurer
8 .favorParameter(true)
9 .parameterName("format")
10 .ignoreAcceptHeader(false)
11 .defaultContentType(MediaType.APPLICATION_JSON)
12 .mediaType("json", MediaType.APPLICATION_JSON)
13 .mediaType("xml", MediaType.APPLICATION_XML);
14 }
15
16 @Override
17 public void configureViewResolvers(ViewResolverRegistry registry) {
18 registry.enableContentNegotiation(
19 new MappingJackson2JsonView(),
20 new MarshallingView(jaxb2Marshaller()),
21 pdfView()
22 );
23 }
24
25 @Bean
26 public Jaxb2Marshaller jaxb2Marshaller() {
27 Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
28 marshaller.setPackagesToScan("com.example.model");
29 return marshaller;
30 }
31
32 @Bean
33 public View pdfView() {
34 return new PdfView();
35 }
36}
37
38// 控制器
39@Controller
40public class UserController {
41
42 @GetMapping("/users/{id}")
43 public User getUser(@PathVariable Long id) {
44 // 根据内容协商返回JSON或XML
45 return userService.findById(id);
46 }
47}

9. RESTful API

9.1 RESTful API设计

RESTful API设计是构建现代Web服务的重要范式,Spring MVC提供了全面的支持:

原则说明示例
资源导向使用名词而非动词/users 而不是 /getUsers
HTTP方法语义使用正确的HTTP方法GET、POST、PUT、DELETE
无状态每个请求包含完整信息不依赖会话状态
统一接口使用标准HTTP状态码200、201、400、404等
可缓存支持缓存机制使用ETag、Cache-Control

9.2 RESTful API实现

RESTful API控制器
java
1@RestController
2@RequestMapping("/api/users")
3public class UserRestController {
4
5 @Autowired
6 private UserService userService;
7
8 // GET /api/users - 获取用户列表
9 @GetMapping
10 public ResponseEntity<List<User>> getUsers(
11 @RequestParam(defaultValue = "0") int page,
12 @RequestParam(defaultValue = "10") int size) {
13
14 List<User> users = userService.findAll(page, size);
15 return ResponseEntity.ok(users);
16 }
17
18 // GET /api/users/{id} - 获取单个用户
19 @GetMapping("/{id}")
20 public ResponseEntity<User> getUser(@PathVariable Long id) {
21 User user = userService.findById(id);
22 if (user == null) {
23 return ResponseEntity.notFound().build();
24 }
25 return ResponseEntity.ok(user);
26 }
27
28 // POST /api/users - 创建用户
29 @PostMapping
30 public ResponseEntity<User> createUser(@Valid @RequestBody User user) {
31 User savedUser = userService.save(user);
32 return ResponseEntity.status(HttpStatus.CREATED)
33 .header("Location", "/api/users/" + savedUser.getId())
34 .body(savedUser);
35 }
36
37 // PUT /api/users/{id} - 更新用户
38 @PutMapping("/{id}")
39 public ResponseEntity<User> updateUser(@PathVariable Long id, @Valid @RequestBody User user) {
40 user.setId(id);
41 User updatedUser = userService.update(user);
42 return ResponseEntity.ok(updatedUser);
43 }
44
45 // DELETE /api/users/{id} - 删除用户
46 @DeleteMapping("/{id}")
47 public ResponseEntity<Void> deleteUser(@PathVariable Long id) {
48 userService.deleteById(id);
49 return ResponseEntity.noContent().build();
50 }
51 }

9.3 API版本控制

API版本控制
java
1// 1. URL路径版本控制
2@RestController
3@RequestMapping("/api/v1/users")
4public class UserApiV1Controller {
5 // V1版本的API
6}
7
8@RestController
9@RequestMapping("/api/v2/users")
10public class UserApiV2Controller {
11 // V2版本的API
12}
13
14// 2. 请求参数版本控制
15@RestController
16@RequestMapping("/api/users")
17public class UserApiVersionController {
18
19 @GetMapping(params = "version=1")
20 public ResponseEntity<UserV1> getUserV1(@RequestParam Long id) {
21 // V1版本的处理逻辑
22 }
23
24 @GetMapping(params = "version=2")
25 public ResponseEntity<UserV2> getUserV2(@RequestParam Long id) {
26 // V2版本的处理逻辑
27 }
28}
29
30// 3. 请求头版本控制
31@RestController
32@RequestMapping("/api/users")
33public class UserApiHeaderVersionController {
34
35 @GetMapping(headers = "X-API-Version=1")
36 public ResponseEntity<UserV1> getUserV1(@RequestParam Long id) {
37 // V1版本的处理逻辑
38 }
39
40 @GetMapping(headers = "X-API-Version=2")
41 public ResponseEntity<UserV2> getUserV2(@RequestParam Long id) {
42 // V2版本的处理逻辑
43 }
44}
45
46// 4. Accept头版本控制
47@RestController
48@RequestMapping("/api/users")
49public class UserApiAcceptVersionController {
50
51 @GetMapping(produces = "application/vnd.company.app-v1+json")
52 public ResponseEntity<UserV1> getUserV1(@RequestParam Long id) {
53 // V1版本的处理逻辑
54 }
55
56 @GetMapping(produces = "application/vnd.company.app-v2+json")
57 public ResponseEntity<UserV2> getUserV2(@RequestParam Long id) {
58 // V2版本的处理逻辑
59 }
60}

10. 面试题精选

10.1 基础概念题

Q: Spring MVC的请求处理流程是怎样的?

A: Spring MVC的请求处理流程如下:

  1. 请求接收:客户端发送HTTP请求到DispatcherServlet
  2. Handler映射:通过HandlerMapping找到对应的Handler
  3. Handler适配:通过HandlerAdapter适配并执行Handler
  4. 业务处理:Handler执行业务逻辑,返回ModelAndView
  5. 视图解析:通过ViewResolver解析视图名称
  6. 视图渲染:渲染视图并返回响应

整个过程由DispatcherServlet统一调度,实现了前端控制器模式,使各组件解耦并协同工作。

10.2 实践题

Q: 如何实现RESTful API?

A: 实现RESTful API需要:

  • 使用@RestController注解
  • 使用@GetMapping@PostMapping等注解匹配HTTP方法
  • 返回ResponseEntity对象控制HTTP状态码和响应头
  • 使用@PathVariable处理路径参数
  • 使用@RequestBody处理请求体
  • 遵循REST设计原则:资源命名、HTTP方法语义、无状态、统一接口等
  • 使用适当的HTTP状态码:200(OK)、201(Created)、204(No Content)、400(Bad Request)、404(Not Found)等

对于更高级的RESTful API,还可以考虑使用HATEOAS添加超链接,使API更具自描述性。

10.3 高级题

Q: Spring MVC如何实现异步请求处理?

A: Spring MVC支持三种异步请求处理方式:

  1. 返回Callable对象
java
1@GetMapping("/async")
2public Callable<String> asyncTask() {
3 return () -> {
4 // 异步任务
5 Thread.sleep(5000);
6 return "Async result";
7 };
8}
  1. 返回DeferredResult对象
java
1@GetMapping("/async-deferred")
2public DeferredResult<String> asyncDeferredResult() {
3 DeferredResult<String> result = new DeferredResult<>();
4 taskExecutor.execute(() -> {
5 try {
6 Thread.sleep(5000);
7 result.setResult("Deferred result");
8 } catch (Exception e) {
9 result.setErrorResult(e);
10 }
11 });
12 return result;
13}
  1. 返回CompletableFuture对象
java
1@GetMapping("/async-future")
2public CompletableFuture<String> asyncFuture() {
3 return CompletableFuture.supplyAsync(() -> {
4 try {
5 Thread.sleep(5000);
6 return "Future result";
7 } catch (Exception e) {
8 throw new RuntimeException(e);
9 }
10 });
11}

异步请求处理的好处是可以释放Web容器线程,提高系统吞吐量,特别是对于长时间运行的任务。

Spring MVC学习要点
  1. 理解核心组件:掌握DispatcherServlet、HandlerMapping、HandlerAdapter等核心组件
  2. 熟悉请求流程:理解从请求到响应的完整处理流程
  3. 掌握控制器开发:学会使用@Controller、@RestController等注解开发控制器
  4. 了解视图技术:熟悉JSP、Thymeleaf等视图技术
  5. 学会RESTful API:掌握RESTful API设计和实现
  6. 熟悉数据验证:学会使用Bean Validation进行数据验证
  7. 掌握拦截器机制:学会自定义拦截器处理横切关注点

通过本章的学习,你应该已经掌握了Spring MVC的核心概念、请求处理流程和实际应用。Spring MVC是构建Java Web应用的重要框架,掌握其原理和使用方法对于开发高质量的Web应用至关重要。无论是传统Web应用还是现代RESTful API,Spring MVC都能提供强大而灵活的支持。

参与讨论