拦截器和过滤器其实都是AOP编程思想的实现。
过滤器:
是处于客户端与服务器资源文件之间的一道过滤网,在访问资源文件之前,通过一序列的过滤器对请求进行修改、判断,把不符合规则的请求在中途拦截或修改;也可以对响应进行过滤拦截和修改。
用在哪?
登录权限验证、资源访问权限控制、敏感词汇过滤、字符编码转换等等,便于代码重用。
用法:
需要一个过滤器类 然后实现javax.servlet.Filter接口。
public class LoginFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException{
// 过滤器初始化
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException{
// ServletRequest是一个接口 而HttpServletRequest是接口的实现
// 但有些方法是HttpServletRequest独有的 例如getSession()
// HttpServletRequest接口继承自ServletRequest接口 增加了和Http相关的方法
// 但是我们可以强制转换
HttpServletRequest request=(HttpServletRequest)servletRequest;
HttpServletResponse response=(HttpServletResponse)servletResponse;
// 若用户没有登录
if (request.getSession().getAttribute(USERINFO)==null && request.getRequestURI().indexOf(/user/doLogin.do)==-1){
response.sendRedirect(request.getContextPath()+/user/doLogin.do);
}
// 若用户已经登录 则继续下一个请求(继续访问)
filterChain.doFilter(request,response);
}
@Override
public void destroy(){
// 过滤器销毁
}
}
web.xml配置
<!-- 配置自定义的Filter 实现登录控制 -->
<filter>
<filter-name>sessionFilter</filter-name>
<filter-class>net.zjitc.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>sessionFilter</filter-name>
<!-- 拦截所有的页面 /斜杠代表在webapp目录下 -->
<url-pattern>/pages/*</url-pattern>
<url-pattern>/css/*</url-pattern>
<url-pattern>/img/*</url-pattern>
<url-pattern>/failer.jsp</url-pattern>
</filter-mapping>
过滤器生命周期:
当服务器启动,会创建Filter对象,并调用init方法,只调用一次.
当访问资源,路径与Filter的拦截路径匹配,会执行Filter中的doFilter方法,这个方法是真正拦截操作的方法.
当服务器关闭时,会调用Filter的destroy方法来进行销毁操作
过滤器是JavaEE标准,采用函数回调的方式进行。是在请求进入容器之后,还未进入Servlet之前进行预处理,并且在请求结束返回给前端这之间进行后期处理。
拦截器:
java里的拦截器提供的是非系统级别的拦截,也就是说,就覆盖面来说,拦截器不如过滤器强大,但是更有针对性。
Java中的拦截器是基于Java反射机制实现的,更准确的划分,应该是基于JDK实现的动态代理。它依赖于具体的接口,在运行期间动态生成字节码。
拦截器是动态拦截Action调用的对象,它提供了一种机制可以使开发者在一个Action执行的前(preHandle)后(postHandle)执行一段代码,也可以在一个Action执行前阻止其
用法:
自定义一个实现了Interceptor接口的类,或者继承抽象类AbstractInterceptor。
public class RateLimiterInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String params = request.getQuery
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
}
}
区别:
①拦截器是基于java的反射机制的,而过滤器是基于函数回调。
②拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
③拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
④拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
⑤在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
⑥拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑。拦截器可以获取ioc中的service bean实现业务逻辑。