SpringMVC拦截器Interceptor
SpringMVC拦截器(Interceptor)实现对每一个请求处理前后进行相关的业务处理,类似与servlet中的Filter。
SpringMVC 中的Interceptor 拦截请求是通过HandlerInterceptor来实现的。
在SpringMVC中定义一个Interceptor非常简单,主要有4种方式:
1)实现Spring的HandlerInterceptor接口;
2)继承实现了HandlerInterceptor接口的类,比如Spring 已经提供的实现了HandlerInterceptor 接口的抽象类HandlerInterceptorAdapter;
3)实现Spring的WebRequestInterceptor接口;
4)继承实现了WebRequestInterceptor的类;
实现了拦截器之后,我们可以通过重写WebMvcConfigurerAdapter的addInterceptors方法来注册自己的拦截器。
我们这里只通过实现HandlerInterceptor接口的方式给出实例。实例中使用拦截器实现两个功能
1)计算每一次请求的处理时间
2)并对特定时间和特定用户(数据在codis中)的请求进行拒绝
1、HandlerInterceptor接口
public interface HandlerInterceptor {
boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) throws Exception;
void postHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler, ModelAndView modelAndView) throws Exception;
void afterCompletion(HttpServletRequest request,
HttpServletResponse response,
Object handler, Exception ex) throws Exception;
}
preHandle():预处理回调方法,若方法返回值为true,请求继续(调用下一个拦截器或处理器方法);若方法返回值为false,请求处理流程中断,不会继续调用其他的拦截器或处理器方法,此时需要通过response产生响应;postHandle():后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时可以通过modelAndView对模型数据进行处理或对视图进行处理afterCompletion():整个请求处理完毕回调方法,即在视图渲染完毕时调用
HandlerInterceptor有三个方法需要实现,但大部分时候可能只需要实现其中的一个方法,HandlerInterceptorAdapter是一个实现了HandlerInterceptor的抽象类,它的三个实现方法都为空实现(或者返回true),继承该抽象类后可以仅仅实现其中的一个方法。
2、实现拦截器
package com.xiaoju.dqa.sentinel.monitor.interceptor; import com.xiaoju.dqa.sentinel.common.client.redis.CodisClient;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Calendar;
import java.util.Set; public class AuthInterceptor implements HandlerInterceptor { protected final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired
private CodisClient codisClient; /*
* 视图函数执行成功后执行
* */
@Override
public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
} /*
* 在视图函数之后执行
* 本函数的作用:计算处理时间
* */
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception {
long startTime = (Long) request.getAttribute("startTime");
request.removeAttribute("startTime");
logger.info("处理时间: {}", System.currentTimeMillis() - startTime);
} /*
* 在视图函数之前执行
* 返回true, 继续执行视图函数
* 返回false, 终止请求流程
* 本函数的作用,:拒绝特定时间sentinel:forbidden:hours; 特定用户的sentinel:forbidden:users请求, 并记录startTime
* */
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
boolean going = true;
long startTime = System.currentTimeMillis();
request.setAttribute("startTime", startTime);
Calendar ca = Calendar.getInstance();
String currentHour = String.valueOf(ca.get(Calendar.HOUR_OF_DAY));
try {
boolean isForbidHour = codisClient.sismember("sentinel:forbidden:hours", currentHour);
if (isForbidHour) {
Set<String> forbiddenUsers = codisClient.smembers("sentinel:forbidden:users");
if (forbiddenUsers != null) {
for (Cookie cookie : request.getCookies()) {
if("username".equals(cookie.getName()) && forbiddenUsers.contains(cookie.getValue())) {
logger.info("[拦截器] 禁止访问. 时间:{}, 用户:{}", currentHour, cookie.getValue());
going = false;
}
}
}
}
} catch (Exception e) {
logger.info("[拦截器] 有问题", e);
}
return going;
}
}
3、注册拦截器
这里预先生成了@bean - authInterceptor是为了让AuthInterceptor类中的codisClient的注入成功,否则即使自动注入了codisClient也无法注入成功。
package com.xiaoju.dqa.sentinel.configuration; import com.xiaoju.dqa.sentinel.monitor.interceptor.AuthInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; @Configuration
public class WebInterceptorConfig extends WebMvcConfigurerAdapter { @Bean
public AuthInterceptor authInterceptor() {
return new AuthInterceptor();
} @Override
public void addInterceptors(InterceptorRegistry registry) {
// 多个拦截器组成一个拦截器链
// addPathPatterns 用于添加拦截规则
// excludePathPatterns 用户排除拦截
registry.addInterceptor(authInterceptor()).addPathPatterns("/**").excludePathPatterns("/sentinel/monitor/**");
super.addInterceptors(registry);
} }
SpringMVC拦截器Interceptor的更多相关文章
- java 过滤器(Filter)与springMVC 拦截器(interceptor)的实现案例
java 过滤器Filter: package com.sun.test.aircraft.filter;import javax.servlet.*;import java.io.IOExcepti ...
- Java过滤器(Filter)与SpringMVC拦截器(Interceptor)之间的关系与区别
过滤器和拦截器的区别: ①拦截器是基于java的反射机制的,而过滤器是基于函数回调. ②拦截器不依赖与servlet容器,过滤器依赖与servlet容器. ③拦截器只能对action请求起作用,而过滤 ...
- SSM-SpringMVC-33:SpringMVC中拦截器Interceptor讲解
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 拦截器Interceptor: 对处理方法进行双向的拦截,可以对其做日志记录等 我选择的是实现Handler ...
- SpringMVC处理器拦截器 Interceptor
拦截器概念 Java 里的拦截器是动态拦截action调用的对象.它提供了一种机制可以使开发者可以定义在一个action执行的前后执行的代码,也可以在一个action执行前阻止其执行,同时也提供了一种 ...
- SpringMVC拦截器的使用
SpringMVC 中的Interceptor 拦截器也是相当重要和相当有用的,它的主要作用是拦截用户的请求并进行相应的处理.比如通过它来进行权限验证,或者是来判断用户是否登陆,或者是像12306 那 ...
- SpringMVC拦截器详解[附带源码分析]
目录 前言 重要接口及类介绍 源码分析 拦截器的配置 编写自定义的拦截器 总结 总结 前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门blog:h ...
- SpringMVC拦截器2(资源和权限管理)(作为补充说明)
SpringMVC拦截器(资源和权限管理) 1.DispatcherServlet SpringMVC具有统一的入口DispatcherServlet,所有的请求都通过DispatcherServle ...
- SpringMVC拦截器(实现登录验证拦截器)
本例实现登陆时的验证拦截,采用SpringMVC拦截器来实现 当用户点击到网站主页时要进行拦截,用户登录了才能进入网站主页,否则进入登陆页面 核心代码 首先是index.jsp,显示链接 <%@ ...
- Spring+SpringMVC+MyBatis深入学习及搭建(十七)——SpringMVC拦截器
转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/7098753.html 前面讲到:Spring+SpringMVC+MyBatis深入学习及搭建(十六)--S ...
随机推荐
- Project 8:利用递归算法求最大值
目标:用递归算法实现求一个数组中的最大元素. 样例输入 5 1 4 2 5 3 样例输出 5 #include <stdio.h> int max(int *,int); int main ...
- js Web存储方式
JSON是数据交互中最常用的一种数据格式. 由于各种语言的语法都不同,在传递数据时,可以将自己语言中的数组.对象等转换为JSON字符串> 传递之后,可以讲JSON字符串,在解析为JSON对象. ...
- 【Alpha】第六次Daily Scrum Meeting
一.今日站立式会议照片 二.会议内容 1.具体讨论了各个功能模块如何实现所使用的函数方法,以及确定各功能编写的详易与主次之分.其中对礼物挑选的各个分类条件做了修改与确认.并考虑邀请同学对已构建出的简易 ...
- class中的东西和继承、多态的概念
class中的private.public.protected 最近看了一些视频顺便总结一下class中的这几个类型以及继承 public: 在C++和C#中类的用法,语法是差不多的.当变量,函数之类 ...
- 201521123016《java程序设计》第4周学习总结
1. 本周学习总结 2. 书面作业 注释的应用 使用类的注释与方法的注释为前面编写的类与方法进行注释,并在Eclipse中查看.(截图) 面向对象设计(大作业1,非常重要) 2.1 将在网上商城购物或 ...
- 201521123115 《Java程序设计》第3周学习总结
Java 第三周总结 1.本周学习总结 {{uploading-image-747934.png(uploading...)}} 2.书面作业 1.代码阅读 public class Test1 { ...
- Java程序设计——学生基本信息管理系统
1.团队课程设计博客链接 http://www.cnblogs.com/handsome321/p/7067121.html 2.个人负责模块说明 本组课题:学生信息管理系统 本人任务:插入.删除学生 ...
- Java程序设计-表达式运算(个人博客)
1.团队课程设计博客链接 洪亚文博客链接:http://www.cnblogs.com/201521123065hyw/ 郑晓丽博客链接:http://www.cnblogs.com/zxl3066/ ...
- 万物皆对象的JavaScript
写在前面: 经过前段时间对于H5语言的学习,开始慢慢适应现在的生活节奏和代码语言.从一开始的毫无头绪到现在可以大概地写出部分的网站静态页面,用了两个周的时间.作为一个之前从未接触过计算机语言的初学者来 ...
- Java:extends和implements的区别+用法
Java代码中的extends和implements让我感到很迷惑,现在终于弄明白它们之间的区别和用法了. [c-sharp] view plain copy //定义一个Runner接口 publi ...