1、说一下你对Spring MVC的理解?
MVC 是模型(Model)、视图(View)、控制器(Controller)的简写,其核心思想是通过将业务逻辑、数据、显示分离来组织代码。SpringMVC 是轻量级Web框架,属于Spring框架的一个模块。
它通过一套注解,让一个简单的Java类成为处理请求的控制器,而无须实现任何接口。同时它还支持RESTful编程风格的请求。
2、SpringMVC有哪些优点?
- 与 Spring 集成使用非常方便,生态好。
- 配置简单,快速上手。
- 支持 RESTful 风格。
- 支持各种视图技术,支持各种请求资源映射策略。
3、Spring MVC的核心组件有哪些?
记住了下面这些组件,也就记住了 SpringMVC 的工作原理。
- 前端控制器(DispatcherServlet):接收用户请求,给用户返回结果。
- 处理器映射器(HandlerMapping):根据请求的url路径,通过注解或者xml配置,寻找匹配的Handler。
- 处理器适配器(HandlerAdapter):Handler 的适配器,调用 handler 的方法处理请求。
- 处理器(Handler):执行相关的请求处理逻辑,并返回相应的数据和视图信息,将其封装到ModelAndView对象中。
- 视图解析器(ViewResolver):将逻辑视图名解析成真正的视图View。
- 视图(View):接口类,实现类可支持不同的View类型(JSP、FreeMarker、Excel等)。
4、Spring MVC工作原理(执行流程)了解吗?
目前的执行流程分为两种情况,因为开发模式变了。
- 视图阶段(老旧JSP等)
- 前后端分离阶段(接口开发,异步)
视图阶段(老旧JSP等):
流程说明(重要):
- 客户端(浏览器)发送请求,
DispatcherServlet拦截请求。 DispatcherServlet根据请求信息调用HandlerMapping。HandlerMapping根据 uri 去匹配查找能处理的Handler(也就是我们平常说的Controller控制器) ,并会将请求涉及到的拦截器和Handler一起封装。DispatcherServlet调用HandlerAdapter适配执行Handler。Handler完成对用户请求的处理后,会返回一个ModelAndView对象给DispatcherServlet,ModelAndView顾名思义,包含了数据模型以及相应的视图的信息。Model是返回的数据对象,View是个逻辑上的View。ViewResolver会根据逻辑View查找实际的View。DispaterServlet把返回的Model传给View(视图渲染)。- 把
View返回给请求者(浏览器)
快速记忆技巧:
核心控制器捕获请求、查找Handler、执行Handler、选择ViewResolver,通过ViewResolver渲染视图并返回;
参考链接:框架篇-07-Springmvc-执行流程_哔哩哔哩_bilibili
5、统一异常怎么处理?
推荐使用注解的方式统一异常处理,具体会使用到 @ControllerAdvice + @ExceptionHandler 这两个注解 。
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {
@ExceptionHandler(BaseException.class)
public ResponseEntity<?> handleAppException(BaseException ex, HttpServletRequest request) {
//......
}
@ExceptionHandler(value = ResourceNotFoundException.class)
public ResponseEntity<ErrorReponse> handleResourceNotFoundException(ResourceNotFoundException ex, HttpServletRequest request) {
//......
}
}
这种异常处理方式下,会给所有或者指定的 Controller 织入异常处理的逻辑(AOP),当 Controller 中的方法抛出异常的时候,由被@ExceptionHandler 注解修饰的方法进行处理。
ExceptionHandlerMethodResolver 中 getMappedMethod 方法决定了异常具体被哪个被 @ExceptionHandler 注解修饰的方法处理异常。
@Nullable
private Method getMappedMethod(Class<? extends Throwable> exceptionType) {
List<Class<? extends Throwable>> matches = new ArrayList<>();
//找到可以处理的所有异常信息。mappedMethods 中存放了异常和处理异常的方法的对应关系
for (Class<? extends Throwable> mappedException : this.mappedMethods.keySet()) {
if (mappedException.isAssignableFrom(exceptionType)) {
matches.add(mappedException);
}
}
// 不为空说明有方法处理异常
if (!matches.isEmpty()) {
// 按照匹配程度从小到大排序
matches.sort(new ExceptionDepthComparator(exceptionType));
// 返回处理异常的方法
return this.mappedMethods.get(matches.get(0));
}
else {
return null;
}
}
从源代码看出:getMappedMethod()会首先找到可以匹配处理异常的所有方法信息,然后对其进行从小到大的排序,最后取最小的那一个匹配的方法(即匹配度最高的那个)。
6、SpringMVC常用注解有哪些?
- @Controller:用于标识此类的实例是一个控制器。
- @RequestMapping:映射Web请求(访问路径和参数)。
- @ResponseBody:注解返回数据而不是返回页面
- @RequestBody:注解实现接收http请求的json 数据,将json数据转换为java对象。
- @PathVariable:获得URL中路径变量中的值
- @RestController: @Controller+@ResponseBody
- @ExceptionHandler标识一个方法为全局异常处理的方法。
7、介绍下SpringMVC拦截器
Spring MVC 拦截器对应HandlerInterceor接口,该接口位于org.springframework.web.servlet的包中,定义了三个方法,若要实现该接口,就要实现其三个方法:
- 前置处理(preHandle()方法):该方法在执行控制器方法之前执行。返回值为Boolean类型,如果返回false,表示拦截请求,不再向下执行,如果返回true,表示放行,程序继续向下执行(如果后面没有其他Interceptor,就会执行controller方法)。所以此方法可对请求进行判断,决定程序是否继续执行,或者进行一些初始化操作及对请求进行预处理。
- 后置处理(postHandle()方法):该方法在执行控制器方法调用之后,且在返回ModelAndView之前执行。由于该方法会在DispatcherServlet进行返回视图渲染之前被调用,所以此方法多被用于处理返回的视图,可通过此方法对请求域中的模型和视图做进一步的修改。
- 已完成处理(afterCompletion()方法):该方法在执行完控制器之后执行,由于是在Controller方法执行完毕后执行该方法,所以该方法适合进行一些资源清理,记录日志信息等处理操作。
可以通过拦截器进行权限检验,参数校验,记录日志等操作
8、SpringMVC怎么配置拦截器?
有两种写法,一种是定义的Interceptor类要实现HandlerInterceptor接口;
另外一种是继承适配器类,接着在接口方法当中,实现处理逻辑;然后在SpringMvc的配置文件中配置拦截器即可:
<!-- 配置SpringMvc的拦截器 -->
<mvc:interceptors>
<bean id="myInterceptor" class="com.dabin.MyHandlerInterceptor"></bean>
<!-- 只拦截部分请求 -->
<mvc:interceptor>
<mvc:mapping path="/xxx.do" />
<bean class="com.dabin.MyHandlerInterceptorAdapter" />
</mvc:interceptor>
</mvc:interceptors>
9、SpringMVC的拦截器和Filter过滤器有什么差别?
| Interceptor | Filter | |
|---|---|---|
| 作用范围 | 是Spring MVC框架中的一部分,主要用于拦截请求,在请求到达Controller之前进行操作,但是不能拦截从Controller返回的视图 | 是Servlet规范中的一部分,主要用于拦截请求和响应,并且可以在请求到达Controller之前或从Controller返回视图之前对请求和响应进行修改和操作 |
| 实现方式 | 使用Spring MVC框架提供的Interceptor接口实现的,具体的逻辑需要自己编写,但是可以使用Spring的一些特性,例如:AOP(面向切面编程) | 使用Java Servlet API中提供的Filter接口实现的,具体的逻辑需要自己编写 |
| 功能 | 用于处理更加特定的任务,例如:权限控制、日志记录、性能监控、事务控制等,并且可以通过AOP实现更高级别的操作,例如:异常处理、安全控制等 | 用于处理全局的、通用的任务,例如:字符编码、安全控制、日志记录等 |