一,filter/interceptor/aop在获取参数上有什么区别?

1,filter可以修改HttpServletRequest的参数(doFilter方法的功能),

interceptor/aop都没有这个功能

但它不提供到被过滤的方法的访问

注意区分请求request的方法

2, interceptor能得到所拦截的方法名和参数名,

不能得到参数值,

interceptor的postHandle方法能得到ModelAndView参数,

用来处理模板的公共参数,把页面的公共内容传递给模板

3, aspect(Aop)能得到注解所在方法的方法名和参数名、参数值,

还可以修改方法的参数值

另外:

filter/interceptor都是针对请求,

aop则是针对方法

看代码,有更直观的感受

说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectforest

对应的源码可以访问这里获取: https://github.com/liuhongdi/

说明:作者:刘宏缔 邮箱: 371125307@qq.com

二,演示项目的相关信息

1,项目地址

https://github.com/liuhongdi/filterinterceptoraop

2,项目原理:

我们在controller中的一个方法上,

添加了filter/interceptor/aspect

然后比较我们能得到哪些参数,对参数做哪些处理?

3,项目结构:

如图:

三,java代码说明:

1,ParamFilter.java

@Component
public class ParamFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("----------------filter init");
}
//过滤功能
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("----------------filter doFilter begin");
//打印得到的request参数
Enumeration paramNames = servletRequest.getParameterNames();
while (paramNames.hasMoreElements()) {
String paramName = (String) paramNames.nextElement();
String[] paramValues = servletRequest.getParameterValues(paramName);
if (paramValues.length == 1) {
String paramValue = paramValues[0];
if (paramValue.length() != 0) {
System.out.println("[filter] request parameter name:"+paramName+";value:"+paramValue);
}
}
}
//修改请求参数
HashMap m = new HashMap(servletRequest.getParameterMap());
m.put("newp", new String[] { "abcd" });
m.put("v", new String[] { "filterv" });
HttpServletRequest req = (HttpServletRequest) servletRequest;
CustomRequestWrapper wrapRequest = new CustomRequestWrapper(req, m);
servletRequest = wrapRequest;
filterChain.doFilter(servletRequest, servletResponse);
} @Override
public void destroy() {
System.out.println("----------------filter destroy");
}
}

说明:filter中可以修改request参数,

但不能对方法进行访问

2,ValidateorInterceptor.java

@Component
public class ValidatorInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("---------------interceptor begin"); //打印request参数
Enumeration<?> temp = request.getParameterNames();
if (null != temp) {
while (temp.hasMoreElements()) {
String en = (String) temp.nextElement();
String value = request.getParameter(en);
System.out.println("[interceptor] request parameters: name:"+en+";value:"+value);
}
} //打印method的相关信息
if(handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
// 获取处理当前请求的 handler 信息
System.out.println("[interceptor] method 类名:" + handlerMethod.getBeanType().getName());
System.out.println("[interceptor] method 方法:" + handlerMethod.getMethod().getName()); MethodParameter[] methodParameters = handlerMethod.getMethodParameters();
for (MethodParameter methodParameter : methodParameters) {
// 只能获取参数的名称,type,index,不能获取到参数的值
System.out.println("[interceptor] method parameter Name: " + methodParameter.getParameterName());
System.out.println("[interceptor] method parameter Type: " + methodParameter.getParameterType());
System.out.println("[interceptor] method parameter Index: " + methodParameter.getParameterIndex());
}
}
//sign校验无问题,放行
return true;
} @Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
} @Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}

说明:interceptor中,只能得到方法的参数名,不能得到参数值

3,RedisRateLimiterAspect.java

