spring boot设置过滤器、监听器及拦截器的方法
前言
其实这篇文章算不上是springboot的东西,我们在spring普通项目中也是可以直接使用的
设置过滤器:
以前在普通项目中我们要在web.xml中进行filter的配置,但是只从servlet3.0后,我们就可以在直接在项目中进行filter的设置,因为她提供了一个注解@WebFilter(在javax.servlet.annotation包下),使用这个注解我们就可以进行filter的设置了,同时也解决了我们使用springboot项目没有web.xml的尴尬,使用方法如下所示
@WebFilter(urlPatterns="/*",filterName="corsFilter",asyncSupported=true)
publicclassCorsFilterimplementsFilter{
@Override
publicvoidinit(FilterConfigfilterConfig)throwsServletException{
}
@Override
publicvoiddoFilter(ServletRequestservletRequest,ServletResponseservletResponse,
FilterChainchain)throwsIOException,ServletException{
HttpServletResponseresponse=(HttpServletResponse)servletResponse;
HttpServletRequestrequest=(HttpServletRequest)servletRequest;
chain.doFilter(servletRequest,servletResponse);
}
@Override
publicvoiddestroy(){
}
}
其实在WebFilter注解中有一些属性我们需要进行设置,比如value、urlPatterns,这两个属性其实都是一样的作用,都是为了设置拦截路径,asyncSupported这个属性是设置配置的filter是否支持异步响应,默认是不支持的,如果我们的项目需要进行请求的异步响应,请求经过了filter,那么这个filter的asyncSupported属性必须设置为true不然请求的时候会报异常。
设置拦截器:
编写一个配置类,继承org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter或者org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport并重写addInterceptors(InterceptorRegistryregistry)方法,其实父类的addInterceptors(InterceptorRegistryregistry)方法就是个空方法。使用方法如下:
@Configuration
publicclassMvcConfigextendsWebMvcConfigurationSupport{
@Override
publicvoidaddInterceptors(InterceptorRegistryregistry){
InterceptorRegistrationregistration=registry.addInterceptor(newHandlerInterceptor(){
@Override
publicbooleanpreHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler)throwsException{
returntrue;
}
@Override
publicvoidpostHandle(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,ModelAndViewmodelAndView)throwsException{
}
@Override
publicvoidafterCompletion(HttpServletRequestrequest,HttpServletResponseresponse,Objecthandler,Exceptionex)throwsException{
}
});
//配置拦截路径
registration.addPathPatterns("/**");
//配置不进行拦截的路径
registration.excludePathPatterns("/static/**");
}
}
配置监听器:
一般我们常用的就是request级别的javax.servlet.ServletRequestListener和session级别的javax.servlet.http.HttpSessionListener,下面以ServletRequestListener为例,编写一个类实现ServletRequestListener接口并实现requestInitialized(ServletRequestEventevent)方法和requestDestroyed(ServletRequestEventevent)方法,在实现类上加上@WebListener(javax.servlet.annotation包下),如下所示
@WebListener
publicclassRequestListenerimplementsServletRequestListener{
@Override
publicvoidrequestDestroyed(ServletRequestEventsre){
System.out.println("请求结束");
}
@Override
publicvoidrequestInitialized(ServletRequestEventsre){
System.out.println("请求开始");
}
}
这样每一个请求都会被监听到,在请求处理前equestInitialized(ServletRequestEventevent)方法,在请求结束后调用requestDestroyed(ServletRequestEventevent)方法,其实在spring中有一个非常好的例子,就是org.springframework.web.context.request.RequestContextListener类
publicclassRequestContextListenerimplementsServletRequestListener{
privatestaticfinalStringREQUEST_ATTRIBUTES_ATTRIBUTE=
RequestContextListener.class.getName()+".REQUEST_ATTRIBUTES";
@Override
publicvoidrequestInitialized(ServletRequestEventrequestEvent){
if(!(requestEvent.getServletRequest()instanceofHttpServletRequest)){
thrownewIllegalArgumentException(
"RequestisnotanHttpServletRequest:"+requestEvent.getServletRequest());
}
HttpServletRequestrequest=(HttpServletRequest)requestEvent.getServletRequest();
ServletRequestAttributesattributes=newServletRequestAttributes(request);
request.setAttribute(REQUEST_ATTRIBUTES_ATTRIBUTE,attributes);
LocaleContextHolder.setLocale(request.getLocale());
RequestContextHolder.setRequestAttributes(attributes);
}
@Override
publicvoidrequestDestroyed(ServletRequestEventrequestEvent){
ServletRequestAttributesattributes=null;
ObjectreqAttr=requestEvent.getServletRequest().getAttribute(REQUEST_ATTRIBUTES_ATTRIBUTE);
if(reqAttrinstanceofServletRequestAttributes){
attributes=(ServletRequestAttributes)reqAttr;
}
RequestAttributesthreadAttributes=RequestContextHolder.getRequestAttributes();
if(threadAttributes!=null){
//We'reassumablywithintheoriginalrequestthread...
LocaleContextHolder.resetLocaleContext();
RequestContextHolder.resetRequestAttributes();
if(attributes==null&&threadAttributesinstanceofServletRequestAttributes){
attributes=(ServletRequestAttributes)threadAttributes;
}
}
if(attributes!=null){
attributes.requestCompleted();
}
}
}
在这个类中,spring将每一个请求开始前都将请求进行了一次封装并设置了一个threadLocal,这样我们在请求处理的任何地方都可以通过这个threadLocal获取到请求对象,好处当然是有的啦,比如我们在service层需要用到request的时候,可以不需要调用者传request对象给我们,我们可以通过一个工具类就可以获取,岂不美哉。
扩充:在springboot的启动类中我们可以添加一些ApplicationListener监听器,例如:
@SpringBootApplication
publicclassDemoApplication{
publicstaticvoidmain(String[]args){
SpringApplicationapplication=newSpringApplication(DemoApplication.class);
application.addListeners(newApplicationListener(){
@Override
publicvoidonApplicationEvent(ApplicationEventevent){
System.err.println(event.toString());
}
});
application.run(args);
}
}
ApplicationEvent是一个抽象类,她的子类有很多比如ServletRequestHandledEvent(发生请求事件的时候触发)、ApplicationStartedEvent(应用开始前触发,做一些启动准备工作)、ContextRefreshedEvent(容器初始化结束后触发),其他还有很多,这里不再多说,但是这些ApplicationListener只能在springboot项目以main方法启动的时候才会生效,也就是说项目要打jar包时才适用,如果打war包,放在Tomcat等web容器中是没有效果的。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对毛票票的支持。