Spring Web MVC de Spring Family Bucket (7) - Interceptor

¡Acostúmbrate a escribir juntos! Este es el día 11 de mi participación en el "Nuevo plan diario de Nuggets · Desafío de actualización de abril", haga clic para ver los detalles del evento .

1. interceptor

Spring MVC proporciona un mecanismo interceptor que permite cierto trabajo de interceptación antes de ejecutar el método de destino, o algún otro procesamiento después de que se ejecuta el método de destino.

El interceptor en Spring MVC es la interfaz HandlerInterceptor, que contiene tres métodos

imagen.png

  • preHandler: este método se llama antes de que el procesador de negocios procese la solicitud. En este método, se procesa la solicitud del usuario. Si se requiere que el interceptor intercepte la solicitud, se llamará a otros interceptores o se procesará el procesador de negocios. Luego regrese True para liberar la solicitud y devolver falso si no es necesario llamar a otros componentes ni liberar la solicitud
  • postHandler: este método se llama después de que el procesador comercial haya terminado de procesar la solicitud, pero se llama antes de que DispatcherServlet devuelva una respuesta al cliente.En este método, se procesa la solicitud de solicitud del usuario
  • afterCompletion: este método se llama después de que DispatcherServlet haya procesado completamente la solicitud, y algunas operaciones de limpieza de recursos se pueden realizar en este método

En segundo lugar, el interceptor personalizado

Copie el proyecto spring-mvc-ajax, cámbiele el nombre a spring-mvc-handler y elimine las clases y los archivos excepto la configuración.

El flujo normal del interceptor

Cree un nuevo HandlerInterceptorSamplerController, defina el método de interceptor en el controlador, pruebe el interceptor personalizado y regrese a la página de éxito

@Controller
public class HandlerInterceptorSamplerController {

    @RequestMapping("/interceptor")
    public String interceptor(){

        System.out.println("interceptor方法被调用");
        return "success";
    }
}
复制代码

Agregar un hipervínculo a la página index.jsp

<a href="/interceptor">拦截该请求</a>
复制代码

Agregue el paquete del interceptor, cree un nuevo interceptor personalizado ZuluInterceptor, el interceptor personalizado debe implementar la interfaz HandlerInterceptor y agregar la impresión de registros a cada método en el interceptor

public class ZuluInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        System.out.println(this.getClass().getName() + " preHandler方法运行了");
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println(this.getClass().getName() + " postHandle方法运行了");
        System.out.println(modelAndView.getViewName());
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println(this.getClass().getName() + " afterCompletion方法运行了");
    }
}
复制代码

Registre el interceptor en el archivo de configuración de Spring MVC y configure qué solicitudes intercepta el interceptor

<mvc:interceptors>
    <!--第一种方式配置某个拦截器,默认是拦截所有请求的-->
    <bean class="com.citi.interceptor.ZuluInterceptor"></bean>
</mvc:interceptors>
复制代码

Inicie la aplicación y haga clic en el hipervínculo en la página de inicio

imagen.pngDe acuerdo con la salida de la consola, el interceptor personalizado se llama con éxito

因此拦截器的正常流程是:拦截器preHandler方法 -> 目标方法 -> 拦截器的postHandler方法 -> 页面渲染 -> 拦截器的afterCompletion方法

拦截器的异常流程

异常流程1 - preHandler返回false

在ZuluInterceptor拦截器的preHandler方法返回false,再次启动,点击首页的超链接 imagen.png 控制台只输出了preHandler方法的执行信息,因此只要preHandler返回false,既不放行就不会有以后的方法的执行。

异常流程2 - 其他异常

保持preHandler方法返回true,同时在Controller中的interceptor方法返回页面前增加异常代码

@RequestMapping("/interceptor")
public String interceptor(){

    System.out.println("interceptor方法被调用");
    // 异常代码
    int i = 10 / 0;
    return "success";
}
复制代码

再次重新启动应用,点击页面的超链接 imagen.png 页面出现有异常代码导致的报错

imagen.png 此时控制台执行了afterCompletion方法

三、多个拦截器执行顺序

在interceptor包中拷贝ZuluInterceptor并重命名为DeltaInterceptor;在Spring MVC配置文件中注册新定义的拦截器

<mvc:interceptors>
    <!--第一种方式配置某个拦截器,默认是拦截所有请求的-->
    <bean class="com.citi.interceptor.ZuluInterceptor"></bean>
    <bean class="com.citi.interceptor.DeltaInterceptor"></bean>
</mvc:interceptors>
复制代码

将Controller中的interceptor方法中的异常代码注销,重新启动,点击页面的插连接

imagen.png 根据控制台的输出可以确定,限制性了Zulu拦截器中的preHandler方法,接着执行Delta拦截器的preHandler方法,再执行目标方法,接着调用Delta拦截器的postHandler,再执行Zulu拦截器的postHandler,再执行Delta拦截器的afterCompletion方法,最后再执行Zulu拦截器的afterCompletion方法

拦截顺序: 拦截器拦截顺序是按照配置的先后顺序,调整拦截器配置顺序

<mvc:interceptors>
    <!--第一种方式配置某个拦截器,默认是拦截所有请求的-->
    <bean class="com.citi.interceptor.DeltaInterceptor"></bean>
    <bean class="com.citi.interceptor.ZuluInterceptor"></bean>
</mvc:interceptors>
复制代码

Comience de nuevo y haga clic en el hipervínculo en la página de inicio. imagen.pngDe acuerdo con la salida de la consola, el interceptor Delta configurado primero en el archivo de configuración se ejecuta primero.

Flujo de excepción de múltiples interceptores:

Mantenga el interceptor Delta en primer lugar y el interceptor Zulu en último lugar en el archivo de configuración de Spring MVC. Si no se libera el interceptor Delta, no habrá llamadas posteriores; si no se libera el interceptor Zulu, ¿cuál será el resultado?

Devuelva falso en el interceptor Zulu, reinicie la aplicación y haga clic en el hipervínculo a la página de inicio

imagen.pngDe acuerdo con la salida de la consola, se puede determinar que el interceptor Zulu no se liberará, pero el método afterCompletion de Delta aún se ejecutará.

已放行了的拦截器的afterCompletion方法总会执行

Supongo que te gusta

Origin juejin.im/post/7085374517136064542
Recomendado
Clasificación