大纲
-
1、SpringMVC的执行流程
-
2、SpringMVC异常处理器
-
3、SpringMVC拦截器
1、SpringMVC的执行流程
SpringMVC 的执行流程如下:
1、用户通过浏览器发起一个 HTTP 请求,该请求会被 DispatcherServlet(前端控制器)拦截;
2、DispatcherServlet 调用 HandlerMapping(处理器映射器)找到具体的
处理器(Handler)及拦截器,最后以 HandlerExecutionChain 执行链的形式
返回给 DispatcherServlet。
3、DispatcherServlet 将执行链返回的 Handler 信息发送给 HandlerAdapter(处理器适配器);
4、HandlerAdapter 根据 Handler 信息找到并执行相应的 Handler(即 Controller 控制器)对请求进行处理;
5、Handler 执行完毕后会返回给 HandlerAdapter 一个 ModelAndView 对象(Spring MVC 的底层对象,
包括 Model 数据模型和 View 视图信息);
6、HandlerAdapter 接收到 ModelAndView 对象后,将其返回给 DispatcherServlet ;
7、DispatcherServlet 接收到 ModelAndView 对象后,会请求
ViewResolver(视图解析器)对视图进行解析;
8、ViewResolver 解析完成后,会将 View 视图并返回给 DispatcherServlet;
9、DispatcherServlet 接收到具体的 View 视图后,进行视图渲染,
将 Model 中的模型数据填充到 View 视图中的 request 域,生成最终的 View(视图);
10、视图负责将结果显示到浏览器(客户端)。
- 常用组件
Spring MVC 的常用组件共有 6 个,它们分别是: DispatcherServlet(前端控制器)、HandlerMapping(处理器映射器)、HandlerAdapter(处理器适配器)、Handler(处理器)、ViewResolver(视图解析器)和 View(视图)。
下表对各个组件的功能说明如下。
组件 | 提供者 | 说明 |
---|---|---|
DispatcherServlet(前端控制器) | 由框架提供 | 它是 Spring MVC 的核心,其本质就是一个 Servlet。 它负责将所有的请求进行统一分发,相当于一个 Spring MVC 的流程控制中心,控制整个流程的执行,对各个组件进行统一调度,以降低组件之间的耦合性,有利于组件之间的拓展。 |
HandlerMapping(处理器映射器) | 由框架提供 | 负责根据请求的 url、method 等信息查找响应的 Handler 处理器(即 Controller 控制器方法)。 |
Handler(处理器) | 由开发人员提供 | 也就是我们常说的 Controller 控制器,负责在 DispatcherServlet 的控制下,对具体的用户请求进行处理。 |
HandlerAdapter(处理器适配器) | 由框架提供 | 它负责根据 HandlerMapping 映射器找到的处理器(Handler)信息,按照特定规则执行相关的处理器(Handler)方法。 |
ViewResolver(视图解析器) | 由框架提供 | 通过 ModelAndView 对象中的 View 信息对逻辑视图名进行解析,将其解析成真正的视图 View(例如 ThymeleafView、InternalResourceView、RedirectView 等),并返回给 DispatcherServlet。 |
View(视图) | View 对象本身由框架提供,但视图所对应的前端页面(例如 JSP、HTML)则需要开发人员自行编写 | 将 Model 模型数据通过页面展示给用户。 |
以上组件中,需要开发人员进行开发的是处理器(Handler,即 Controller)和视图(View)。通俗的说,要开发处理该请求的具体代码逻辑,以及最终展示给用户的界面。
2、SpringMVC异常处理器
2.1 基于XML配置的异常处理
SpringMVC提供了一个处理控制器方法执行过程中所出现的异常的接口:HandlerExceptionResolver。
- 代码示例
public class GlobalExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler,
Exception exception) {
// 判断异常的种类
String msg = null;
if (exception instanceof CustomerException) {
// 如果是自定义异常,就从异常里面取出错误消息
CustomerException custExp = (CustomerException) exception;
msg = custExp.getExpMessage();
} else {
// 如果是运行时异常,则取错误的堆栈信息
exception.printStackTrace(); // 向控制台上打印堆栈信息
StringWriter s = new StringWriter();
PrintWriter printWriter = new PrintWriter(s);
exception.printStackTrace(printWriter);
msg = s.toString();
}
// 写日志、发短信、发邮件
// 在此省略这一步......
// 返回一个友好的错误页面,并显示错误消息
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("msg", msg);
modelAndView.setViewName("error");
return modelAndView;
}
}
- 配置
在springmvc.xml文件中配置这个自定义的异常处理器:
<!-- 配置全局异常处理器,且全局异常处理器只能有一个 -->
<bean class="com.itheima.springmvc.exception.GlobalExceptionResolver"></bean>
2.2 基于注解的异常处理器
3、SpringMVC拦截器
拦截器(Interceptor)是 Spring MVC 提供的一种强大的功能组件。它可以对用户请求进行拦截,并在请求进入控制器(Controller)之前、控制器处理完请求后、甚至是渲染视图后,执行一些指定的操作。
在 Spring MVC 中,拦截器的作用与 Servlet 中的过滤器类似,它主要用于拦截用户请求并做相应的处理,例如通过拦截器,我们可以执行权限验证、记录请求信息日志、判断用户是否已登录等操作。
Spring MVC 拦截器使用的是可插拔式的设计,如果我们需要某一拦截器,只需在配置文件中启用该拦截器即可;如果不需要这个拦截器,则只要在配置文件中取消应用该拦截器即可。
3.1 定义拦截器
想要在 Spring MVC 项目中使用拦截器,第一步就是要对拦截器类进行定义。
Spring MVC 在 org.springframework.web.servlet 包中提供了一个 HandlerInterceptor 接口,该接口包含 3 个方法,如下表:
方法名 | 返回值 | 说明 |
---|---|---|
preHandle () | boolean | 该方法在控制器方法之前执行,其返回值用来表示是否中断后续操作。 - 返回值为 true 时,表示继续向下执行; - 返回值为 false 时,表示中断后续的操作。 |
postHandle () | void | 该方法会在控制器方法调用之后,解析式图之前执行。我们可以通过此方法对请求域中的模型(Model)数据和视图做出进一步的修改。 |
afterCompletion () | void | 该方法会在整个请求完成后,即视图渲染结束之后执行。我们可以通过该方法实现资源清理、日志记录等工作。 |
- 代码示例
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle 执行");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle 执行");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion 执行");
}
}
3.2 配置拦截器
在定义完拦截器后,我们还需要在 Spring MVC 的配置文件中使用 mvc:interceptors 标签及其子标签对拦截器进行配置,这样这个拦截器才会生效。
在 Spring MVC 的配置文件中,mvc:interceptors 标签用于定义一组拦截器,
<!--配置拦截器-->
<mvc:interceptors>
<!--拦截器 1-->
<mvc:interceptor>
<!--配置拦截器拦截的请求路径-->
<mvc:mapping path="/**"/>
<!--配置拦截器不需要拦截的请求路径-->
<mvc:exclude-mapping path="/login"/>
<mvc:exclude-mapping path="/"/>
<!--定义在 <mvc:interceptors> 下,表示拦截器只对指定路径的请求进行拦截-->
<bean id="interceptor" class="net.biancheng.c.interceptor.MyInterceptor"></bean>
</mvc:interceptor>
</mvc:interceptors>
3.3 拦截器的执行流程
拦截器的执行流程如下图所示:
拦截器处理流程的步骤如下:
- 当请求的路径与拦截器拦截的路径相匹配时,程序会先执行拦截器类(MyInterceptor)的 preHandl() 方法。若该方法返回值为 true,则继续向下执行 Controller(控制器)中的方法,否则将不再向下执行;
- 控制器方法对请求进行处理;
- 调用拦截器的 postHandl() 方法,此时我们可以对请求域中的模型(Model)数据和视图做出进一步的修改;
- 通过 DispatcherServlet 的 render() 方法对视图进行渲染;
- 调用拦截器的 afterCompletion () 方法,完成资源清理、日志记录等工作。
评论