JAVA拦截器的三种实现方式

JAVA拦截器的三种实现方式

  • 一、java原生过滤器Filter
  • 二、springMVC拦截器
  • 三、aop切面实现拦截器

一、java原生过滤器Filter

/*** 自定义Filter* 对请求的header 过滤token** 过滤器Filter可以拿到原始的HTTP请求和响应的信息,*     但是拿不到你真正处理请求方法的信息,也就是方法的信息** @Component 注解让拦截器注入Bean,从而让拦截器生效* @WebFilter 配置拦截规则** 拦截顺序:filter—>Interceptor-->ControllerAdvice-->@Aspect -->Controller**/
@Slf4j
@Component
@WebFilter(urlPatterns = {"/**"},filterName = "authFilter")
public class MyFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {log.info("TokenFilter init {}",filterConfig.getFilterName());}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {String param = request.getParameter("param");response.setContentType("text/html;charset=UTF-8");//获取请求头tokenString token = "";HttpServletRequest httpServletRequest = (HttpServletRequest) request;Enumeration<String> headerNames = httpServletRequest.getHeaderNames();while(headerNames.hasMoreElements()) {//判断是否还有下一个元素String nextElement = headerNames.nextElement();//获取headerNames集合中的请求头if ("token".equals(nextElement)){token = httpServletRequest.getHeader(nextElement);log.info("请求头key[" + nextElement + "]:" + token);}}log.info("doFilter-我拦截到了请求:"+ param);if (null != param && "pass".equals(param)){//验证tokenif ("7758258xx".equals(token)){chain.doFilter(request,response);//到下一个链}else{response.getWriter().write("doFilter-请求头token不通过");}}else{log.info("doFilter-参数param不符合条件");response.getWriter().write("doFilter-参数param不通过");}}@Overridepublic void destroy() {log.info("destroy");}
}

二、springMVC拦截器