@Component
@Aspect
public class RedisRateLimiterAspect {
@Pointcut("@annotation(com.filterinterceptoraop.demo.annotation.RedisRateLimiter)")
private void pointcut() {} /*
* around,
* if reach limit in time
* return error info
* */
@Around(value = "pointcut()")
public Object requestLimit(ProceedingJoinPoint joinPoint) throws Exception {
System.out.println("---------------aop begin");
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest();
//打印request参数
Enumeration<?> temp = request.getParameterNames();
if (null != temp) {
while (temp.hasMoreElements()) {
String en = (String) temp.nextElement();
String value = request.getParameter(en);
System.out.println("[aop] request parameter name:"+en+";value:"+value);
}
} //打印方法的信息
Object[] args = joinPoint.getArgs();
try {
Signature signature = joinPoint.getSignature();
MethodSignature methodSignature = (MethodSignature)signature;
//获取目标方法
Method targetMethod = methodSignature.getMethod();
String method_name = targetMethod.getName();
System.out.println("[aop] method name:"+method_name);
String[] paramNames = methodSignature.getParameterNames(); Map<String, Object> nameAndArgs = new HashMap<String, Object>();
for (int i = 0; i < paramNames.length; i++) {
nameAndArgs.put(paramNames[i], args[i]);// paramNames即参数名
if (paramNames[i].equals("version")) {
//System.out.println("version value:"+args[i]);
args[i] = "aopv";
}
System.out.println("[aop] method parameter name:"+paramNames[i]+";value:"+args[i]);
} if (targetMethod.isAnnotationPresent(RedisRateLimiter.class)) {
return joinPoint.proceed(args);
} else {
return joinPoint.proceed();
}
} catch (Throwable e) {
e.printStackTrace();
return null;
}
}
}

说明:aop中,可以得到方法的参数名和参数值,而且还可以修改方法的参数值

四,测试效果

1,访问url:

http://127.0.0.1:8080/home/home?v=1

然后查看控制台的输出

2,filter的输出

----------------filter doFilter begin
[filter] request parameter name:v;value:1

filter中我们得到了正确的request参数值

3,interceptor的输出

---------------interceptor begin
[interceptor] request parameters: name:v;value:filterv
[interceptor] request parameters: name:newp;value:abcd
[interceptor] method 类名:com.filterinterceptoraop.demo.controller.HomeController
[interceptor] method 方法:homeMethod
[interceptor] method parameter Name: version
[interceptor] method parameter Type: class java.lang.String
[interceptor] method parameter Index: 0
[interceptor] method parameter Name: httpServletRequest
[interceptor] method parameter Type: interface javax.servlet.http.HttpServletRequest
[interceptor] method parameter Index: 1
[interceptor] method parameter Name: httpServletResponse
[interceptor] method parameter Type: interface javax.servlet.http.HttpServletResponse
[interceptor] method parameter Index: 2
[interceptor] method parameter Name: modelMap
[interceptor] method parameter Type: class org.springframework.ui.ModelMap
[interceptor] method parameter Index: 3

请求参数v的值变成了filterv,而且增加了一个请求参数:newp,

这是filter中代码的作用

可以看到:interceptor得到了它所拦截请求对应的方法名和参数名,

但没有方法的参数值,它也不能修改request的参数和方法的参数

4,aop的输出:

---------------aop begin
[aop] request parameter name:v;value:filterv
[aop] request parameter name:newp;value:abcd
[aop] method name:homeMethod
[aop] method parameter name:version;value:aopv
[aop] method parameter name:httpServletRequest;value:com.filterinterceptoraop.demo.wrapper.CustomRequestWrapper@1ce466d8
[aop] method parameter name:httpServletResponse;value:org.apache.catalina.connector.ResponseFacade@45eedc13
[aop] method parameter name:modelMap;value:{}

aop中的请求参数没有变,

它可以得到方法的参数名和参数值,

在这里我们修改参数version的值为 aopv

5,controller中的输出:

---------------controller begin
[controller] request parameter name:v;value:filterv
[controller] request parameter name:newp;value:abcd
[controller] method parameter version:aopv

controller中接收到的方法的参数值是我们在aop中修改过的

五,查看spring boot版本

  .   ____          _            __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.3.1.RELEASE)

