SpringMVC好好学三(中央处理器、异常处理器和拦截器)

SpringMVC好好学三(中央处理器、异常处理器和拦截器)

大纲

  • 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 拦截器的执行流程

拦截器的执行流程如下图所示:

拦截器处理流程的步骤如下:

  1. 当请求的路径与拦截器拦截的路径相匹配时,程序会先执行拦截器类(MyInterceptor)的 preHandl() 方法。若该方法返回值为 true,则继续向下执行 Controller(控制器)中的方法,否则将不再向下执行;
  2. 控制器方法对请求进行处理;
  3. 调用拦截器的 postHandl() 方法,此时我们可以对请求域中的模型(Model)数据和视图做出进一步的修改;
  4. 通过 DispatcherServlet 的 render() 方法对视图进行渲染;
  5. 调用拦截器的 afterCompletion () 方法,完成资源清理、日志记录等工作。
end
  • 作者:旭仔(联系作者)
  • 发表时间:2024-03-17 10:43
  • 版权声明:自由转载-非商用-非衍生-保持署名
  • 转载声明:如果是转载栈主转载的文章,请附上原文链接
  • 公众号转载:请在文末添加作者公众号二维码(公众号二维码见右边,欢迎关注)
  • 评论