springboot拦截提⽰_SpringBoot过滤器和
aop使⽤总结
根据实现原理分成下⾯两⼤类:
Filter和Listener:依赖Servlet容器,基于函数回调实现。可以拦截所有请求,覆盖范围更⼴,但⽆法获取ioc容器中的bean。
Interceptor和aop:依赖spring框架,基于java反射和动态代理实现。只能拦截controller的请求,可以获取ioc容器中的bean。
执⾏顺序:
Filter > Listener > Interceptor > aop
:listener是servlet规范中定义的⼀种特殊类。⽤于监听servletContext、HttpSession和servletRequest等域对象的创建和销毁
事件。监听域对象的属性发⽣修改的事件。⽤于在事件发⽣前、发⽣后做⼀些必要的处理。其主要可⽤于以下⽅⾯:1、统计在线⼈数和在
线⽤户2、系统启动时加载初始化信息3、统计⽹站访问量4、记录⽤户访问路径。
过滤器:Filter是Servlet技术中最实⽤的技术,Web开发⼈员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态
图⽚⽂件或静态 html ⽂件等进⾏拦截,从⽽实现⼀些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等⼀
些⾼级功能。它主要⽤于对⽤户请求进⾏预处理,也可以对HttpServletResponse进⾏后处理。使⽤Filter的完整流程:Filter对⽤户请求
进⾏预处理,接着将请求交给Servlet进⾏处理并⽣成响应,最后Filter再对服务器响应进⾏后处理。
:Interceptor 在AOP(Aspect-Oriented Programming)中⽤于在某个⽅法或字段被访问之前,进⾏拦截然后在之前或之后加⼊某
些操作。⽐如⽇志,安全等。⼀般⽅法都是通过动态代理的⽅式实现。可以通过它来进⾏权限验证,或者判断⽤户是否登陆,或者是
像12306 判断当前时间是否是购票时间。
⼀:过滤器(可通过配置类或者注解两种⽅式实现)
1,通过配置类来实现,在只实现过滤器的接⼝,并不需要通过任何注解注⼊IOC容器,都通过配置类来注⼊。
packagecom.chitic.supplywatermon.aop;import
javax.servlet.*;importjavax.servlet.annotation.WebFilter;importjava.io.IOException;/*** @Description //TODO
* @Author GaoX
* @Date 2020/9/16 8:55*/
//@WebFilter(filterName = "myFilter",urlPatterns = {"/*"})
public class AFilter implementsFilter {
@Overridepublic void init(FilterConfig filterConfig) throwsServletException {
}
@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throwsIOException, ServletException {
}
@Overridepublic voiddestroy() {
}
}
注册过滤器
importorg.springframework.boot.web.servlet.FilterRegistrationBean;t.annotation.Bean;import
@Configurationpublic classFilterConfig {
@BeanpublicFilterRegistrationBean AFilter() {
FilterRegistrationBean filterRegistrationBean= newFilterRegistrationBean();
AFilter aFilter=newAFilter();
filterRegistrationBean.setFilter(aFilter);
filterRegistrationBean.addUrlPatterns("*");
filterRegistrationBean.setName("AFilter");
filterRegistrationBean.setOrder(1);returnfilterRegistrationBean;
}
@BeanpublicFilterRegistrationBean BFilter() {
FilterRegistrationBean filterRegistrationBean= newFilterRegistrationBean();
BFilter bFilter=newBFilter();
filterRegistrationBean.setFilter(bFilter);
filterRegistrationBean.addUrlPatterns("*");
filterRegistrationBean.setName("BFilter");
filterRegistrationBean.setOrder(2);returnfilterRegistrationBean;
}
}
2,注解⽅式
@WebFilter(filterName = "myFilter",urlPatterns = {"/*"})
启动类@ServletComponentScan
⼆:(可通过配置类或者注解两种⽅式实现)
Listener也是Servlet层⾯的,可以⽤于监听Web应⽤中某些对象、信息的创建、销毁和修改等动作发⽣,然后做出相应的响应处
理。根据监听对象,将分为3类:
spring ioc注解ServletContextListener:对应application,实现接⼝ServletContextListener。在整个Web服务中只有⼀个,在Web服务关闭时销
毁。可⽤于做数据缓存,例如结合redis,在Web服务创建时从数据库拉取数据到缓存服务器。
HttpSessionListener:对应session会话,实现接⼝HttpSessionListener。在会话起始时创建,⼀端关闭会话后销毁。可⽤作获取在线
⽤户数量。
ServletRequestListener:对应request,实现接⼝ServletRequestListener。request对象是客户发送请求时创建的,⽤于封装请求数
据,请求处理完毕后销毁。可⽤作封装⽤户信息。
packagecom.chitic.supplywatermon.aop;importjavax.servlet.annotation.WebListener;importjavax.servlet.http.HttpSessionEv @Description //TODO
* @Author GaoX
* @Date 2020/9/16 8:54*/
//@WebListener
public class listener1 implementsHttpSessionListener {private int count = 0;
@Overridepublic voidsessionCreated(HttpSessionEvent se) {
count++;
System.out.println("新增在线⼈数,当前在线⼈数:"+count);
}
@Overridepublic voidsessionDestroyed(HttpSessionEvent se) {
count--;
System.out.println("删减在线⼈数,当前在线⼈数:"+count);
}
}
注册
packagecom.chitic.supplywatermon.aop;importorg.springframework.boot.web.servlet.ServletListenerRegistrationBean;impo classMyListener {
@BeanpublicServletListenerRegistrationBean listenerRegist() {
ServletListenerRegistrationBean srb= newServletListenerRegistrationBean();
srb.setListener(newlistener1());
System.out.println("listener");returnsrb;
}
}
三:(Interceptor)
Interceptor和Filter和Listener有本质上的不同,前⾯⼆者都是依赖于Servlet容器,⽽Interceptor则是依赖于Spring框架,是aop
的⼀种表现,基于Java的动态代理实现的。
声明的类:1,通过实现 HandlerInterceptor接⼝;2,继承HandlerInterceptorAdapter类; 实现preHandle、postHandle和afterCompletion⽅法。
通过配置类配置:通过实现WebMvcConfigurer接⼝,实现addInterceptors⽅法。
packagecom.chitic.supplywatermon.aop;importorg.springframework.lang.Nullable;importorg.springframework.web.servlet.M @Description //TODO
* @Author GaoX
* @Date 2020/9/16 8:54*/
public class HandlerInterceptorAdapter1 extendsHandlerInterceptorAdapter {/*** This implementation always returns
{@codetrue}.*/@Overridepublic booleanpreHandle(HttpServletRequest request, HttpServletResponse response, Object handler)throwsException {return true;
}/*** This implementation is empty.*/@Overridepublic voidpostHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable ModelAndView modelAndView)throwsException {
}/*** This implementation is empty.*/@Overridepublic voidafterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler,
@Nullable Exception ex)throwsException {
}/*** This implementation is empty.*/@Overridepublic voidafterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response,
Object handler)throwsException {
}
}
注册
packagecom.chitic.supplywatermon.aop;t.annotation.Configuration;importorg.springfra
@Configurationpublic class MywebConfig implementsWebMvcConfigurer {
@Overridepublic voidaddInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(newHandlerInterceptorAdapter1())
.addPathPatterns("/**");
}
}
四:aop
相⽐较于,Spring 的aop则功能更强⼤,封装的更细致,需要单独引⽤ jar包。
org.springframework.boot
spring-boot-starter-aop
在定义AOP的类时,不需要和前⾯⼀样⿇烦了,只需要通过注解,底层实现逻辑都通过IOC框架实现好了,涉及到的注解如下:
@Aspect:将⼀个 java 类定义为切⾯类。
@Pointcut:定义⼀个切⼊点,可以是⼀个规则表达式,⽐如下例中某个 package 下的所有函数,也可以是⼀个注解等。
@Before:在切⼊点开始处切⼊内容。
@After:在切⼊点结尾处切⼊内容,⽆论是否有异常,都会执⾏,类似于finally。
@AfterReturning:在切⼊点 return 内容之后处理逻辑,只有执⾏成功会执⾏,异常不会。
@Around:在切⼊点前后切⼊内容,并⾃⼰控制何时执⾏切⼊点⾃⾝的内容。原则上可以替代@Before和@After。
@AfterThrowing:⽤来处理当切⼊内容部分抛出异常之后的处理逻辑。
@Order(100):AOP 切⾯执⾏顺序, @Before 数值越⼩越先执⾏,@After 和 @AfterReturning 数值越⼤越先执⾏。
DemoAspect.java
importorg.aspectj.lang.ProceedingJoinPoint;import
org.aspectj.lang.annotation.*;importorg.springframework.stereotype.Component;/*** @Aspect 注解 使之成为切⾯类
* @Component 注解 把切⾯类加⼊到IOC容器中*/@Aspect
@Componentpublic classDemoAspect {
@Pointcut("execution( public * pers.kerry.ller.DemoController.*(..) )")public voiddoPointcut(){
}
@Before("doPointcut()")public voiddoBefore(){
System.out.println("==doBefore==");
}
@After("doPointcut()")public voiddoAfter(){
System.out.println("==doAfter==");
}
@AfterReturning("doPointcut()")public voiddoAfterReturning(){
System.out.println("==doAfterReturning==");
}/*** 环绕通知返回值类型Object,对应所有被拦截⽅法的返回值类型,不能为void*/@Around("doPointcut()")public Object doAround(ProceedingJoinPoint proceedingJoinPoint)throwsThrowable{
System.out.println("==doAround.before==");
Object ret=proceedingJoinPoint.proceed();
System.out.println("==doAround.after==");returnret;
}
}
SpringBootApplication 上使⽤@ServletComponentScan 注解后
Servlet可以直接通过@WebServlet注解⾃动注册
Filter可以直接通过@WebFilter注解⾃动注册
Listener可以直接通过@WebListener 注解⾃动注册

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。