spring boot: filter/interceptor/aop在获取request/method参数上的区别(spring boot 2.3.1)的更多相关文章

  1. spring aop 中获取 request

    使用aop时需要request 和response 使用方法调用时 HttpServletRequest request = ((ServletRequestAttributes)RequestCon ...

  2. Spring MVC(三)控制器获取页面请求参数以及将控制器数据传递给页面和实现重定向的方式

    首先做好环境配置 在mvc.xml里进行配置 1.开启组件扫描 2.开启基于mvc的标注 3.配置试图处理器 <?xml version="1.0" encoding=&qu ...

  3. Java开发学习(十八)----AOP通知获取数据(参数、返回值、异常)

    前面的博客我们写AOP仅仅是在原始方法前后追加一些操作,接下来我们要说说AOP中数据相关的内容,我们将从获取参数.获取返回值和获取异常三个方面来研究切入点的相关信息. 前面我们介绍通知类型的时候总共讲 ...

  4. flask中获取request的参数的方法

    request请求总体分为两类: 1.get请求 访问时会在地址栏直接显示参数不安全,且参数大小比较小. 2.post请求 参数不显示在地址栏,一般用户注册.登录都通过post请求完成. flask获 ...

  5. Spring Boot在aop中获取request对象

    doBefore(){ ServetRequestAttrbtes attributes = (ServetRequestAttrbtes)RequestContextHolder.getHttpat ...

  6. Filter ,Interceptor,AOP

    一.Filter: Filter也称之为过滤器,它是Servlet技术中比较激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态 ...

  7. 使用JavaScript获取Request中参数的值

    本人很少写博客,有不正确的地方还希望大家多多指导. 假设现在有一个URL,如下. http://www.jacky.com/?id=1101&name=jacky 如何通过JS访问到id和na ...

  8. 43. Spring Boot动态数据源(多数据源自动切换)【从零开始学Spring Boot】

    [视频&交流平台] àSpringBoot视频 http://study.163.com/course/introduction.htm?courseId=1004329008&utm ...

  9. java获取request中的参数、java解析URL问号后的参数

    java获取request中的参数.java解析URL问号后的参数.有时候我们需要从request中获取参数,或者获取拼接在Url后面的参数,有时候一个一个去拿有点麻烦,一起拿出来放在一个map里面需 ...

随机推荐

  1. numpy函数笔记(持续更新)

    numpy函数笔记 np.isin用法 np.isin(a,b) 用于判定a中的元素在b中是否出现过,如果出现过返回True,否则返回False,最终结果为一个形状和a一模一样的数组.(注意:这里的a ...

  2. jmeter的用途

    1.可以测接口 2.测试连数据库 3.可以进行压测 4.可部署分布式

  3. 抓包工具Burp Suite安装步骤(待补充)

    Burp Suite V2.1(破解版)安装步骤:(可以自行下载破解版或汉化版) 百度网盘下载地址: 链接:https://pan.baidu.com/s/1bU5JME3OsEsXrSirTdesR ...

  4. 本周 GitHub 速览:自动化当道,破密、爬虫各凭本事

    作者:HelloGitHub-小鱼干 摘要:安全门外汉,如何在不知道密钥或密码的情况下,破解哈希得到原文,Ciphey 会告诉你当中的密码.说到 auto 智能爬虫会基于上一次的爬虫经历进一步学习以获 ...

  5. 国产化之路-麒麟V10操作系统安装.net core 3.1 sdk

    随着芯片国产化,操作系统国产化,软件国产化的声浪越来越高,公司也已经把开发项目国产化提上了日程,最近搞来了台长城的国产化电脑主机,用来搞试验,安装的是麒麟V10的操作系统,国产化折腾之路就此开始,用的 ...

  6. 使用Jasmine和karma对传统js进行单元测试

    当你拿到十五年前的一堆javascript的代码,你如何对这堆javascript代码写单元测试呢?于是就有了这篇文章. 注意:不需要装任何现代化js框架,包括angular,react,vue之类的 ...

  7. input输入框 只能输入数字 oninput = "value=value.replace(/[^\d]/g,'')" input输入框输入大于0的数字 oninput="value=value.replace(/\D|^0/g,'')"

    项目中因为利用 element-ui 和avue两个ui框架搭建的 1.利用element-ui自带的校验需要注意点 prop  :rules ref这三个属性 2.利用oninput时间进行校验   ...

  8. java基础整理总结篇(1)

    >>java数据区域,大致分以下几种 寄存器:位于cpu内部,寄存器的数量有限,所以寄存器根据需求分配.不能直接控制它. 堆栈:位于通用RAM(随机访问存储器)中,通过堆栈指针可以从处理器 ...

  9. 基于bellman-ford算法使用队列优化的spfa求最短路O(m),最坏O(n*m)

    acwing851-spfa求最短路 #include<iostream> #include<cstring> #include<algorithm> #inclu ...

  10. Dubbo工作流程

    一.dubbo整体架构 其中Service 和 Config 层为 API,对应服务提供方来说是使用ServiceConfig来代表一个要发布的服务配置对象,对应服务消费方来说ReferenceCon ...