https://howtodoinjava.com/spring-mvc/spring-intercepting-requests-using-handlerinterceptor-with-example/

如您所知,servlet 过滤器可以在处理该 servlet 之前和之后对它们处理的每个 Web 请求进行预处理和后处理。 以类似的方式,您可以在 Spring Web 应用程序中使用HandlerInterceptor接口来对由 Spring MVC 处理器处理的 Web 请求进行预处理和后处理。 这些处理器通常用于处理返回/提交的模型属性,并将它们传递给视图/处理器。

HandlerInterceptor接口

处理器拦截器是在 Spring 的 Web 应用程序上下文中配置的,因此它们可以利用任何容器功能,并引用容器中声明的任何 bean。 可以为特定的 URL 映射注册处理器拦截器,因此它仅拦截映射到某些 URL 的请求。

每个处理器拦截器都必须实现HandlerInterceptor接口,该接口包含要实现的三种回调方法:preHandle()postHandle()afterCompletion()

  • preHandle():在请求处理器处理请求之前。
  • postHandle():请求处理器处理完请求后。 它提供对返回的ModelAndView对象的访问,因此您可以在其中操作模型属性。
  • afterCompletion():在完成所有请求处理之后,即在渲染视图之后。

HandlerInterceptorAdapter

HandlerInterceptor接口的问题在于,无论是否需要,新类都必须实现所有三种方法。 为避免覆盖,可以使用HandlerInterceptorAdapter类。 此类实现HandlerInterceptor并提供默认的空白实现。

因此,无论您想在处理器中覆盖什么方法,都可以从HandlerInterceptorAdapter对其进行扩展。

HandlerInterceptor接口示例

我在这里重用为 Spring MVC hello world 应用程序 创建的代码。 我正在创建一个CustomRequestHandler类。 此类方法(即preHandle()postHandle()afterCompletion())将按照上述讨论进行调用。

  1. package com.howtodoinjava.demo.handlers;
  2. import javax.servlet.http.HttpServletRequest;
  3. import javax.servlet.http.HttpServletResponse;
  4. import org.springframework.web.servlet.ModelAndView;
  5. import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
  6. public class CustomRequestHandler extends HandlerInterceptorAdapter
  7. {
  8. public boolean preHandle(HttpServletRequest request,
  9. HttpServletResponse response,
  10. Object handler)
  11. throws Exception
  12. {
  13. long startTime = System.currentTimeMillis();
  14. request.setAttribute("startTime", startTime);
  15. return true;
  16. }
  17. public void postHandle( HttpServletRequest request,
  18. HttpServletResponse response,
  19. Object handler,
  20. ModelAndView modelAndView)
  21. throws Exception
  22. {
  23. long startTime = (Long) request.getAttribute("startTime");
  24. request.removeAttribute("startTime");
  25. long endTime = System.currentTimeMillis();
  26. modelAndView.addObject("totalTime", endTime - startTime);
  27. System.out.println("Request Prcessing Time :: " + (endTime - startTime));
  28. }
  29. public void afterCompletion( HttpServletRequest request,
  30. HttpServletResponse response,
  31. Object handler,
  32. Exception exceptionIfAny)
  33. throws Exception
  34. {
  35. System.out.println("View Rendered !!");
  36. }
  37. }

现在,创建请求处理器后,必须将其声明为 spring 配置文件,以便 spring 可以在适当的时候将请求传递给它。

处理器拦截器已注册到DefaultAnnotationHandlerMapping bean,负责将拦截器应用于标有@Controller注解的任何类。 您可以在拦截器属性中指定多个拦截器,其类型为数组。

  1. <bean id="customRequestHandler" class="com.howtodoinjava.demo.handlers.CustomRequestHandler" />
  2. <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
  3. <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
  4. <property name="interceptors">
  5. <list>
  6. <ref bean="customRequestHandler" />
  7. </list>
  8. </property>
  9. </bean>

现在,当您再次运行 hello world 应用程序时,它将在输出下方显示。

  1. Request Prcessing Time :: 15
  2. View Rendered !!

仅将HandlerInterceptor接口应用于某些 URL

好吧,使用上述方法,您的处理器将被应用到应用程序中的所有控制器上,而不管它们映射到什么 URL。 如果您只想将处理器映射到某些 URL,则必须使用<mvc:interceptors>标签。

  1. <mvc:interceptors>
  2. <mvc:interceptor>
  3. <mvc:mapping path="/somepath_one/*"/>
  4. <ref bean="customRequestHandler_one" />
  5. </mvc:interceptor>
  6. <mvc:interceptor>
  7. <mvc:mapping path="/somepath_two/*"/>
  8. <ref bean="customRequestHandler_two" />
  9. </mvc:interceptor>
  10. </mvc:interceptors>

这就是这个快速提示。

祝您学习愉快!