如题, 方式有三种。

(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. http请求方法,get 对比 post

    本文转自:http://www.w3school.com.cn/tags/html_ref_httpmethods.asp 两种最常用的 HTTP 方法是:GET 和 POST. 什么是 HTTP? ...

  2. 实验1 C语言开发环境...

    #include<stdio.h> int main(){ int days; printf("输入一个整数:\n") ; scanf("%d",& ...

  3. 10.jmeter jsr223 javascript 深度比对json object

    function sortJSON(data, key, way) { //log.info(" " + key + " ------------------- &quo ...

  4. JS原型链详解

    最近面试被问到了就决定好好深入理解原型链 对象 要清楚原型链,首先要弄清楚对象: 普通对象 最普通的对象:有__proto__属性(指向其原型链),没有prototype属性. 原型对象(person ...

  5. Kubernetes V1.16.2部署Dashboard V2.0(beta5)

    Kubernetes V1.16.2部署Dashboard V2.0(beta5) 在Master上部署Dashboard 集群安装部署请看安装Kubernetes V1.16.2 kubectl g ...

  6. Cnblogs 的 MetaWeblog 的接口发生了变化

    Cnblogs 的 MetaWeblog 的接口发生了变化 */--> Cnblogs 的 MetaWeblog 的接口发生了变化 最近把 emacs 重新配置了一下,把 cnblogs 包也重 ...

  7. django的配置

    1.django的默认配置 import os # Build paths inside the project like this: os.path.join(BASE_DIR, ...) # 获取 ...

  8. Mybatis-技术专区-中的条件查询createCriteria example里面的条件

    之前用Mybatis框架反向的实体,还有实体里面的Example,之前只是知道Example里面放的是条件查询的方法,可以一直不知道怎么用,到今天才开始知道怎么简单的用. 在我们前台查询的时候会有许多 ...

  9. C# 面试 笔试题

    1.简述 private. protected. public. internal.protected internal 访问修饰符和访问权限 private : 私有成员, 在类的内部才可以访问. ...

  10. Java 8实战之读书笔记一:内容简介

    本书的主要内容如下:  如何使用Java 8新增的强大特性  如何编写能有效利用多核架构的程序  重构.测试和调试  怎样高效地应用函数式编程 目录: 第一部分 基础知识 第1 章 为什么要关心Jav ...