顾名思义,在 Spring,拦截器拦截我们通过实现HandlerInterceptor
接口来请求。 它为我们提供了一些方法,使我们能够拦截控制器类正在处理的传入请求或控制器类已经处理的响应。
接口提供给我们的方法有:
preHandle()
– 返回true
或false
。 如果返回true
,则处理程序执行链继续,否则停止。postHandle()
– 处理程序执行后调用。afterCompletion()
– 在请求完成并生成视图之后调用。
HandlerInterceptor
与HandlerInterceptorAdapter
首先,我说过我们需要实现HandlerInterceptor
接口,但是我们也可以实现HandlerInterceptorAdapter
。 它们之间有 1 个区别,就是HandlerInterceptor
我们必须覆盖我上面提到的所有三种方法,而HandlerInterceptorAdapter
允许我们仅覆盖所需的方法。
代码实现
通常,这 3 种方法的工作流程会引发Exception
或返回true
。
@Component
public class EmployeeInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,Object handler) throws Exception {
// Basic validation of password and username
String username = request.getParameter("username");
String password = request.getParameter("password");
if(StringUtils.isEmpty(username) || StringUtils.isEmpty(password)) {
// throw the exception
throw new Exception("Empty username or password.");
}
// if no exception has been thrown, return true
return true;
}
@Override
public boolean postHandle(HttpServletRequest request, HttpServletResponse response,Object handler, ModelAndView modelAndView) throws Exception {
log.info(request);
return true;
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception exc) throws Exception {
if (exc != null)
exc.printStackTrace();
else
log.info("Request: " + request + " / Exception: " + exc);
}
}
让我们分解上面的代码示例。
首先我们创建我们的类并实现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
方法内添加了拦截器。
@Configuration
public class AppConfig extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new EmployeeInterceptor()).addPathPatterns("/account/signin/process");
}
}
另外,请记住,您必须在addInterceptors
方法中指定适当的路径模式。