Spring Web MVC семейства Spring Bucket (7) — перехватчик

Привыкайте писать вместе! Это 11-й день моего участия в «Новом ежедневном плане Nuggets · Апрельское задание по обновлению», нажмите, чтобы просмотреть подробности мероприятия .

1. Перехватчик

Spring MVC предоставляет механизм перехватчика, который позволяет выполнить некоторую работу по перехвату перед запуском целевого метода или некоторую другую обработку после запуска целевого метода.

Перехватчик в Spring MVC — это интерфейс HandlerInterceptor, который содержит три метода.

изображение.png

  • preHandler: этот метод вызывается до того, как бизнес-процессор обработает запрос. В этом методе обрабатывается запрос пользователя. Если для перехвата запроса требуется перехватчик, будут вызваны другие перехватчики или будет обработан бизнес-процессор. Затем возврат Значение true, чтобы отменить запрос, и вернуть false, если нет необходимости вызывать другие компоненты, а также для освобождения запроса.
  • postHandler: этот метод вызывается после того, как бизнес-процессор закончил обработку запроса, но он вызывается до того, как DispatcherServlet вернет ответ клиенту.В этом методе обрабатывается запрос запроса пользователя.
  • afterCompletion: этот метод вызывается после того, как DispatcherServlet полностью обработает запрос, и в этом методе могут быть выполнены некоторые операции по очистке ресурсов.

Во-вторых, пользовательский перехватчик

Скопируйте проект spring-mvc-ajax, переименуйте его в spring-mvc-handler и удалите классы и файлы, кроме конфигурации.

Нормальный поток перехватчика

Создайте новый HandlerInterceptorSamplerController, определите метод перехватчика в контроллере, протестируйте пользовательский перехватчик и вернитесь на страницу успеха.

@Controller
public class HandlerInterceptorSamplerController {

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

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

Добавьте гиперссылку на страницу index.jsp

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

Добавьте пакет перехватчика, создайте новый пользовательский перехватчик ZuluInterceptor, пользовательский перехватчик должен реализовывать интерфейс HandlerInterceptor и добавить печать журнала для каждого метода в перехватчике.

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方法运行了");
    }
}
复制代码

Зарегистрируйте перехватчик в файле конфигурации Spring MVC и настройте, какие запросы перехватывает перехватчик.

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

Запустите приложение и нажмите гиперссылку на главной странице

изображение.pngСогласно выводу консоли, пользовательский перехватчик вызывается успешно.

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

拦截器的异常流程

异常流程1 - preHandler返回false

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

异常流程2 - 其他异常

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

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

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

再次重新启动应用,点击页面的超链接 изображение.png 页面出现有异常代码导致的报错

изображение.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方法中的异常代码注销,重新启动,点击页面的插连接

изображение.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>
复制代码

Запустите снова и щелкните гиперссылку на домашней изображение.pngстранице.Согласно выводу консоли, перехватчик Delta, настроенный первым в файле конфигурации, выполняется первым.

Поток исключений нескольких перехватчиков:

Держите перехватчик Delta первым, а перехватчик Zulu последним в файле конфигурации Spring MVC. Если не выпустить перехватчик Дельта, то последующих вызовов не будет, если не выпустить перехватчик Зулу, то какой будет результат?

Верните false в перехватчике Zulu, перезапустите приложение и щелкните гиперссылку на домашнюю страницу.

изображение.pngПо выводу консоли можно определить, что перехватчик Zulu не будет выпущен, но метод afterCompletion Delta все равно будет выполнен.

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

рекомендация

отjuejin.im/post/7085374517136064542