拦截Restful API的三种方式
如题, 方式有三种。
(1). 过滤器filter
javaEE规范
(2). 拦截器interceptor
springmvc提供
(3). 切片 aspect
一. Filter使用示例
import org.springframework.stereotype.Component; import javax.servlet.*;
import java.io.IOException; /**
* 使用@Component注解,该Filter就生效了。
* 还可以使用配置方式使用过滤生效 {@link FilterRegistrationBean}
*/
@Component
public class LoggerFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("LoggerFilter doFilter begin");
long startTime = System.currentTimeMillis();
filterChain.doFilter(servletRequest,servletResponse);
long endTime = System.currentTimeMillis();
System.out.println("used time :" + (endTime - startTime));
System.out.println("LoggerFilter doFilter end");
} @Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("LoggerFilter init...");
} @Override
public void destroy() {
System.out.println("LoggerFilter destroy...");
}
}
二. Interceptor使用示例
2.1 自定义一个拦截器
import org.springframework.stereotype.Component;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView; import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; /**
* 定义一个拦截器, 它会拦截所有的控制器,包括spring自带的控制器,诸如BasicErrorController.class
* 注意: interceptor与filter不同,仅仅使用一个@Component注解,该interceptor并不会生效
*/
@Component
public class LoggerInterceptor implements HandlerInterceptor {
/**
* 在进入controller方法之前调用
*
* @param handler : 就是启用的controller方法
* @return true: 执行下一个拦截器
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("LoggerInterceptor preHandle...");
request.setAttribute("startTime", System.currentTimeMillis());
HandlerMethod handlerMethod = (HandlerMethod) handler;
System.out.println("Controller类名:"+ handlerMethod.getBean().getClass().getName());
System.out.println("Controller方法名:"+ handlerMethod.getMethod().getName());
return true;
} /**
* 在执行完controller方法之后调用,如果controller方法抛出异常,则不会调用
*
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("LoggerInterceptor postHandle begin");
long startTime = (long) request.getAttribute("startTime");
System.out.println("used time :" + ( System.currentTimeMillis()-startTime));
System.out.println("LoggerInterceptor postHandle end");
} /**
* 在视图渲染之后调用,controller有无异常抛出,都会被调用
* @param ex 如果controller方法无异常抛出,ex 为null , 否则就是controller中抛出来的异常
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("LoggerInterceptor afterCompletion begin");
long startTime = (long) request.getAttribute("startTime");
System.out.println("used time :" + ( System.currentTimeMillis()-startTime));
System.out.println("LoggerInterceptor afterCompletion ex = " + ex);
System.out.println("LoggerInterceptor afterCompletion end");
}
}
2.2 注册拦截器
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import qinfeng.zheng.mockmvcdemo.interceptor.LoggerInterceptor; /**
* SpringBoot 1.X 使用WebMvcConfigurerAdapter.java即可,
* SpringBoot 2.x WebMvcConfigurerAdapter.java已过时了
*/
@Configuration
public class WebConfig implements WebMvcConfigurer { @Autowired
private LoggerInterceptor loggerInterceptor; /**
* 注册拦截器
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// registry.addInterceptor(new LoggerInterceptor());
registry.addInterceptor(loggerInterceptor);
}
}
三. 切片
/**
* 定义一个切片
*/
@Aspect
@Component
public class LoggerAspect {
/**
* 第一个 * : 方法的任意返回值
* 第二个 * : qinfeng.zheng.mockmvcdemo.controller.TestController类中的任意方法
* .. : 方法的任意参数
* @param pjp
* @return
*
* 参考: https://docs.spring.io/spring/docs/5.2.0.RELEASE/spring-framework-reference/core.html#aop 5.4.3
*/
@Around("execution(* qinfeng.zheng.mockmvcdemo.controller.TestController.*(..))")
public Object handle(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("LoggerAspect handle start...");
// 方法参数列表
Object[] args = pjp.getArgs();
Arrays.stream(args).forEach(x-> System.out.println(x));
long startTime = System.currentTimeMillis();
Object result = pjp.proceed();
System.out.println("used time :" + (System.currentTimeMillis() - startTime));
System.out.println("LoggerAspect handle end...");
return result;
}
}
四. 总结
Filter最弱,只能获取request对象
Interceptor,比Filter好,它不但能获取request对象 ,而且还能拿到HandlerMethoh对象,从而知道调用那个Controller ,以及具体的方法
Aspect,功能最强大,它可以获取Controller方法的方法的参数列表。。。。。
拦截Restful API的三种方式的更多相关文章
- Struts2访问Servlet API的三种方式
有时我们需要用到Request, Response, Session,Page, ServletContext这些我们以前常用的对象,那么在Struts2中怎么样使用到这些对象呢,通常有三种方式. * ...
- IntelliJ IDEA 2017版 spring-boot 拦截器的操作三种方式
一.注解方式 @WebServlet(urlPatterns = "/myServlet") public class MyServlet extends HttpServlet ...
- java:struts框架2(方法的动态和静态调用,获取Servlet API三种方式(推荐IOC(控制反转)),拦截器,静态代理和动态代理(Spring AOP))
1.方法的静态和动态调用: struts.xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCT ...
- 【百度地图API】关于如何进行城市切换的三种方式
原文:[百度地图API]关于如何进行城市切换的三种方式 摘要:本文介绍了三种切换城市的方式:查询城市.城市列表和显示城市轮廓. ------------------------------------ ...
- python 全栈开发,Day94(Promise,箭头函数,Django REST framework,生成json数据三种方式,serializers,Postman使用,外部python脚本调用django)
昨日内容回顾 1. 内容回顾 1. VueX VueX分三部分 1. state 2. mutations 3. actions 存放数据 修改数据的唯一方式 异步操作 修改state中数据的步骤: ...
- 【深入Struts2】获取ServletAPI的三种方式
一:获取servletAPI的三种方法 在传统的Web开发中,经常会用到Servlet API中的HttpServletRequest.HttpSession和ServletContext.Strut ...
- iOS字体加载三种方式
静态加载 动态加载 动态下载苹果提供的多种字体 其他 打印出当前所有可用的字体 检查某字体是否已经下载 这是一篇很简短的文章,介绍了 iOS 自定义字体加载的三种方式. 静态加载 这个可以说是最简单最 ...
- 【整理】Linux下中文检索引擎coreseek4安装,以及PHP使用sphinx的三种方式(sphinxapi,sphinx的php扩展,SphinxSe作为mysql存储引擎)
一,软件准备 coreseek4.1 (包含coreseek测试版和mmseg最新版本,以及测试数据包[内置中文分词与搜索.单字切分.mysql数据源.python数据源.RT实时索引等测 ...
- WPFの三种方式实现快捷键
最近,对wpf添加快捷键的方式进行了整理.主要用到的三种方式如下: 一.wpf命令: 资源中添加命令 <Window.Resources> <RoutedUICommand x:Ke ...
随机推荐
- Jmeter 上传下载文件
最近很多同学都在问jmeter上传.下载文件的脚本怎么做,要压测上传.下载文件的功能,脚本怎么做,网上查了都说的很含糊,这次呢,咱们就好好的把jmeter的上传下载文件好好缕缕,都整明白了,怎么个过程 ...
- P1541乌龟棋
传送 这题咋做? 当然是爆搜了. 但是蒟蒻不会爆搜(TLE,WA两开花qwq),更不会记忆化搜索,所以我们换个思路. 注意这句话: 这肯定是有用的(洛咕还不会闲圈到给一句毛用都没有的话),那它有什么用 ...
- .Net-WCF-图书:《WCF编程》
ylbtech-.Net-WCF-图书:<WCF编程> <WCF编程>是2008年1月机械工业出版社出版的图书,作者是Juval Lowy.Clemens Vasters. 1 ...
- 学院-成就学院:Academy of Achievement
ylbtech-学院-成就学院:Academy of Achievement 1.返回顶部 1. https://www.achievement.org/ 2. https://www.achieve ...
- 使用sqlalchemy创建单条数据-分层管理代码
这里主要是如何把整个流程的代码分层管理,方便维护 不拆分层次,整个流程顺下来的代码看这里:sqlAlchemy基本使用 项目结构: model.py用来描述表结构: from sqlalchemy i ...
- [SHOI2012] 火柴游戏
[SHOI2012] 火柴游戏 [题目链接] 链接 [思路要点] 首先发现移动火柴操作可以放到最后做.每一次移动火柴一定可以看做是添加一根火柴再删除一根火柴,并且可以将任意一次添加和一次删除操作合并为 ...
- Scala函数高级操作
字符串高级操作:***** 非常重要 将函数赋值给变量/值def sayHello(name:String): Unit = { println(s"Hello:$name")} ...
- BZOJ 4675(点分治)
题面 传送门 分析 由于期望的线性性,我们可以分别计算每个点对对答案的贡献 有三个人取数字,分开对每个人考虑 设每个人分别取了k个数,则一共有\(C_n^k\)种组合,选到每种组合的概率为\(\fra ...
- jenkinsapi和python打包工具的安装日志
Successfully installed PyInstaller-3.3.1 altgraph-0.15 dis3-0.1.2 future-0.16.0 macholib-1.9 pefile- ...
- JVM中类加载器的父委托机制
类加载器 类加载器用来把类加载到Java虚拟机中. 类加载器的类型 有两种类型的类加载器: 1.JVM自带的加载器: 根类加载器(Bootstrap) 扩展类加载器(Extension) 系统类加载器 ...