如题, 方式有三种。

(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. weilaiqiche

    <!DOCTYPE html><html lang="en"> <head> <meta http-equiv="Content ...

  2. PageObject设计模式 在selenium 自动化测试里面的应用

    PageObject设计模式1. Web自动化测试框架(WebTestFramework)是基于Selenium框架且采用PageObject设计模式进行二次开发形成的框架. 2. web测试时,建议 ...

  3. 【转载】Spring Boot:常用属性汇总

    附录A.常用应用程序属性 摘自:https://docs.spring.io/spring-boot/docs/current/reference/html/common-application-pr ...

  4. Cookie 记录最后访问时间

    package cn.gs.ly.servlet; import java.io.IOException; import java.io.PrintWriter; import java.util.D ...

  5. virtualenv-windows下排坑

    1. 安装 pip install virtualenv pip install virtualenvwrapper-win    (win下一定要有这个 -win,不然后续 workon,mkvir ...

  6. debian7下安装eclipse

    apt-get install build-essential 完成后从eclipse官网上下载C++专用的版本,直接解压缩即可

  7. 利用多态,简易实现电脑usb连接设备案例

    package cn.learn.Practice03; public interface UsbInterface { void open(); //打开usb void close(); //关闭 ...

  8. 洛谷 P1440 求m区间内的最小值(单调队列)

    题目链接 https://www.luogu.org/problemnew/show/P1440 显然是一道单调队列题目…… 解题思路 对于单调队列不明白的请看这一篇博客:https://www.cn ...

  9. python学习第五天流程控制分支if和循环while

    所有的逻辑结构围绕分支和循环进行,比如登陆注册,支付成功与否等等,下面讲述分支if用法和while用法 if age>30: print("www.96net.com.cn" ...

  10. CSRF相关

    CSRF原理 第一次获取页面的时候浏览器返回一个随机字符串,之后提交数据的时候需要把到这个字符串去提交,不然会报错 返回的时候还会把这个字符串放到cookie里面, 使用form提交时候: {% cs ...