在控制层进行访问拦截也是我们在项目中常会遇到的需求,例如:项目中要求系统登录操作有时间限制--12306购票时间的限制等.
对于这类需求我们一般有几种选择:
- 过滤器Filter
- AOP
- SpringMVC拦截器...
本文我们主要说一下SpringMVC拦截器的实现
原理
Spring MVC的拦截器是基于回调机制,可以在目标方法执行之前/之后,做一些处理.
如下图所示:
客户端的请求通过前端控制器会被HandleInterceptor拦截器拦截,会根据拦截器的方法(preHandle/postHandle),分别在Controller层的目标方法之前或之后只写一些业务.
实现
我们要实现的是登录前的拦截,然后进行时间判定--所以我们需要用preHandle方法,可以在目标方法执行之前,先进行业务检测,满足条件则放行,不满足条件则进行拦截
具体实现分为两步:
- 定义拦截器:
public class TimeAccessInterceptor implements HandlerInterceptor{ /** 此方法会在你的目标Controller执行之前执行 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { System.out.println("==preHandler=="); LocalDateTime now = LocalDateTime.now();//JDK8的新特性 int hour = now.getHour(); System.out.println("hour:"+hour); if(hour<9||hour>19) throw new ServiceException("不在访问时间:9~14");//return false return true;//true表示放行,false表示请求到此结束 }}
我们自己创建一个类并且实现HandlerInterceptor拦截器接口,然后根据你的业务需求实现方法,我们这里实现的是preHandle方法用于在controller执行之前执行,通过JDK8的新特性--LocalDateTime.now()来获取当前时间,可以再通过now.getHoure()等方法来获取具体的小时/分钟/秒等.在判断是否在我们禁止登陆的时间范围内,如果是则抛出异常(这里ServiceException是我们自己定义的异常类),抛出异常==return false,返回值return true表示放行,false表示拦截结束.
- 对拦截器进行配置
@Configurationpublic class SpringWebConfig implements WebMvcConfigurer { /** * 注册拦截器 */ @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new TimeAccessInterceptor()) .addPathPatterns("/user/doLogin"); }}
创建一个SpringWebConfig类并且实现WebMvcConfigurer接口,类由@Configuration注解描述,表示是一个配置类,重写实现类中的addInterceptors方法,参数InterceptorRegistry registry拦截器集合,调用addInterceptor(new TimeAccessInterceptor())向其中添加我们定义的拦截器类,在调用addPathPatterns("/user/doLogin"),添加要拦截的路径,()内就是我们登陆的路径.