如题, 方式有三种。

(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的三种方式的更多相关文章

  1. Struts2访问Servlet API的三种方式

    有时我们需要用到Request, Response, Session,Page, ServletContext这些我们以前常用的对象,那么在Struts2中怎么样使用到这些对象呢,通常有三种方式. * ...

  2. IntelliJ IDEA 2017版 spring-boot 拦截器的操作三种方式

    一.注解方式 @WebServlet(urlPatterns = "/myServlet") public class MyServlet extends HttpServlet ...

  3. java:struts框架2(方法的动态和静态调用,获取Servlet API三种方式(推荐IOC(控制反转)),拦截器,静态代理和动态代理(Spring AOP))

    1.方法的静态和动态调用: struts.xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCT ...

  4. 【百度地图API】关于如何进行城市切换的三种方式

    原文:[百度地图API]关于如何进行城市切换的三种方式 摘要:本文介绍了三种切换城市的方式:查询城市.城市列表和显示城市轮廓. ------------------------------------ ...

  5. python 全栈开发,Day94(Promise,箭头函数,Django REST framework,生成json数据三种方式,serializers,Postman使用,外部python脚本调用django)

    昨日内容回顾 1. 内容回顾 1. VueX VueX分三部分 1. state 2. mutations 3. actions 存放数据 修改数据的唯一方式 异步操作 修改state中数据的步骤: ...

  6. 【深入Struts2】获取ServletAPI的三种方式

    一:获取servletAPI的三种方法 在传统的Web开发中,经常会用到Servlet API中的HttpServletRequest.HttpSession和ServletContext.Strut ...

  7. iOS字体加载三种方式

    静态加载 动态加载 动态下载苹果提供的多种字体 其他 打印出当前所有可用的字体 检查某字体是否已经下载 这是一篇很简短的文章,介绍了 iOS 自定义字体加载的三种方式. 静态加载 这个可以说是最简单最 ...

  8. 【整理】Linux下中文检索引擎coreseek4安装,以及PHP使用sphinx的三种方式(sphinxapi,sphinx的php扩展,SphinxSe作为mysql存储引擎)

          一,软件准备 coreseek4.1 (包含coreseek测试版和mmseg最新版本,以及测试数据包[内置中文分词与搜索.单字切分.mysql数据源.python数据源.RT实时索引等测 ...

  9. WPFの三种方式实现快捷键

    最近,对wpf添加快捷键的方式进行了整理.主要用到的三种方式如下: 一.wpf命令: 资源中添加命令 <Window.Resources> <RoutedUICommand x:Ke ...

随机推荐

  1. 简单了解winform

    WinForm是·Net开发平台中对Windows Form的一种称谓. Windows窗体可用于设计窗体和可视控件,以创建丰富的基于Windows的窗体应用程序.可以访问数据库中的数据,并在窗体上显 ...

  2. jmeter之JDBC请求

    jmeter不仅可以测试http请求,也可以执行JDBC请求的测试.本次以mysql为例,介绍JDBC请求如何完成发送 目录 1.环境配置 2.数据库连接配置 3.添加一个JDBC请求 1.环境配置 ...

  3. Jmeter接口测试报告模板优化

    优化后在接口报告的接口信息中,直接展示url,method,结果和响应时间,详情中展示请求和响应数据.具体如下: 模板文件 jmeter-results-detail-report_21.xsl: & ...

  4. IoC与DI,Unity的使用

    IoC的全称为Inversion of Control(控制反转),DI的全称为Dependency Injection(依赖注入).IoC是一个控制容器,我们将设计好的对象放入到容器中,将对象交给容 ...

  5. ELK 日志系统入门及通过 Docker 部署

    1. ELK 系统是什么 ELK 是一套日志中心解决方案,其三个字母分别表示: Elasticsearch:负责日志存储及检索 Logstash:负责日志收集.过滤及格式化 Kibana:数据看板,负 ...

  6. Zookeeper---作为服务注册中心

    认识Zookeeper是一套分布式协调服务. 优点: 简单:与文件系统类似,Znode的组织方式. 多副本:一般再线上都是三副本或者五副本的形式,最少会有三个节点. 有序:有序的操作,根据时间戳进行排 ...

  7. [Codeforces 280D]k-Maximum Subsequence Sum(线段树)

    [Codeforces 280D]k-Maximum Subsequence Sum(线段树) 题面 给出一个序列,序列里面的数有正有负,有两种操作 1.单点修改 2.区间查询,在区间中选出至多k个不 ...

  8. 针对三星Exynos CPU Root漏洞

    因为系统为了保护这些符号地址泄露,而用的一种保护手段,从而使除root用户外的普通用户不能直接查看符号地址: 原因在于内核文件kallsyms.c中的显示符号地址命令中做了如下限制: seq_prin ...

  9. Warning: session_start(): open(/var/lib/php/session/)

    Warning: session_start(): open(/var/lib/php/session/) 今天放置一个新的站点www.96net.com.cn在里面,登陆后台出现这种错,之后再lin ...

  10. 上传.cgi在252板子上跑

    1.windows下写好.c程序 2.进入linux,准备交叉编译 arm-hisiv600-linux-gcc -g -Wall -o xxx.cgi xxx.c(交叉编译工具取决于板子) 3.把. ...