在Java后端开发的面试中,SpringMVC 作为一个成熟且广泛使用的Web框架,其相关面试题几乎是必考内容。无论是初级工程师还是资深架构师,都需要深入理解 MVC 模式的核心理念以及 SpringMVC 的具体实现机制。本文将全面梳理 SpringMVC 面试题,从工作原理、核心组件、数据绑定、异常处理到高级特性,为您提供一份详尽的备考指南。
理解 SpringMVC 的工作原理是回答面试题的基础。面试官通常会询问:“请描述一下 SpringMVC 的请求处理流程?”
用户发送请求到前端控制器 DispatcherServlet。
DispatcherServlet 调用 HandlerMapping 查找处理器(Controller)。
DispatcherServlet 通过 HandlerAdapter 执行具体的 Controller 方法。
Controller 返回逻辑视图名,ViewResolver 解析为实际视图。
// 伪代码示例:SpringMVC 核心流程
1. Client sends request -> DispatcherServlet
2. DispatcherServlet -> HandlerMapping (finds Controller)
3. DispatcherServlet -> HandlerAdapter (invokes Controller)
4. Controller -> Service -> Model & View Name
5. DispatcherServlet -> ViewResolver (resolves View)
6. ViewResolver -> View (renders response)
7. View -> Client
在上述流程中,DispatcherServlet 是前端控制器,负责接收所有请求并协调其他组件。HandlerMapping 负责将请求映射到相应的处理器,HandlerAdapter 负责调用处理器,ViewResolver 负责解析视图。理解这些组件的协作关系,是掌握 SpringMVC 的关键。
DispatcherServlet 是 SpringMVC 的核心,它实现了前端控制器模式。所有请求首先到达 DispatcherServlet,由其统一分发。面试官可能会问:“DispatcherServlet 是如何初始化的?”
在 Spring Boot 应用中,DispatcherServlet 由 DispatcherServletAutoConfiguration 自动配置。在传统的 Spring 应用中,需要在 web.xml 中配置 DispatcherServlet 及其初始化参数。
HandlerMapping 负责将请求映射到处理器。常见的实现包括:
@RequestMapping 注解的映射。HandlerAdapter 负责调用处理器。由于处理器可能是不同的类型(如实现 Controller 接口、使用 @Controller 注解等),HandlerAdapter 提供了统一的调用接口。
ViewResolver 负责将逻辑视图名解析为实际的视图对象。常见的实现包括:
数据绑定是 SpringMVC 的重要功能,它负责将 HTTP 请求参数绑定到方法参数或命令对象上。面试官常问:“SpringMVC 是如何进行数据绑定的?”
对于基本数据类型(如 int, String 等),SpringMVC 直接使用 WebDataBinder 进行绑定。如果参数名与请求参数名一致,则直接绑定;否则需要使用 @RequestParam 注解指定参数名。
@GetMapping("/user")
public String getUser(@RequestParam("name") String username) {
// username 绑定自请求参数 "name"
return "user";
}
对于 POJO 对象,SpringMVC 会递归绑定对象的属性。如果请求参数名与对象属性名一致,则直接绑定。
@PostMapping("/user")
public String createUser(User user) {
// user 对象自动绑定请求参数
return "success";
}
对于复杂类型(如 List, Map),需要使用特定的语法。例如,绑定 List 需要使用索引:items[0].name。
@PostMapping("/list")
public String createList(@RequestParam List<String> items) {
// 绑定 items[0], items[1] 等
return "success";
}
如果默认的数据绑定机制无法满足需求,可以实现 Converter 接口来自定义转换器。
public class StringToDateConverter implements Converter<String, Date> {
@Override
public Date convert(String source) {
// 实现转换逻辑
return new SimpleDateFormat("yyyy-MM-dd").parse(source);
}
}
SpringMVC 提供了灵活的异常处理机制。面试官可能会问:“SpringMVC 中如何处理全局异常?”
在 Controller 中使用 @ExceptionHandler 注解可以处理特定 Controller 中的异常。
这是处理全局异常的最佳实践。通过 @ControllerAdvice 注解的类可以捕获所有 Controller 中的异常。
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ModelAndView handleException(Exception e) {
ModelAndView mv = new ModelAndView();
mv.addObject("error", e.getMessage());
mv.setViewName("error");
return mv;
}
}
这是一种基于配置的异常处理方式,将异常类型映射到视图名称。
Interceptor 用于在请求处理前后执行特定逻辑,如权限检查、日志记录等。实现 HandlerInterceptor 接口并重写 preHandle, postHandle, afterCompletion 方法。
使用 MultipartFile 接口处理文件上传。需要在配置中注册 MultipartResolver。
SpringMVC 提供了对 RESTful 风格的全面支持,使用 @RestController 和 @RequestMapping 等注解可以轻松构建 RESTful API。
| 特性 | Filter (过滤器) | Interceptor (拦截器) |
|---|---|---|
| 所属框架 | Servlet 规范 | SpringMVC |
| 触发时机 | 请求进入 Servlet 之前 | 请求进入 Controller 之前/之后 |
| 访问范围 | 只能访问 Servlet API | 可以访问 Spring 容器中的 Bean |
| 典型应用 | 字符编码、安全过滤 | 权限检查、日志记录 |
核心组件包括 DispatcherServlet, HandlerMapping, HandlerAdapter, ViewResolver 等。它们的协作流程如下:DispatcherServlet 接收请求,调用 HandlerMapping 找到处理器,通过 HandlerAdapter 执行处理器,处理器返回模型和视图,ViewResolver 解析视图,最后 DispatcherServlet 渲染视图并返回响应。
可以通过实现 HandlerExceptionResolver 接口或使用 @ControllerAdvice 注解结合 @ExceptionHandler 注解来定义全局异常处理器。
通过 @RequestMapping 注解的 method 属性指定 HTTP 方法(GET, POST, PUT, DELETE 等),并使用 @PathVariable 获取 URL 中的路径变量,@RequestBody 和 @ResponseBody 处理 JSON 数据。
需要在配置中注册 MultipartResolver,在 Controller 方法中使用 MultipartFile 参数接收上传的文件,并调用其 transferTo() 方法保存文件。
过滤器是 Servlet 规范的一部分,可以在请求进入 Servlet 之前进行过滤;拦截器是 SpringMVC 的一部分,可以在请求进入 Controller 之前和之后执行逻辑。拦截器可以访问 Spring 容器中的 Bean,而过滤器不能。