SpringMVC知识点总结

发布于:2025-06-21 ⋅ 阅读:(16) ⋅ 点赞:(0)

目录

SpringMVC处理流程

什么是DispatcherServlet

为什么需要DispatcherServlet

工作流程:请求的生命周期

什么是Handler Mapping

一、核心概念:为什么需要 HandlerMapping?

二、工作原理:请求匹配流程

三、常见 HandlerMapping 实现类

什么是Handler Adapter

一、核心概念:为什么需要 HandlerAdapter?

二、工作流程:请求到处理器的适配过程

 什么是View Resolver

一、核心概念:为什么需要 View Resolver?

二、工作流程:逻辑视图名 → 实际视图对象

什么是ModelAndView

使用 ModelAndView 的优点

什么是@ModelAttribute注解

@ModelAttribute 的使用场景

什么是@RequestParam注解

 什么是 @PathVariable 注解

 什么是SpringMVC的拦截器

一、拦截器的核心作用

二、拦截器的工作流程

 三、拦截器的实现方式

什么是SpringMVC的异常处理机制

使用 @ControllerAdvice + @ExceptionHandler

什么是 Spring MVC 的 REST 支持

一、核心特性与优势

如何在 Spring MVC 中处理 JSON 数据

接收 JSON 数据

返回 JSON 数据

什么是@RestController注解

如何在 Spring MVC 中实现跨域资源共享(CORS)

一、全局配置(推荐)

二、控制器级别配置

三、方法级别配置

如何在 Spring MVC 中使@ExceptionHandler 注解

一、基本用法:在控制器内处理特定异常

二、全局异常处理:使用 @ControllerAdvice


SpringMVC处理流程

SpringMVC是Spring框架中的一个模块用于构建基于Web的应用程序。遵循Model-View-Controller的设计模式,将业务逻辑、用户界面和数据分离。

处理流程

  1. 用户请求:客户端向服务器发送 HTTP 请求。
  2. 前端控制器:DispatcherServlet 作为前端控制器,接收所有请求。
  3. 处理器映射:DispatcherServlet 通过 HandlerMapping 找到处理请求的 Handler(即 Controller 中的方法)。
  4. 处理器适配器:通过 HandlerAdapter 调用 Handler。
  5. 处理器处理请求:Handler 处理请求,并返回一个 ModelAndView 对象。
  6. 视图解析器:DispatcherServlet 通过 ViewResolver 解析 ModelAndView 中的逻辑视图名,得到实际的 View。
  7. 视图渲染:View 将模型数据渲染为具体的视图(如 JSP、JSON 等)。
  8. 响应客户端:将渲染结果返回给客户端。

核心组件

  • DispatcherServlet:前端控制器,负责接收请求、协调组件处理请求和返回响应。
  • HandlerMapping:处理器映射器,根据请求找到对应的 Handler。
  • HandlerAdapter:处理器适配器,调用 Handler。
  • Handler:处理器,即 Controller 中的方法,负责处理请求。
  • ViewResolver:视图解析器,将逻辑视图名解析为实际的 View。
  • View:视图,负责渲染模型数据。

什么是DispatcherServlet

DispatcherServlet 是 SpringMVC 框架的核心组件,作为整个请求处理流程的中央调度器(Front Controller),负责接收所有 HTTP 请求并协调各个组件完成请求的处理和响应。

为什么需要DispatcherServlet

1.统一入口
所有请求(如 /user/list/order/create)都由 DispatcherServlet 接收,避免每个控制器单独处理 HTTP 连接。

2.职责分离
DispatcherServlet 不处理具体业务逻辑,仅负责:

  • 路由请求到合适的控制器方法
  • 管理请求处理流程中的组件协作
  • 返回最终响应给客户端

3.遵循 MVC 模式

将请求处理、业务逻辑和视图渲染分离,提高代码可维护性。

工作流程:请求的生命周期

当客户端发送请求时,DispatcherServlet 的处理流程如下:

  1. 接收请求 → 所有请求首先到达 DispatcherServlet
  2. 映射处理器 → 通过 HandlerMapping 找到处理该请求的控制器方法(Handler)。
  3. 调用处理器 → 通过 HandlerAdapter 调用控制器方法。
  4. 处理业务逻辑 → 控制器方法执行并返回 ModelAndView
  5. 解析视图 → 通过 ViewResolver 将逻辑视图名解析为具体视图(如 JSP、JSON)。
  6. 渲染视图 → 将模型数据填充到视图中并返回响应。

