千家信息网

spring里的三大拦截器

发表于:2024-10-24 作者:千家信息网编辑
千家信息网最后更新 2024年10月24日,Filter新建 TimeFilter@Componentpublic class TimeFilter implements Filter {@Overridebr/>@OverrideSystem
千家信息网最后更新 2024年10月24日spring里的三大拦截器

Filter
新建 TimeFilter

@Component
public class TimeFilter implements Filter {@Override
br/>@Override

System.out.println("time filter init");
}

@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {    System.out.println("time filter start");    long startTime = System.currentTimeMillis();    filterChain.doFilter(servletRequest, servletResponse);    long endTime = System.currentTimeMillis();    System.out.println("time filter consume " + (endTime - startTime) + " ms");    System.out.println("time filter end");}@Overridepublic void destroy() {    System.out.println("time filter init");}

}

启动服务器,在浏览器输入:http://localhost:8080/hello?name=tom
可以在控制台输出如下结果:

time filter start
name: tom
time filter consume 3 ms
time filter end

可以看到,filter 先执行,再到真正执行 HelloController.sayHello() 方法。
通过 TimeFilter.doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) 方法的参数可以看出,我们只能得到原始的 request 和 response对象,不能得到这个请求被哪个 Controller 以及哪个方法处理了,使用Interceptor 就可以获得这些信息。

Interceptor
新建 TimeInterceptor

@Component
public class TimeInterceptor extends HandlerInterceptorAdapter {

private final NamedThreadLocal<Long> startTimeThreadLocal = new NamedThreadLocal<>("startTimeThreadLocal");@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("time interceptor preHandle");

    HandlerMethod handlerMethod = (HandlerMethod) handler;

// 获取处理当前请求的 handler 信息
System.out.println("handler 类:" + handlerMethod.getBeanType().getName());
System.out.println("handler 方法:" + handlerMethod.getMethod().getName());

    MethodParameter[] methodParameters = handlerMethod.getMethodParameters();

for (MethodParameter methodParameter : methodParameters) {
String parameterName = methodParameter.getParameterName();
// 只能获取参数的名称,不能获取到参数的值
//System.out.println("parameterName: " + parameterName);
}

    // 把当前时间放入 threadLocal

startTimeThreadLocal.set(System.currentTimeMillis());

    return true;

}

@Override

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("time interceptor postHandle");
}

@Override

public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    // 从 threadLocal 取出刚才存入的 startTime

Long startTime = startTimeThreadLocal.get();
long endTime = System.currentTimeMillis();

    System.out.println("time interceptor consume " + (endTime - startTime) + " ms");    System.out.println("time interceptor afterCompletion");

}
}

注册 TimeInterceptor
把 TimeInterceptor 注入 spring 容器

@Configuration
public class WebConfig extends WebMvcConfigurerAdapter {

@Autowiredprivate TimeInterceptor timeInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {    registry.addInterceptor(timeInterceptor);}

}

启动服务器,在浏览器输入:http://localhost:8080/hello?name=tom
可以在控制台输出如下结果:

time filter start
time interceptor preHandle
handler 类:com.nextyu.demo.web.controller.HelloController
handler 方法:sayHello
name: tom
time interceptor postHandle
time interceptor consume 40 ms
time interceptor afterCompletion
time filter consume 51 ms
time filter end

可以看到,filter 先于 interceptor 执行,再到真正执行 HelloController.sayHello() 方法。通过 interceptor 方法上的 handler 参数,我们就可以得到这个请求被哪个 Controller 以及哪个方法处理了。但是不能直接获取到这个方法上的参数值(在这里就是 HelloController.sayHello(String name) 方法参数 name 的值),通过 Aspect 就可以获取到。

Aspcet

Aspcet
新建 TimeAspect

@Aspect@Component
br/>@Component

@Around("execution(* com.nextyu.demo.web.controller.*.*(..))")public Object handleControllerMethod(ProceedingJoinPoint pjp) throws Throwable {    System.out.println("time aspect start");    Object[] args = pjp.getArgs();    for (Object arg : args) {        System.out.println("arg is " + arg);    }    long startTime = System.currentTimeMillis();    Object object = pjp.proceed();    long endTime = System.currentTimeMillis();    System.out.println("time aspect consume " + (endTime - startTime) + " ms");    System.out.println("time aspect end");    return object;}

}

启动服务器,在浏览器输入:http://localhost:8080/hello?name=tom
可以在控制台输出如下结果:

time filter start
time interceptor preHandle
handler 类:com.nextyu.demo.web.controller.HelloController
handler 方法:sayHello
time aspect start
arg is tom
name: tom
time aspect consume 0 ms
time aspect end
time interceptor postHandle
time interceptor consume 2 ms
time interceptor afterCompletion
time filter consume 4 ms
time filter end

可以看到,filter 先执行,再到 interceptor 执行,再到 aspect 执行,再到真正执行 HelloController.sayHello() 方法。
我们也获取到了 HelloController.sayHello(String name) 方法参数 name 的值。

请求拦截过程图

graph TD
httprequest-->filter
filter-->interceptor
interceptor-->aspect
aspect-->controller

方法 参数 控制台 服务器 浏览器 结果 处理 控制 服务 浏览 输入 输出 信息 原始 名称 容器 对象 就是 时间 过程 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 信息网络安全监察专升本 创业板服务器概念股 嵌入式软件开发程序编程规范 软件开发后台应用 网络安全 安恒 刘博 数据库的安全加固 新时代网络安全做我做起 大专学网络技术好还是软件开发 网站源码带数据库 湖南本地软件开发定制大概费用 数据库rds 网络技术如何改变了政治参与 南京点米互联网科技怎么样 国家网络安全与信息化厅职责 浙江智能化软件开发市场报价 服务器适不适合家用 河南智能软件开发要多少钱 日志管理系统云服务器流程 课程设计凯撒密码网络安全 网络安全教育讲的是什么 服务器底板折弯 河南辰星网络技术有限公司 动物森友会都有什么服务器 我的世界服务器怎么改成中文名字 mc阿喵的服务器被炸 荆州定制软件开发方案 查身份证长度数据库语句 广州省情数据库 思科网络技术学院教程知识点 数据库查询全部数据
0