JAVA拦截器的三种实现方式

news/2024/10/21 19:29:38/

JAVA拦截器的三种实现方式

javaFilter_1">一、java原生过滤器Filter

javascript">/*** 自定义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拦截器

javascript">/*** 自定义拦截器* 自定义拦截器后,需要配置进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:

javascript"><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.4</version>
</dependency>
javascript">/*** @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.ppmy.cn/news/1465916.html

相关文章

【火猫欧洲杯】意甲:孔蒂亲自推动,送走尼日利亚锋霸

本赛季那不勒斯作为卫冕冠军发挥不佳,联赛仅仅排在第10名,休赛期他们率先炒掉了主帅卡尔佐纳,基本上锁定了前国米主帅孔蒂。孔蒂对于执教那不勒斯也非常期待,根据意大利媒体爆料,孔蒂已经开始准备推动转会,将球队的进攻核心奥斯梅恩卖掉,如果可以他想将自己的爱将卢卡库换回来。…

git都在自己的个人分支开发吗?功能分支和个人分支工作流

在实际的开发过程中&#xff0c;使用分支的策略可以根据项目的需求和团队的工作流程进行调整。以下是两种常见的分支策略&#xff1a; 1. 功能分支&#xff08;Feature Branches&#xff09; 每个功能或修复一个独立的分支。这种方法通常被称为“功能分支工作流”。 优点 隔…

burp插件new_xp_capcha识别验证码的简易安装

1.new_xp_capcha 插件是大佬开发的可以正常白嫖&#xff0c;感谢大佬&#xff0c;我找了个不需要任何高级操作就可以做的安装手法&#xff0c;因为我在网上搜了一下就发现这个的安装过程攻略都还蛮复杂&#xff0c;我这里用了个简单的手法 2.安装 下载地址&#xff1a;smxia…

fintuning chatglm3

chatglm3介绍 ChatGLM3-6B 是 ChatGLM 系列最新一代的开源模型&#xff0c;在保留了前两代模型对话流畅、部署门槛低等众多优秀特性的基础上&#xff0c;ChatGLM3-6B 引入了如下特性&#xff1a; 更强大的基础模型&#xff1a; ChatGLM3-6B 的基础模型 ChatGLM3-6B-Base 采用…

After Effects 2022(AE2022)支持win版和mac版下载

​After Effects 2022 是由Adobe公司推出的一款专业视频后期制作软件&#xff0c;它主要用于视频合成、视频特效制作、视频剪辑、动画制作等领域。After Effects 2022 内置了丰富的特效和过渡效果&#xff0c;用户可以通过它进行高级的视频合成和动画制作。 该软件具有直观的用…

基于Vue uni-app的自定义列表表格信息展示组件

摘要&#xff1a;随着软件技术的不断发展&#xff0c;前端开发面临着越来越多的挑战。特别是在业务场景复杂多变的情况下&#xff0c;如何提高开发效率和降低维护成本成为了关键。本文旨在探讨组件化开发在前端应用中的重要性&#xff0c;并以Vue uni-app自定义列表表格为例&am…

前端命令行部署

最近接了一个项目&#xff0c;发版本需要把dist包给后端部署服务&#xff0c;再加上产品那边需求不稳定&#xff0c;改了又改&#xff0c;一天要发好几个&#xff0c;不仅跟我配合的后端不胜其烦&#xff0c;本人也是很烦。最近在网上看到一个npm自主部署的包–deploy cli工具&…

R可视化:可发表的prism点图

介绍 可发表的prism点图 加载R包 knitr::opts_chunk$set(echo = TRUE, message = FALSE, warning = FALSE) library(tidyverse) library(ggpubr) library(ggprism)rm(list = ls()) options(stringsAsFactors = F)导入数据 data("iris")head(iris)处理数据 plotd…