Spring MVC

208 阅读6分钟

1、说一下你对Spring MVC的理解?

MVC 是模型(Model)、视图(View)、控制器(Controller)的简写,其核心思想是通过将业务逻辑、数据、显示分离来组织代码。SpringMVC 是轻量级Web框架,属于Spring框架的一个模块。

它通过一套注解,让一个简单的Java类成为处理请求的控制器,而无须实现任何接口。同时它还支持RESTful编程风格的请求。

image.png

2、SpringMVC有哪些优点?

  1. 与 Spring 集成使用非常方便,生态好。
  2. 配置简单,快速上手。
  3. 支持 RESTful 风格。
  4. 支持各种视图技术,支持各种请求资源映射策略。

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等): image.png

流程说明(重要):

  1. 客户端(浏览器)发送请求, DispatcherServlet拦截请求。
  2. DispatcherServlet 根据请求信息调用 HandlerMappingHandlerMapping 根据 uri 去匹配查找能处理的 Handler(也就是我们平常说的 Controller 控制器) ,并会将请求涉及到的拦截器和 Handler 一起封装。
  3. DispatcherServlet 调用 HandlerAdapter适配执行 Handler
  4. Handler 完成对用户请求的处理后,会返回一个 ModelAndView 对象给DispatcherServletModelAndView 顾名思义,包含了数据模型以及相应的视图的信息。Model 是返回的数据对象,View 是个逻辑上的 View
  5. ViewResolver 会根据逻辑 View 查找实际的 View
  6. DispaterServlet 把返回的 Model 传给 View(视图渲染)。
  7. 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 注解修饰的方法进行处理。

ExceptionHandlerMethodResolvergetMappedMethod 方法决定了异常具体被哪个被 @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的包中,定义了三个方法,若要实现该接口,就要实现其三个方法:

  1. 前置处理(preHandle()方法):该方法在执行控制器方法之前执行。返回值为Boolean类型,如果返回false,表示拦截请求,不再向下执行,如果返回true,表示放行,程序继续向下执行(如果后面没有其他Interceptor,就会执行controller方法)。所以此方法可对请求进行判断,决定程序是否继续执行,或者进行一些初始化操作及对请求进行预处理。
  2. 后置处理(postHandle()方法):该方法在执行控制器方法调用之后,且在返回ModelAndView之前执行。由于该方法会在DispatcherServlet进行返回视图渲染之前被调用,所以此方法多被用于处理返回的视图,可通过此方法对请求域中的模型和视图做进一步的修改。
  3. 已完成处理(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过滤器有什么差别?

InterceptorFilter
作用范围是Spring MVC框架中的一部分,主要用于拦截请求,在请求到达Controller之前进行操作,但是不能拦截从Controller返回的视图是Servlet规范中的一部分,主要用于拦截请求和响应,并且可以在请求到达Controller之前或从Controller返回视图之前对请求和响应进行修改和操作
实现方式使用Spring MVC框架提供的Interceptor接口实现的,具体的逻辑需要自己编写,但是可以使用Spring的一些特性,例如:AOP(面向切面编程)使用Java Servlet API中提供的Filter接口实现的,具体的逻辑需要自己编写
功能用于处理更加特定的任务,例如:权限控制、日志记录、性能监控、事务控制等,并且可以通过AOP实现更高级别的操作,例如:异常处理、安全控制等用于处理全局的、通用的任务,例如:字符编码、安全控制、日志记录等