多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
# Spring `HandlerInterceptor`示例 > [https://howtodoinjava.com/spring-mvc/spring-intercepting-requests-using-handlerinterceptor-with-example/](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 应用程序**](https://howtodoinjava.com/spring/spring-mvc/spring-mvc-hello-world-example/) 创建的代码。 我正在创建一个`CustomRequestHandler`类。 此类方法(即`preHandle()`,`postHandle()`和`afterCompletion()`)将按照上述讨论进行调用。 ```java package com.howtodoinjava.demo.handlers; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.web.servlet.ModelAndView; import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; public class CustomRequestHandler extends HandlerInterceptorAdapter { public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { long startTime = System.currentTimeMillis(); request.setAttribute("startTime", startTime); return true; } public void postHandle( HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { long startTime = (Long) request.getAttribute("startTime"); request.removeAttribute("startTime"); long endTime = System.currentTimeMillis(); modelAndView.addObject("totalTime", endTime - startTime); System.out.println("Request Prcessing Time :: " + (endTime - startTime)); } public void afterCompletion( HttpServletRequest request, HttpServletResponse response, Object handler, Exception exceptionIfAny) throws Exception { System.out.println("View Rendered !!"); } } ``` 现在,创建请求处理器后,必须将其声明为 spring 配置文件,以便 spring 可以在适当的时候将请求传递给它。 处理器拦截器已注册到`DefaultAnnotationHandlerMapping` bean,负责将拦截器应用于标有`@Controller`注解的任何类。 您可以在拦截器属性中指定多个拦截器,其类型为数组。 ```java <bean id="customRequestHandler" class="com.howtodoinjava.demo.handlers.CustomRequestHandler" /> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" /> <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"> <property name="interceptors"> <list> <ref bean="customRequestHandler" /> </list> </property> </bean> ``` 现在,当您再次运行 hello world 应用程序时,它将在输出下方显示。 ``` Request Prcessing Time :: 15 View Rendered !! ``` ## 仅将`HandlerInterceptor`接口应用于某些 URL 好吧,使用上述方法,您的处理器将被应用到应用程序中的所有控制器上,而不管它们映射到什么 URL。 如果您只想将处理器映射到某些 URL,则必须使用`<mvc:interceptors>`标签。 ```java <mvc:interceptors> <mvc:interceptor> <mvc:mapping path="/somepath_one/*"/> <ref bean="customRequestHandler_one" /> </mvc:interceptor> <mvc:interceptor> <mvc:mapping path="/somepath_two/*"/> <ref bean="customRequestHandler_two" /> </mvc:interceptor> </mvc:interceptors> ``` 这就是这个快速提示。 **祝您学习愉快!**