如题, 方式有三种。

(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. docker 搭建gitlab

    https://docs.gitlab.com/omnibus/docker/ https://blog.csdn.net/m0_37444820/article/details/81147452 h ...

  2. MySQL常用SQL(含复杂SQL查询)

    1.复杂SQL查询 1.1.单表查询 (1)选择指定的列 [例]查询全体学生的学号和姓名 select Sno as 学号,Sname as 姓名 from student; select Sno,S ...

  3. 实验吧 Web的WriteUp

    每次看别人的Writeup都有一种感觉,为什么有了WriteUp我还是不会,每次都打击自己的积极性,所以自己尝试写一篇每个萌新都能看懂的Writeup. 0x01 天下武功唯快不破 题目提示 : 看看 ...

  4. Spring中两种引入配置文件方式

    用过Spring的人都知道,我们一般把数据库的配置.日志的配置或者其他的通用配置放在单独的配置文件中,在和Spring整合时,一般通过以下两种方法引入: <context:property-pl ...

  5. .NET简单三层的理解

    1.UI 表示层 :就是我们看到的网站前台2.BLL 业务逻辑层:很简单 也很重要 处理逻辑问题 简单程序看不出啥效果3.DAL 数据访问层: 写数据连接和执行的SQL语句4.MODEL 模型层:封装 ...

  6. JS动态添加Easyui的HTML时样式丢失

    解决办法: $.parser.parse($("#creatLi").html(<li>xxxxxx</li>)); ------------------- ...

  7. Django csrf,xss,sql注入

    一.csrf跨站请求伪造(Cross-site request forgery) CSRF的攻击原理:简单说就是利用了高权限帐号(如管理员)的登录状态或者授权状态去做一些后台操作,但实际这些状态并没有 ...

  8. python-生成式的基本使用

    生成式是python中的一种高级玩法,起码看起来显得要高级一点.它可以使用简单的一行代码实现列表.字典等数据类型的创建或数据类型的转换等任务.另外,它和生成器还有些许关联. 列表生成式 列表生成式即生 ...

  9. 记一次Laravel 定时任务schedul:run未执行的处理

    关于Laravel的任务调度(定时任务)的配置在此不做赘述,跟着官方文档一步一步的操作是不会导致定时任务不能正常工作的. 为保证能及时捕获定时任务执行出现异常的原因,只需在配置系统crontab时指定 ...

  10. HDFS-NameNode和SeconddaryNode

    一.NN和2N的工作机制 一.概述 一.概述 一.概述 一.概述 一.概述 一.概述 一.概述