1 概述
SpringMVC拦截器(Interceptor)实现对每一个请求处理前后进行相关的业务处理,类似与servlet中的Filter。
SpringMVC 中的Interceptor 拦截请求是通过HandlerInterceptor来实现的。
在SpringMVC中定义一个Interceptor,主要有4种方式:
1)实现Spring的HandlerInterceptor接口;
2)继承实现了HandlerInterceptor接口的类,比如Spring 已经提供的实现了HandlerInterceptor 接口的抽象类HandlerInterceptorAdapter;
3)实现Spring的WebRequestInterceptor接口;
4)继承实现了WebRequestInterceptor的类;
2 demo
本次示例是采用第一种实现方式
实现HandlerInterceptor接口
@Component
public class MyHandlerIntercepter implements HandlerInterceptor {
private final Logger logger = Logger.getLogger(MyHandlerIntercepter.class);
//Handler执行前调用
//应用场景:登录认证、身份授权
//返回值为true则是放行,为false是不放行
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws MyException {
logger.info("resquest请求地址path:"+request.getServletPath()+" uri:"+request.getRequestURI());
Long userId= getUserId(request.getHeader("H-User-Token"));
if (userId != null && checkAuth(userId,request.getRequestURI())){
return true;
}
//这里的异常是我自定义的异常,系统抛出异常后框架捕获异常然后转为统一的格式返回给前端, 其实这里也可以返回false
throw new MyException("No access");
}
/**
* 根据token获取用户ID
* @param userToken
* @return
*/
private Long getUserId(String userToken){
Long userId = null;
return userId;
}
/**
* 校验用户访问权限
* @param userId
* @param requestURI
* @return
*/
private boolean checkAuth(Long userId,String requestURI){
return true;
}
//进入Handler开始执行,并且在返回ModelAndView之前调用
//应用场景:对ModelAndView对象操作,可以把公共模型数据传到前台,可以统一指定视图
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) {
}
//执行完Handler之后调用
//应用场景:统一异常处理、统一日志处理
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
logger.error("intercepter 异常处理",ex);
}
}
抛出的自定义异常,j交由前文中讲过的springmvc异常处理器处理,错误信息会统一返回到error页面中。
3 拦截器配置
@Configuration
@EnableWebMvc
public class ConfigAdapter implements WebMvcConfigurer {
@Autowired
private MyHandlerIntercepter intercepter1;
//注册自定义的拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(intercepter1);
}
}