java 过虑器 、拦截器 、监听器的区别?
-
实现原理:
- 过滤器基于函数回调实现。
- 拦截器基于Java的反射机制实现。
- 监听器用于监听特定事件的发生,并作出相应处理。
-
使用范围:
- 过滤器依赖于Tomcat等容器,主要用于Web程序。
- 拦截器不依赖于servlet容器,可应用于Web程序、Application、Swing等。
- 监听器同样可用于监听Web程序中的特定事件。
过滤器的应用场景
1、过滤敏感词汇(防止sql注入)
2、设置字符编码
3、URL级别的权限访问控制
4、压缩响应信息
拦截器的应用场景
1、登录验证,判断用户是否登录。
2、权限验证,判断用户是否有权限访问资源,如校验token
3、日志记录,记录请求操作日志(用户ip,访问时间等),以便统计请求访问量。
4、处理cookie、本地化、国际化、主题等。
5、性能监控,监控请求处理时长等。
6、通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用
-
触发时机:
- 过滤器在请求进入Servlet之前和响应返回给前端之前进行预处理。
- 拦截器在请求进入Servlet后,但在进入Controller之前进行预处理。
- 监听器在特定事件发生时触发,如Servlet生命周
- 过滤器、拦截器和监听器的简单示例期中的创建、初始化、销毁等。
过滤器、拦截器和监听器的简单示例
import javax.servlet.*;
import java.io.IOException;
public class SimpleFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 过滤器初始化时执行的方法
System.out.println("Filter initialized");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
// 在请求处理之前可以添加逻辑
System.out.println("Before request processing");
chain.doFilter(request, response); // 将请求传递给下一个过滤器或目标资源
// 在请求处理之后可以添加逻辑
System.out.println("After request processing");
}
@Override
public void destroy() {
// 过滤器销毁时执行的方法
System.out.println("Filter destroyed");
}
}
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SimpleInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// 在请求处理之前进行调用(Controller方法调用之前)
System.out.println("Before Controller method");
return true; // 只有返回true才会继续向下执行,返回false取消当前请求
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// 请求处理之后进行调用,但是在视图被渲染之前(Controller方法调用之后)
System.out.println("After Controller method, before view rendering");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
// 在整个请求结束之后被调用,也就是在DispatcherServlet渲染了对应的视图之后执行(主要用于进行资源清理工作)
System.out.println("After view rendering");
}
}
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class SimpleListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
// 当ServletContext被初始化时调用
System.out.println("ServletContext initialized");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
// 当ServletContext被销毁时调用
System.out.println("ServletContext destroyed");
}
}
如何配置过滤器、拦截器和监听器?
@Component
public class MyFilter implements Filter {
// 实现doFilter等方法
}
// 拦截器 注入
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
}
}
@Component
public class MyListener implements ServletContextListener {
// 实现contextInitialized、contextDestroyed等方法
}