/*** 自定义拦截器* 自定义拦截器后,需要配置进Spring** 拦截器Interceptor可以拿到原始的HTTP请求和响应的信息,*    也可以拿到你真正处理请求方法的信息,但是拿不到传进参数的那个值。**拦截顺序:filter—>Interceptor-->ControllerAdvice-->@Aspect -->Controller*/
@Slf4j
@Component
public class MyInterceptor implements HandlerInterceptor {/*** 在访问Controller某个方法之前这个方法会被调用。* @param request* @param response* @param handler* @return false则表示不执行postHandle方法,true 表示执行postHandle方法* @throws Exception*/@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {log.info("Interceptor preHandle {}","");String token = request.getHeader("token");log.info("Interceptor preHandle token :{}",token);log.info("Interceptor preHandle uri {}",request.getRequestURL().toString());response.setContentType("text/html;charset=UTF-8");//spring boot 2.0对静态资源也进行了拦截,当拦截器拦截到请求之后,// 但controller里并没有对应的请求时,该请求会被当成是对静态资源的请求。// 此时的handler就是 ResourceHttpRequestHandler,就会抛出上述错误。if (handler instanceof HandlerMethod){HandlerMethod handlerMethod = (HandlerMethod) handler;Method method = handlerMethod.getMethod();log.info("Token Interceptor preHandle getMethod {}",method.getName());}else if(handler instanceof ResourceHttpRequestHandler){//静态资源ResourceHttpRequestHandler resourceHttpRequestHandler = (ResourceHttpRequestHandler) handler;log.info("Token Interceptor preHandle getMethod {}",resourceHttpRequestHandler.getMediaTypes());}if (!"7758258xx".equals(token)){response.getWriter().write("doInterceptor-请求头token不通过");return false;}//false则表示不执行postHandle方法,不执行下一步chain链,直接返回responsereturn true;}/*** 请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)* preHandle方法处理之后这个方法会被调用,如果控制器Controller出现了异常,则不会执行此方法* @param request* @param response* @param handler* @param modelAndView* @throws Exception*/@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {log.info("Interceptor postHandle");}/*** 不管有没有异常,这个afterCompletion都会被调用* @param request* @param response* @param handler* @param ex* @throws Exception*/@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {log.info("Interceptor afterCompletion");}

三、aop切面实现拦截器

引入maven:

<dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.4</version>
</dependency>
/*** @Description: 切面*/
@Slf4j
@Component  //表示它是一个Spring的组件
@Aspect  //表示它是一个切面
public class MyAspect {private static final Logger logger = LoggerFactory.getLogger(MyAspect.class);ThreadLocal<Long> startTime = new ThreadLocal<>();/*** 第一个*代表返回类型不限* 第二个*代表所有类* 第三个*代表所有方法* (..) 代表参数不限* com.zhangximing.springbootinterceptor.controller 测试的controller层*/@Pointcut("execution(public * com.zhangximing.springbootinterceptor.controller.*.*(..))")public void pointCut(){};@Before(value = "pointCut()")public void before(JoinPoint joinPoint){System.out.println("方法执行前执行......before");ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();HttpServletRequest request = attributes.getRequest();logger.info("<=====================================================");logger.info("请求来源: =》" + request.getRemoteAddr());logger.info("请求URL:" + request.getRequestURL().toString());logger.info("请求方式:" + request.getMethod());logger.info("响应方法:" + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());logger.info("请求参数:" + Arrays.toString(joinPoint.getArgs()));logger.info("连接点的方法签名对象:"+joinPoint.getSignature());logger.info("连接点所在的目标对象:"+joinPoint.getTarget());logger.info("代理对象:"+joinPoint. getThis());logger.info("------------------------------------------------------");startTime.set(System.currentTimeMillis());}// 定义需要匹配的切点表达式,同时需要匹配参数/*** @description 要拦截修改参数的值只有使用这个方法,Around相当于before+after* @param pjp* @param arg 类型可以根据pointCut指定切点类下的方法确定,也可以使用统一的Object,也可以不写参数* @return* @throws Throwable*/@Around("pointCut() && args(arg)")public Object around(ProceedingJoinPoint pjp, Object arg) throws Throwable{logger.info("入参:{}",arg);logger.info("方法环绕start...around");JSONObject param = JSONObject.parseObject(JSONObject.toJSONString(arg));if ("zxm".equals(param.getString("name"))){JSONObject result = new JSONObject();result.put("success",false);result.put("msg","error");return result;}param.put("exist",true);param.put("name","cml");//修改值Object[] objects = new Object[]{param};Object objectNew = pjp.proceed(objects);logger.info("方法环绕end...around");return objectNew;}@After("within(com.zhangximing.springbootinterceptor.controller.*)")public void after(){System.out.println("方法之后执行...after.");}/**** @param AjaxResult  rst 该参数类型需要与测试的Controller层的返回值类型一致,否则不生效,也就是找不到*            该测试中的AjaxResult是测试项目中封装好的出参*/@AfterReturning(pointcut="pointCut()",returning = "rst")public void afterRunning(JSONObject rst){if(startTime.get() == null){startTime.set(System.currentTimeMillis());}System.out.println("方法执行完执行...afterRunning");logger.info("耗时(毫秒):" +  (System.currentTimeMillis() - startTime.get()));logger.info("返回数据:{}", rst);logger.info("==========================================>");}@AfterThrowing("within(com.zhangximing.springbootinterceptor.controller.*)")public void afterThrowing(){System.out.println("异常出现之后...afterThrowing");}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/20263.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 基础面试300题 (141- 170 )

Java 基础面试300题 &#xff08;141- 170 &#xff09; 141. 编译运行以下代码时会发生什么&#xff1f; class Mammal {} class Cat extends Mammal { } List<Mammal> list new ArrayList<Cat>();上述代码将出现编译错误。这是因为为List指定了Mammal哺乳动物…

SpringSecurity6从入门到实战之整合原生Filter链

SpringSecurity6从入门到实战之整合原生Filter链 DelegatingFilterProxy 从官网上来进行学习可以看到第一个类就是DelegatingFilterProxy,我们首先看看官网给下的定义. Spring提供了一个名为DelegatingFilterProxy的过滤器实现&#xff0c;它允许在Servlet容器的生命周期和Spr…

Raid的全局热备和独立热备

目录 Hot Spare背景: 1.定义与功能 2.数据存储与容量 3.配置模式 4.数量限制&#xff1a; 5.数据重建: 6.管理与维护 实操全局热备和独立热备&#xff1a; 配置全局热备: 配置独立热备: Hot Spare背景: 在RAID配置中&#xff0c;Hot Spare(热备)是一个非常重要的概念…

amis源码 Api接口调用解析:

Amis中传入用户自定义fetcher(基于fetcher做接口调用)&#xff1a; 1.embed渲染时可以传入用户定义的fetcher(接口调用)&#xff1a; import axios from "/libs/api.request"; //自定义的fetcher调用接口&#xff08;axios调用&#xff09; { fetcher: ()>{ ……

发现一个ai工具网站

网址 https://17yongai.com/ 大概看了下&#xff0c;这个网站收集的数据还挺有用的&#xff0c;有很多实用的ai教程。 懂ai工具的可以在这上面找找灵感。

善听提醒遵循易经原则。世界大同只此一路。

如果说前路是一个大深坑&#xff0c;那必然是你之前做的事情做的不太好&#xff0c;当坏的时候&#xff0c;坏的结果来的时候&#xff0c;是因为你之前的行为&#xff0c;你也就不会再纠结了&#xff0c;会如何走出这个困境&#xff0c;是好的来了&#xff0c;不骄不躁&#xf…

事先预判事的结果事先预防从容应对防微杜渐

很多人呢&#xff0c;学习倪老师的知识&#xff0c;也都是从他的中医方面&#xff0c;认识了他很多的东西呢&#xff0c;对于倪老师的知识性的总结的东西呢&#xff0c;不是很了解。 其实啊&#xff0c;倪老师也是一个&#xff0c;对于这种文化的传承&#xff0c;有着很大很深刻…

一些汇编语言的总结

一、汇编语言的介绍 1、汇编语言和处理器指令集高度相关&#xff0c;不同指令集的汇编语言不兼容。 2、汇编语言是对机器语言的一种抽象&#xff0c;用英文字符来代表运算和控制指令&#xff0c;用英文字母和数字代表操作数。 二、常用的汇编语言 有 x86的汇编语言&#xff…

YOLOv10涨点改进:卷积魔改 | 分布移位卷积(DSConv),提高卷积层的内存效率和速度

💡💡💡本文改进内容: YOLOv10如何魔改卷积进一步提升检测精度?提出了一种卷积的变体,称为DSConv(分布偏移卷积),其可以容易地替换进标准神经网络体系结构并且实现较低的存储器使用和较高的计算速度。 DSConv将传统的卷积内核分解为两个组件:可变量化内核(VQK)和…

iOS编程入门:揭秘神秘的开发世界

iOS编程入门&#xff1a;揭秘神秘的开发世界 在数字化时代的浪潮中&#xff0c;iOS编程成为了许多开发者热衷探索的领域。想要入门iOS编程&#xff0c;不仅需要掌握基础知识&#xff0c;还需理解其独特的生态系统。本文将通过四个方面、五个方面、六个方面和七个方面&#xff…

golang中通过反射获取结构体Tag标签定义的内容 函数和测试用例

当我们在go语言中定义结构体的时候&#xff0c; 经常需要给某些字段打上一个Tag标签, 如 Name string json:"name" , 那这个标签有和作用呢&#xff1f; 这个作用可大了&#xff0c;最为常用的是json序列化和反序列化&#xff0c; 还有各种ORM 的实体对象定义&…

C# yolov8 TensorRT +ByteTrack Demo

C# yolov8 TensorRT ByteTrack Demo 目录 效果 说明 项目 代码 Form2.cs YoloV8.cs ByteTracker.cs 下载 参考 效果 说明 环境 NVIDIA GeForce RTX 4060 Laptop GPU cuda12.1cudnn 8.8.1TensorRT-8.6.1.6 版本和我不一致的需要重新编译TensorRtExtern.dll&…

微调医疗大模型,与通用大模型效果对比

下面是一份CT描述&#xff1a; “肝脏大小、形态未见明确异常。肝S2见一结节状低密度影&#xff0c;大小约13x11mm&#xff0c;增强扫描呈明显渐进性强化&#xff0c;延迟期呈等密度。余肝实质内未见异常密度影或强化灶。肝内大血管及其分支走行未见异常&#xff0c;肝门区层次…

ip地址告诉别人安全吗?ip地址告诉别人会有什么风险

IP地址告诉别人安全吗&#xff1f;在数字化时代&#xff0c;IP地址作为网络连接的关键标识符&#xff0c;承载着重要的安全意义。然而&#xff0c;很多人可能并不清楚&#xff0c;轻易地将自己的IP地址告诉他人可能带来一系列安全风险。那么&#xff0c;IP地址告诉别人会有什么…

文件夹损坏0字节:全面解析、恢复技巧与预防策略

在数字时代&#xff0c;数据的完整性和安全性至关重要。然而&#xff0c;我们时常会遭遇文件夹损坏并显示为0字节的棘手问题。这种情况一旦发生&#xff0c;用户可能会面临数据丢失的风险。本文将详细探讨文件夹损坏0字节的现象&#xff0c;分析其背后的原因&#xff0c;并提供…

Redis-重定向

实验环境&#xff08;3主3从的Redis-Cluster&#xff09; 一、Redis重定向基础篇 1、MOVED重定向 Redis Custer 中&#xff0c;客户端可以向集群中任意节点发送请求。此时当前节点先对 Key 进行 CRC 16 计算&#xff0c;然后按 16384 取模确定 Slot 槽。确定该 Slot 槽所对应的…

为什么使用短链系统?

短链接&#xff08;Short Link&#xff09;是指将一个原始的长 URL&#xff08;Uniform Resource Locator&#xff09;通过特定的算法或服务转化为一个更短、易于记忆的 URL。短链接通常只包含几个字符&#xff0c;而原始的长 URL 可能会非常长。 短链接的原理非常简单&#x…

FPGA编程与PLC编程的区别:深入解析与对比

FPGA编程与PLC编程的区别&#xff1a;深入解析与对比 在工业自动化和控制系统领域&#xff0c;FPGA&#xff08;现场可编程门阵列&#xff09;编程和PLC&#xff08;可编程逻辑控制器&#xff09;编程都是关键的编程技术&#xff0c;但它们在应用、功能、结构和编程方法上存在…

IEEE编程语言排行榜:深度解析编程语言的四大维度、五大趋势、六大热门与七大挑战

IEEE编程语言排行榜&#xff1a;深度解析编程语言的四大维度、五大趋势、六大热门与七大挑战 在信息技术领域&#xff0c;编程语言排行榜一直是衡量各种编程语言流行度和影响力的重要指标。IEEE&#xff08;电气电子工程师协会&#xff09;作为全球最具影响力的科技专业组织之…

【Java数据结构】详解LinkedList与链表(二)

目录 1.❤️❤️前言~&#x1f973;&#x1f389;&#x1f389;&#x1f389; 2.反转一个单链表 3. 找到链表的中间节点 4.输入一个链表&#xff0c;输出该链表中倒数第k个结点。 5.合并两个有序链表 6.链表分割 7. 判定链表的回文结构 8.输入两个链表&#xff0c;找…