原文: https://javatutorial.net/interceptors-in-spring

顾名思义,在 Spring,拦截器拦截我们通过实现HandlerInterceptor接口来请求。 它为我们提供了一些方法,使我们能够拦截控制器类正在处理的传入请求或控制器类已经处理的响应。

Spring 拦截器 - 图1

接口提供给我们的方法有:

  1. preHandle() – 返回truefalse。 如果返回true,则处理程序执行链继续,否则停止。
  2. postHandle() – 处理程序执行后调用。
  3. afterCompletion() – 在请求完成并生成视图之后调用。

HandlerInterceptorHandlerInterceptorAdapter

首先,我说过我们需要实现HandlerInterceptor接口,但是我们也可以实现HandlerInterceptorAdapter。 它们之间有 1 个区别,就是HandlerInterceptor我们必须覆盖我上面提到的所有三种方法,而HandlerInterceptorAdapter允许我们仅覆盖所需的方法。

代码实现

通常,这 3 种方法的工作流程会引发Exception或返回true

  1. @Component
  2. public class EmployeeInterceptor implements HandlerInterceptor {
  3. @Override
  4. public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler) throws Exception {
  5. // Basic validation of password and username
  6. String username = request.getParameter("username");
  7. String password = request.getParameter("password");
  8. if(StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
  9. // throw the exception
  10. throw new Exception("Empty username or password.");
  11. }
  12. // if no exception has been thrown, return true
  13. return true;
  14. }
  15. @Override
  16. public boolean postHandle(HttpServletRequest request, HttpServletResponse response,Object handler, ModelAndView modelAndView) throws Exception {
  17. log.info(request);
  18. return true;
  19. }
  20. @Override
  21. public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
  22. Object handler, Exception exc) throws Exception {
  23. if (exc != null)
  24. exc.printStackTrace();
  25. else
  26. log.info("Request: " + request + " / Exception: " + exc);
  27. }
  28. }

让我们分解上面的代码示例。

首先我们创建我们的类并实现HandlerInterceptor,因为它会覆盖所有三个方法。 按照惯例,类名必须在初始名称之后具有Interceptor。 然后,我们重写preHandle()方法。 它包含 3 个参数 - 请求,响应和处理程序,并且不要忘记throws Exception

preHandle()

我的preHandle()方法非常简单–它从请求中获取用户名和密码,然后检查它们是否为空以及是否为空,然后抛出异常,指出“空用户名或密码”。 如果它们不为空,则返回true。 在正常环境中,您当然会做更多的验证,但是为了简单起见,我这样做了。

postHandle()

如果没有引发异常并记录请求,我的postHandle()方法从返回true不会起到什么作用。 它包含 4 个参数 - 请求,响应,处理程序和modelAndView。 它还throws Exception。通常,此方法用于修改ModelAndView(通常通过添加其他属性)或简单地确定处理程序方法处理客户请求所花费的时间。

afterCompletion()

我的afterCompletion()方法记录了请求和异常,但是在此之前,它通过说exc != null来检查是否有异常,如果存在,那么我们说exc.printStackTrace()

配置

我们的拦截器尚未添加到 Spring 配置中。 要添加它,我们必须实现一个自定义@Configuration文件,该文件扩展了WebMvcConfigurerAdapter,该文件在addInterceptors方法内添加了拦截器。

  1. @Configuration
  2. public class AppConfig extends WebMvcConfigurerAdapter {
  3. @Override
  4. public void addInterceptors(InterceptorRegistry registry) {
  5. registry.addInterceptor(new EmployeeInterceptor()).addPathPatterns("/account/signin/process");
  6. }
  7. }

另外,请记住,您必须在addInterceptors方法中指定适当的路径模式。