什么是Handler Mapping

HandlerMapping 是 SpringMVC 框架中的核心组件之一,负责将 HTTP 请求映射到对应的处理器(Handler),即控制器(Controller)中的方法。

一、核心概念:为什么需要 HandlerMapping?
  1. 请求路由
    当客户端发送请求(如 GET /user/list)时,HandlerMapping 需确定由哪个控制器方法处理该请求。

  2. 解耦 URL 与处理器
    通过配置或注解,将 URL 模式(如 /user/*)与处理器绑定,无需硬编码映射关系。

  3. 支持多种映射策略
    可根据路径、请求方法、请求参数等条件进行复杂匹配。

二、工作原理:请求匹配流程

当 DispatcherServlet 接收到请求时,HandlerMapping 的工作流程如下:

  1. 提取请求信息:从 HTTP 请求中获取 URL、请求方法(GET/POST)、请求参数等。
  2. 匹配处理器:根据配置的映射规则,找到对应的处理器(如 UserController.listUsers() 方法)。
  3. 返回 HandlerExecutionChain:包含处理器对象和拦截器列表。
  4. 执行拦截器:在处理器执行前后,执行注册的拦截器逻辑。
三、常见 HandlerMapping 实现类

SpringMVC 提供多种 HandlerMapping 实现,支持不同的映射方式:

1. RequestMappingHandlerMapping(最常用)

  • 支持注解:处理 @RequestMapping@GetMapping@PostMapping 等注解。
  • 匹配规则
    • 根据 URL 路径(如 /user/{id}
    • 请求方法(GET/POST/PUT/DELETE)
    • 请求参数(如 ?action=edit
    • 请求头(如 Content-Type

2. SimpleUrlHandlerMapping

  • 基于 URL 路径映射:通过配置文件或 Java 代码显式定义 URL 与处理器的映射关系。
  • 适用场景:静态资源映射、遗留系统集成。

3. BeanNameUrlHandlerMapping

  • 按 Bean 名称映射:将 URL 映射到 Bean 名称以 / 开头的 Bean。
  • 示例:若 Bean 名称为 /userController,则映射到 /userController 路径。

什么是Handler Adapter

HandlerAdapter 是 SpringMVC 框架中的核心组件之一,负责 ** 调用具体的处理器(Handler)** 并处理其返回值。由于 SpringMVC 支持多种处理器类型(如注解方法、实现 Controller 接口的类),HandlerAdapter 的作用是将不同类型的处理器统一适配为可执行的标准接口。

一、核心概念:为什么需要 HandlerAdapter?
  1. 统一调用接口
    不同类型的处理器(如 @RequestMapping 注解的方法、实现 Controller 接口的类)具有不同的调用方式。HandlerAdapter 将它们统一为 handle() 方法,使 DispatcherServlet 无需关心具体调用细节。

  2. 解耦处理器类型
    处理器的实现方式(如注解驱动、接口驱动)可以灵活变化,只需提供对应的 HandlerAdapter 实现即可。

  3. 参数解析与返回值处理
    负责解析 HTTP 请求参数到处理器方法参数,并将处理器返回值转换为 ModelAndView 或其他响应格式。

二、工作流程:请求到处理器的适配过程

当 DispatcherServlet 通过 HandlerMapping 找到匹配的处理器后,HandlerAdapter 的工作流程如下:

  1. 检查支持性DispatcherServlet 调用 supports() 方法,确认当前 HandlerAdapter 是否支持该处理器类型。
  2. 调用处理器:调用 handle() 方法,执行处理器逻辑并返回 ModelAndView
  3. 处理返回值:将处理器返回的原始数据(如 StringUser 对象)转换为 ModelAndView 或直接写入响应。

 什么是View Resolver

在 SpringMVC 中,View Resolver(视图解析器) 是负责将控制器返回的逻辑视图名(如 "user/list")解析为实际视图对象(如 JSP、Thymeleaf 模板或 JSON 转换器)的组件。它是连接控制器逻辑和视图渲染的桥梁,使控制器无需关心具体的视图实现细节。

一、核心概念:为什么需要 View Resolver?
  1. 解耦视图实现
    控制器只需返回逻辑视图名(如 "success"),无需指定具体的视图技术(如 JSP、Thymeleaf),实现了业务逻辑视图渲染的分离。

  2. 统一视图处理流程
    DispatcherServlet 通过 View Resolver 统一处理所有视图,简化了请求处理流程。

  3. 支持多种视图技术
    同一应用中可同时使用不同的视图技术(如 JSP、Freemarker、JSON),通过不同的 View Resolver 实现切换。

二、工作流程:逻辑视图名 → 实际视图对象

当控制器返回 ModelAndView 时,View Resolver 的工作流程如下:

  1. 获取逻辑视图名:从 ModelAndView 中提取逻辑视图名(如 "user/list")。
  2. 解析视图对象:View Resolver 根据配置规则,将逻辑视图名转换为实际的视图对象(如 JstlViewThymeleafView)。
  3. 视图渲染:调用视图对象的 render() 方法,将模型数据填充到视图模板中,并输出响应。

什么是ModelAndView

ModelAndView用于封装模型数据和视图信息。它允许控制器方法返回一个对象,该对象包含视图名称和模型数据,从而将数据传递给视图进行渲染。

ModelAndView 主要解决两个问题:

  1. 携带数据:将控制器处理后的业务数据(模型)传递给视图。
  2. 指定视图:告诉框架应该使用哪个视图来渲染数据。

其本质是一个容器,包含两个关键部分:

  • Model:存储视图需要展示的数据(如 Map、对象等)。
  • View:指定视图的逻辑名称或具体实现,用于渲染数据。
使用 ModelAndView 的优点
  1. 清晰分离模型和视图:将模型数据和视图信息封装在一个对象中,使得控制器方法的返回值更加清晰和结构化。
  2. 灵活性:可以在一个地方设置视图和模型数据,便于维护和修改。
  3. 简化代码:通过返回 ModelAndView 对象,可以避免在控制器方法中显式设置模型和视图。

什么是@ModelAttribute注解

@ModelAttribute 注解是 Spring MVC 中用于绑定请求参数到模型对象的注解。它可以用于方法参数、方法和控制器类中,以便将请求中的数据绑定到模型对象,并将该对象添加到模型中,以便在视图中使用。

@ModelAttribute 的使用场景
  1. 方法参数:用于绑定请求参数到方法参数,并将该参数添加到模型中。
  2. 方法:用于在处理请求之前准备模型数据。通常用于在处理请求之前初始化一些公共数据。
  3. 控制器类:用于在所有请求处理方法之前初始化模型数据。

什么是@RequestParam注解

@RequestParam 注解是 Spring MVC 中用于将请求参数绑定到处理方法的参数上的注解。它可以用于从 URL 查询参数、表单数据或其他请求参数中提取值,并将这些值传递给控制器方法的参数。

  • 参数说明
    • value 或 name:请求参数的名称(必填)。
    • required:参数是否必须(默认 true)。
    • defaultValue:参数缺失时的默认值。
@GetMapping("/example")
public String handleRequest(
    @RequestParam("paramName") String paramValue,
    @RequestParam Integer age) {
    
    // 使用 paramValue 和 age 参数
    return "result";
}

 什么是 @PathVariable 注解

@PathVariable 注解是 Spring MVC 中用于将 URL 路径中的变量绑定到处理方法的参数上的注解。它允许你从 URL 路径中提取参数,并将这些参数传递给控制器方法,从而实现更加动态和灵活的 URL 路由。 

 什么是SpringMVC的拦截器

在 Spring MVC 中,拦截器(Interceptor) 是一种特殊的组件,用于在请求处理的关键节点插入自定义逻辑。它类似于 Servlet 规范中的 Filter,但功能更强大、更灵活,是 AOP(面向切面编程)思想的典型应用。

一、拦截器的核心作用
  1. 请求预处理:在控制器方法执行前执行特定逻辑(如身份验证、日志记录)。
  2. 请求后处理:在控制器方法执行后、视图渲染前执行逻辑(如修改响应数据)。
  3. 完成后处理:在整个请求处理完成后执行清理工作(如释放资源)。

拦截器允许开发者在不修改控制器代码的前提下,对请求进行全局或局部的增强处理。

二、拦截器的工作流程

当客户端发送请求时,拦截器的执行流程如下:

  1. 请求进入 DispatcherServlet
  2. 预处理(preHandle):按顺序执行拦截器链的 preHandle 方法。若任一拦截器返回 false,则终止请求处理,直接返回响应。
  3. 执行控制器方法:所有拦截器的 preHandle 均返回 true 时执行。
  4. 后处理(postHandle):按拦截器逆序执行 postHandle,可修改 ModelAndView
  5. 完成后处理(afterCompletion):无论请求是否成功,均按逆序执行,用于资源清理。
 三、拦截器的实现方式

Spring MVC 的拦截器通过实现 HandlerInterceptor 接口来定义。这个接口包含三个主要方法:

  1. preHandle:在请求处理之前执行。返回 true 表示继续处理请求,返回 false 表示中止请求。
  2. postHandle:在请求处理之后、视图渲染之前执行。可以修改视图模型数据。
  3. afterCompletion:在整个请求完成之后(包括视图渲染之后)执行。通常用于资源清理。

什么是SpringMVC的异常处理机制

在 Spring MVC 中,异常处理机制用于统一捕获和处理控制器层抛出的异常,避免直接将异常堆栈暴露给客户端,同时提供友好的错误响应。

使用 @ControllerAdvice + @ExceptionHandler

从 Spring 3.2 开始,Spring MVC 引入了 @ControllerAdvice@ExceptionHandler 注解,提供了一种基于注解的异常处理机制。这种方式允许开发者将异常处理逻辑与具体的 Controller 分离,从而实现更加模块化和可重用的异常处理代码。

实现方式:首先,使用 @ControllerAdvice 注解标记一个类,该类将作为全局的异常处理类。然后,在该类中使用 @ExceptionHandler 注解标记方法,并指定该方法用于处理哪种类型的异常。当指定的异常发生时,Spring MVC 将自动调用该方法进行处理

什么是 Spring MVC 的 REST 支持

Spring MVC 的 REST 支持是指其对 RESTful API 的强大集成能力,允许开发者轻松构建符合 REST 架构风格的 Web 服务。通过简洁的注解和丰富的工具,Spring MVC 使控制器能够直接返回 JSON、XML 等数据格式,而非传统的视图页面,从而满足现代前后端分离架构的需求。

一、核心特性与优势
  1. 注解驱动开发
    通过 @RestController@RequestMapping 等注解快速定义 REST 接口,无需额外配置。

  2. 自动数据转换
    借助 HttpMessageConverter,自动将 Java 对象转换为 JSON/XML 响应,或将请求中的 JSON/XML 反序列化为 Java 对象。

  3. 统一异常处理
    通过 @ExceptionHandler 和 @ControllerAdvice 统一处理 REST API 的异常,返回标准化错误格式。

  4. 灵活的请求映射
    支持 @GetMapping@PostMapping 等简化注解,精确匹配 HTTP 方法。

  5. 内容协商
    根据客户端请求的 Accept 头或 URL 后缀(如 .json),动态返回不同格式的数据。

如何在 Spring MVC 中处理 JSON 数据

接收 JSON 数据
  • 使用 @RequestBody 注解:在控制器方法的参数上使用 @RequestBody 注解可以将 HTTP 请求体中的 JSON 数据自动解析为对应的 Java 对象。
  • 手动解析 JSON:如果你需要更多的控制权,可以使用 Jackson 或 Gson 等库手动解析 JSON 数据。
返回 JSON 数据
  • 使用 @ResponseBody 注解:在控制器方法上使用 @ResponseBody 注解可以将方法返回的对象自动序列化为 JSON 数据并写入到 HTTP 响应体中。
  • 手动序列化 JSON:如果你需要更多的控制权,可以使用 Jackson 或 Gson 等库手动将 Java 对象序列化为 JSON 数据。

什么是@RestController注解

@RestController 是 用于标记一个类作为 RESTful 控制器。这个注解实际上是 @Controller@ResponseBody 注解的组合。

@ResponseBody将方法返回的对象自动序列化为JSON数据并写入到HTTP响应体中。@Controller则用于标记一个类作为控制器负责处理HTTP请求并将结果返回给客户端

如何在 Spring MVC 中实现跨域资源共享(CORS)

一、全局配置(推荐)

通过实现 WebMvcConfigurer 接口,添加全局 CORS 配置:

@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/api/**")  // 匹配所有以 /api/ 开头的请求
            .allowedOrigins("http://example.com")  // 允许的域名
            .allowedMethods("GET", "POST", "PUT", "DELETE")  // 允许的 HTTP 方法
            .allowedHeaders("*")  // 允许的请求头
            .allowCredentials(true)  // 允许携带凭证(如 Cookie)
            .maxAge(3600);  // 预检请求的缓存时间(秒)
    }
}
二、控制器级别配置

使用 @CrossOrigin 注解在控制器类上:

@RestController
@RequestMapping("/api/users")
@CrossOrigin(origins = "http://example.com", maxAge = 3600)
public class UserController {
    // 所有方法都允许来自 http://example.com 的跨域请求
}
三、方法级别配置

在特定方法上使用 @CrossOrigin 注解:

@RestController
@RequestMapping("/api")
public class UserController {
    @GetMapping("/users/{id}")
    @CrossOrigin(origins = "http://example.com")
    public User getUser(@PathVariable Long id) {
        // 仅该方法允许跨域
    }
}

如何在 Spring MVC 中使@ExceptionHandler 注解

在 Spring MVC 中,@ExceptionHandler 注解用于处理控制器层抛出的异常,使你可以在同一个控制器或全局范围内定义统一的异常处理逻辑。

一、基本用法:在控制器内处理特定异常

在控制器类中定义异常处理方法,捕获并处理该控制器抛出的特定异常:

@RestController
@RequestMapping("/api/users")
public class UserController {
    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        User user = userService.findById(id);
        if (user == null) {
            throw new UserNotFoundException("用户不存在,ID: " + id);
        }
        return user;
    }

    // 处理 UserNotFoundException 异常
    @ExceptionHandler(UserNotFoundException.class)
    public ResponseEntity<ErrorResponse> handleUserNotFound(UserNotFoundException ex) {
        ErrorResponse error = new ErrorResponse(
            HttpStatus.NOT_FOUND.value(),
            ex.getMessage()
        );
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
    }
}

关键点

  • 异常类型匹配@ExceptionHandler 后的括号内指定要捕获的异常类。
  • 返回值:可以是 ResponseEntityModelAndView 或其他对象(自动转换为 JSON/XML)。
  • 参数:可接收异常对象(如 UserNotFoundException ex)和请求 / 响应对象。
二、全局异常处理:使用 @ControllerAdvice

创建全局异常处理器,处理所有控制器抛出的异常:

@ControllerAdvice
public class GlobalExceptionHandler {
    // 处理所有 RuntimeException 及其子类
    @ExceptionHandler(RuntimeException.class)
    public ResponseEntity<ErrorResponse> handleRuntimeException(RuntimeException ex) {
        ErrorResponse error = new ErrorResponse(
            HttpStatus.INTERNAL_SERVER_ERROR.value(),
            "系统内部错误: " + ex.getMessage()
        );
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(error);
    }

    // 处理参数校验异常
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ErrorResponse> handleValidationException(MethodArgumentNotValidException ex) {
        Map<String, String> errors = ex.getBindingResult().getFieldErrors()
            .stream()
            .collect(Collectors.toMap(
                FieldError::getField, 
                FieldError::getDefaultMessage
            ));
        
        ErrorResponse error = new ErrorResponse(
            HttpStatus.BAD_REQUEST.value(),
            "参数校验失败",
            errors
        );
        
        return ResponseEntity.badRequest().body(error);
    }
}

关键点

  • @ControllerAdvice:标记该类为全局异常处理器,可通过 basePackages 指定扫描范围。
  • 异常优先级:多个 @ExceptionHandler 存在时,优先匹配最具体的异常类(如子类优先于父类)。

网站公告

今日签到

点亮在社区的每一天
去签到