前后端分离项目中Spring MVC的请求执行流程
在前后端分离架构中,Spring MVC的执行流程与传统服务端渲染模式有显著差异,主要变化在于视图解析和响应处理环节。以下是完整的执行流程分析,特别针对RESTful API场景:
一、核心执行流程(RESTful API场景)

二、关键阶段详细解析
1. 请求接收与分发阶段
DispatcherServlet的核心工作:
- 初始化九大核心组件(包括
HandlerMapping
、HandlerAdapter
等) - 处理
Content-Type
和Accept
头部 - 处理CORS预检请求(OPTIONS方法)
- 根据请求路径选择对应的
HandlerMapping
特殊处理:
- 对于
application/json
内容类型,会启用MappingJackson2HttpMessageConverter
- 如果请求包含
Authorization
头,会触发安全过滤器链
2. 处理器映射阶段
HandlerMapping的工作机制:
RequestMappingHandlerMapping
扫描所有@RestController
注解的类- 构建包含以下元素的映射注册表:
- URL路径模式(支持Ant风格和路径变量)
- 支持的HTTP方法(GET/POST/PUT等)
- 消费/生产的媒体类型(consumes/produces)
- 参数条件(@RequestParam等)
- 匹配优先级:
- 精确路径优先于模式匹配
- 最长路径模式优先
示例匹配过程:
@RestController
@RequestMapping("/api/v1/users")
public class UserController {@GetMapping(value = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE)public UserDTO getUser(@PathVariable Long id) {// ...}
}
当请求GET /api/v1/users/123
时:
- 匹配到
UserController.getUser()
方法 - 提取路径变量
id=123
- 确认produces类型匹配
3. 参数绑定阶段
参数解析器链(HandlerMethodArgumentResolver):
参数类型 | 对应解析器 | 典型注解 |
URL路径参数 | PathVariableMethodArgumentResolver | @PathVariable |
查询参数 | RequestParamMethodArgumentResolver | @RequestParam |
JSON/XML请求体 | RequestResponseBodyMethodProcessor | @RequestBody |
请求头 | RequestHeaderMethodArgumentResolver | @RequestHeader |
Cookie值 | ServletCookieValueMethodArgumentResolver | @CookieValue |
Session属性 | SessionAttributeMethodArgumentResolver | @SessionAttribute |
复杂参数绑定示例:
@PostMapping("/search")
public PageResult<UserDTO> searchUsers(@RequestBody UserQuery query,@RequestHeader("X-Auth-Token") String token,@Valid PageRequest pageRequest) {// ...
}
4. 业务处理阶段
控制器的典型职责:
- 参数验证(结合JSR-303)
- 业务逻辑编排
- 异常捕获与转换
- 返回领域对象或DTO
RESTful最佳实践:
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public ResponseEntity<UserDTO> createUser(@Valid @RequestBody UserCreateDTO dto) {UserDTO created = userService.createUser(dto);URI location = ServletUriComponentsBuilder.fromCurrentRequest().path("/{id}").buildAndExpand(created.getId()).toUri();return ResponseEntity.created(location).body(created);
}
5. 返回值处理阶段
ResponseBody处理机制:
RequestResponseBodyMethodProcessor
处理返回值- 选择匹配的
HttpMessageConverter
:
MappingJackson2HttpMessageConverter
:处理JSONMappingJackson2XmlHttpMessageConverter
:处理XMLByteArrayHttpMessageConverter
:处理字节数组
- 根据
Accept
头决定响应格式
转换器选择算法:
- 检查控制器方法声明的produces类型
- 检查请求的Accept头
- 按照转换器注册顺序选择第一个能处理的
三、前后端分离特有处理
1. 统一响应封装模式
响应体封装策略:
public class ApiResult<T> {private long timestamp = System.currentTimeMillis();private String code;private String message;private T data;public static <T> ApiResult<T> success(T data) {return new ApiResult<>("200", "success", data);}// 工厂方法省略...
}
通过ControllerAdvice实现统一包装:
@RestControllerAdvice
public class ResponseWrapper implements ResponseBodyAdvice<Object> {@Overridepublic boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {// 不包装已经封装的结果或特定类型return !returnType.getParameterType().equals(ApiResult.class) && !returnType.hasMethodAnnotation(NoWrapper.class);}@Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType,MediaType selectedContentType,Class<? extends HttpMessageConverter<?>> selectedConverterType,ServerHttpRequest request, ServerHttpResponse response) {return ApiResult.success(body);}
}
2. 全局异常处理机制
异常处理中心:
@RestControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(BusinessException.class)public ResponseEntity<ApiResult<Void>> handleBusinessException(BusinessException ex) {return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(ApiResult.error(ex.getErrorCode(), ex.getMessage()));}@ExceptionHandler(MethodArgumentNotValidException.class)@ResponseStatus(HttpStatus.BAD_REQUEST)public ApiResult<Map<String, String>> handleValidationException(MethodArgumentNotValidException ex) {Map<String, String> errors = ex.getBindingResult().getFieldErrors().stream().collect(Collectors.toMap(FieldError::getField,fieldError -> Optional.ofNullable(fieldError.getDefaultMessage()).orElse("")));return ApiResult.error("VALIDATION_FAILED", "参数校验失败", errors);}
}
3. 跨域解决方案
精细化CORS配置:
@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addCorsMappings(CorsRegistry registry) {registry.addMapping("/api/**").allowedOrigins("https://frontend.com").allowedMethods("GET", "POST", "PUT", "DELETE").allowedHeaders("Content-Type", "Authorization").exposedHeaders("X-Custom-Header").allowCredentials(true).maxAge(3600);}
}
四、性能优化关键点
1. 消息转换器优化
Jackson自定义配置:
@Configuration
public class JacksonConfig {@Beanpublic Jackson2ObjectMapperBuilderCustomizer jacksonCustomizer() {return builder -> {builder.simpleDateFormat("yyyy-MM-dd HH:mm:ss");builder.timeZone(TimeZone.getTimeZone("Asia/Shanghai"));builder.modules(new JavaTimeModule());builder.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS,DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);builder.featuresToEnable(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL,MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS);};}
}
2. 异步处理模式
异步控制器实现:
@RestController
@RequestMapping("/async")
public class AsyncController {@GetMapping("/data")public CompletableFuture<ApiResult<Data>> fetchData() {return CompletableFuture.supplyAsync(() -> {// 模拟耗时操作try { Thread.sleep(1000); } catch (InterruptedException e) { /*...*/ }return dataService.getComplexData();}).thenApply(ApiResult::success);}@GetMapping("/deferred")public DeferredResult<ApiResult<Data>> deferredResult() {DeferredResult<ApiResult<Data>> result = new DeferredResult<>(5000L);CompletableFuture.runAsync(() -> {try {Data data = dataService.getComplexData();result.setResult(ApiResult.success(data));} catch (Exception e) {result.setErrorResult(e);}});return result;}
}
五、安全防护措施
1. 输入验证体系
DTO验证示例:
public class UserCreateDTO {@NotBlank(message = "用户名不能为空")@Size(min = 4, max = 20, message = "用户名长度4-20个字符")private String username;@Email(message = "邮箱格式不正确")private String email;@Pattern(regexp = "^(?=.*[A-Za-z])(?=.*\\d)[A-Za-z\\d]{8,}$",message = "密码必须至少8个字符,包含字母和数字")private String password;@AssertTrue(message = "必须接受用户协议")private boolean acceptedTerms;
}
2. 防XSS/CSRF策略
XSS过滤配置:
@Bean
public FilterRegistrationBean<XssFilter> xssFilter() {FilterRegistrationBean<XssFilter> registration = new FilterRegistrationBean<>();registration.setFilter(new XssFilter());registration.addUrlPatterns("/api/*");registration.setOrder(Ordered.HIGHEST_PRECEDENCE);return registration;
}public class XssFilter extends OncePerRequestFilter {private final XssCleaner xssCleaner = new DefaultXssCleaner();@Overrideprotected void doFilterInternal(HttpServletRequest request,HttpServletResponse response,FilterChain chain) throws IOException, ServletException {chain.doFilter(new XssRequestWrapper(request, xssCleaner), response);}
}
通过以上深度解析,开发者可以全面掌握前后端分离架构下Spring MVC的完整工作流程,包括从请求接收到响应返回的每个关键环节,以及针对RESTful API场景的特殊处理方式和优化策略。