首页 > 编程知识 正文

springmvc拦截器原理,过滤器拦截器使用场景

时间:2023-05-05 00:39:35 阅读:17191 作者:4589

一.过滤器和拦截器的区别

1、滤波器和拦截器的触发时机不同。 过滤器在请求访问容器之后,但在请求访问servlet之前进行预处理。 请求结束后返回也是在servlet处理结束后返回前端之前。

2、拦截器可以获取IOC容器中的每个bean,但不能过滤。 拦截器由spring提供和管理,因此拦截器可以使用spring功能。 可以向拦截器注入服务以调用业务逻辑。 过滤器是JavaEE标准,只依赖servlet API,不需要依赖spring。

3、滤波器的实现基于回调函数。 拦截器(代理模式)的实现基于反射

4、过滤器依赖于servlet容器,是servlet规范的一部分,但拦截器是独立存在的,可以在任何情况下使用。

5、过滤器的执行通过servlet容器的回调进行,拦截器通常以动态代理(反射)方式执行。

6、过滤器的生命周期由servlet容器管理,拦截器由IoC容器管理,通过注入等方式可以获取其他Bean的实例,使用方便。

过滤器和拦截器很相似,但有很大的区别

最明显的区别是,**过滤器可以修改请求,但不能拦截器

过滤器必须在servlet容器中实现,拦截器可以应用于javaEE、javaSE等各种环境

拦截器可以调用IOC容器中的各种依赖关系,但过滤器不能

过滤器只能在请求前后使用,但拦截器采用各种方法**

差异很多,请大家调查一下

总的来说

过滤器是筛选你想要的东西。 例如,requeset中你想要的部分

拦截器在安全方面被广泛使用,例如结束一些过程

网上有很好的照片。 请复印在这里给我看

过滤器(Filter ) :可以获取原始http请求,但无法获取请求的控制器和请求控制器中方法的信息。

拦截器可以获得你请求的控制器和方法,但不能获得请求方法的参数。

切片:可以获得方法的参数,但不能获得http请求和响应对象。

二、过滤器两种方式:

1、使用spring boot提供的过滤器注册过滤器

2、用本机servlet注释定义Filter

这两种方式的本质都相同,都是在FilterRegistrationBean中注册自定义过滤器

方式一: (使用spring boot提供的FilterRegistrationBean注册filter (http://www.Sina.com /

package com.corwien.filter; 导入javax.servlet.*; import java.io.IOException; publicclassmyfilterimplementsfilter { @ overridepublicvoidinit (filterconfigfilterconfig ) throws ServletException { } @ overridepublicvoiddofilter (servletrequestservletrequest,ServletResponse servletResponse, 过滤器通道过滤器通道) throws servlet exception {//do something处理request或response //doFilter ()方法的servletRequest参数必须转换为HttpServletRequest过滤器链中的下一个filterhttpservletrequestrequest=(http servletrequest ) servlet request; http servlet响应=(http servlet响应) servlet响应; String ip=request.getRemoteAddr (; string URL=request.getrequest URL ().toString ); simpledateformatsdf=newsimpledateformat (yyyy-mm-ddhh : mm : ss ); 日期d=new date (; stringdate=SDF.format(d; system.out.printf('%s%s已访问%s%n”、date、ip和url ); filter chain.do filter (请求,响应; } @Ov

erride public void destroy() { }}

②、注册自定义Filter

@Configurationpublic class FilterConfig { @Bean public FilterRegistrationBean registrationBean() { ** FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(new** **MyFilter());** filterRegistrationBean.addUrlPatterns("/*"); return filterRegistrationBean; }}

方式一的①②步骤可以用下面这段代码代替:

@Configuration public class FilterConfig { @Bean public **FilterRegistrationBean** registFilter() { **FilterRegistrationBean registration** **= new FilterRegistrationBean(); registration.setFilter(new** **LogCostFilter());** registration.addUrlPatterns("/*"); registration.setName("LogCostFilter"); registration.setOrder(1); return registration; } } public class LogCostFilter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { long start = System.currentTimeMillis(); filterChain.doFilter(servletRequest,servletResponse); System.out.println("Execute cost="+(System.currentTimeMillis()-start)); } @Override public void destroy() { //销毁 }

方式二:(使用原生servlet注解定义Filter )

// 注入spring容器

@Component // 定义filterName 和过滤的url@WebFilter(filterName = "my2Filter" ,urlPatterns = "/*") public class My2Filter implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("filter2"); } @Override public void destroy() { }}

这里直接用@WebFilter就可以进行配置,同样,可以设置url匹配模式,过滤器名称等。这里需要注意一点的是@WebFilter这个注解是Servlet3.0的规范,并不是Spring boot提供的。除了这个注解以外,我们还需在启动类中加另外一个注解:@ServletComponetScan,指定扫描的包。

三、拦截器的配置

实现拦截器可以通过继承 HandlerInterceptorAdapter类也可以通过实现HandlerInterceptor这个接口。另外,如果preHandle方法return true,则继续后续处理。

首先我们实现拦截器类:

public class LogCostInterceptor implements HandlerInterceptor { long start = System.currentTimeMillis(); @Override public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception { start = System.currentTimeMillis(); return true; } @Override public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception { System.out.println("Interceptor cost="+(System.currentTimeMillis()-start)); } @Override public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception { }}

我们还需要实现HandlerInterceptor这个接口,这个接口包括三个方法,preHandle是请求执行前执行的,postHandler是请求结束执行的,但只有preHandle方法返回true的时候才会执行,afterCompletion是视图渲染完成后才执行,同样需要preHandle返回true,该方法通常用于清理资源等工作。除了实现上面的接口外,我们还需对其进行配置:

@Configuration public class InterceptorConfig extends WebMvcConfigurerAdapter { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new LogCostInterceptor()).addPathPatterns("/**"); super.addInterceptors(registry); }}

这里我们继承了WebMVCConfigurerAdapter,这里我们重写了addInterceptors这个方法,进行拦截器的配置,主要配置项就两个,一个是指定拦截器,第二个是指定拦截的URL。

坑坑坑:
拦截器不生效常见问题:
1)是否有加@Configuration
2)拦截路径是否有问题 ** 和 *
3)拦截器最后路径一定要 “/**”, 如果是目录的话则是 /*/

总结一下:创建拦截器需要两步:

1、自定义拦截器
2、注册拦截器

四、应用场景

拦截器是在DispatcherServlet这个servlet中执行的,因此所有的请求最先进入Filter,最后离开Filter。其顺序如下。

Filter->Interceptor.preHandle->Handler->Interceptor.postHandle->Interceptor.afterCompletion->Filter

拦截器应用场景
拦截器本质上是面向切面编程(AOP),符合横切关注点的功能都可以放在拦截器中来实现,主要的应用场景包括:

登录验证,判断用户是否登录。
权限验证,判断用户是否有权限访问资源,如校验token
日志记录,记录请求操作日志(用户ip,访问时间等),以便统计请求访问量。
处理cookie、本地化、国际化、主题等。
性能监控,监控请求处理时长等。
通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个处理器都需要的即可使用拦截器实现)
过滤器应用场景
1)过滤敏感词汇(防止sql注入)
2)设置字符编码
3)URL级别的权限访问控制
4)压缩响应信息

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。