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 ...
随机推荐
- Java设计模式之-------->"代理模式"
01.什么是代理模式? 解析:代理(Proxy):代理模式的主要作用是为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个对象不想或者不能直接引用另一个对象, 而代理对象可以在客户端和目标 ...
- CSS3弹性盒模型 display:box
刚开始做网页时就有一个困惑,为什么display:block只能垂直排列,如果要水平排列就要使用float:left等方式.这种方法最难受的当然是当子元素的数量改变时,需要去修改子元素的宽度使重新适应 ...
- web切图的几个快捷键及总结
自由的控制视图系列 自由的浏览图片:按住空格后,鼠标拖动 自由的缩放图片:按住alt+滚轮 切换到实际像素(100%):Ctrl + 1 工作区类型切换:Tab 控制内容系列 通过画面上点选一个图 ...
- 关于SCSI/SATA/IDE硬盘的比较
看linux的书时,发现许多地方提到SCSI/SATA/IDE这几种硬盘接口,对这些硬盘的概念和区别感到很模糊.所以特意查了一些资料,基本上算是弄懂了他们的区别. 目前硬盘最要分为3种.也即:IDE. ...
- 团队作业6——展示博客(Alpha版本)
Deadline: 2017-5-7 22:00PM,以博客发表日期为准 评分基准: 按时交 - 有分,检查的项目包括后文的四个方面 团队成员介绍 Alpha阶段进展 团队合作,各成员分工 Beta阶 ...
- 201521123091 《Java程序设计》第1周学习总结
Java 第一周总结 第一周的作业. 1.本章学习总结 [x] 初识Java语言:Java的历史,三大平台,了解JVM/JRE/JDK [x] Java开发环境的配置 [x] 用记事本编写Java程序 ...
- Swing-布局管理器应用--WIN7上计算器的UI实现
学完了Swing布局管理器,为了加深理解我决定做一些UI的实现,那就从WIN7上的计算器开始吧!首先,我们来研究一下它的UI.该计算器的UI主要有3个,分别是标准型.科学型和程序员型,如下图所示. ...
- 201521123052《Java程序设计》第3周学习总结
1. 本周学习总结 2. 书面作业 1.代码阅读 public class Test1 { private int i = 1;//这行不能修改 private static int j = 2; p ...
- 201521123059 《Java程序设计》第十四周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多数据库相关内容. 1.关系型数据库 --建立表格时表中一列中的数据类型必须一致.关系表中的行必须是唯一的,列是不可分的,某些行的某 ...
- 201521123117 《Java程序设计》第11周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 2. 书面作业 本次PTA作业题集多线程 1.互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) ...