1、Java三大器
监听器Listener | 过滤器Filter | 拦截器Interceptor | |
---|---|---|---|
作用目标 | 系统级别参数、对象 | 所有web请求 | Action(部分web请求) |
实现 | 事件 | 函数回调 | 反射机制(动态代理) |
应用 | 打印日志、统计网站在线人数、访问量等 | 设置字符编码、过滤敏感词汇、权限访问控制等 | 拦截未登入用户等 |
Servlet支持 | ServletContextListener、HttpSessionListener等抽象接口 | Filter接口 | |
Spring支持 | HandlerInterceptor、HandlerInterceptorAdapter |
2、定义
(1)过滤器是一个实现了 javax.servlet.Filter 接口的 Java 类,依赖于servlet容器。
(2)对Web服务器管理的所有Web资源进行过滤,并且添加某些功能,如:字符编码过滤,设置成统一的utf-8、过滤敏感词汇、URL权限访问控制等。
(3)过滤器不是用户主动调用的,而是根据规则自己执行。
(4)一个过滤器实例只能在容器初始化时调用一次,即filter对象只会创建一次,init方法也只会执行一次。
3、过滤器与拦截器的区别
- 过滤器能过滤所有的web请求,而拦截器只针对Action部分请求,过滤器能修改request;
- 过滤器依赖于servlet容器,拦截器依赖于web框架,在SpringMVC中依赖于SpringMVC框架;
- 过滤器只在请求的前后使用,拦截器可以详细到每个方法,更具有针对性;
- 一个过滤器实例只能在容器初始化时调用一次,拦截器可多次调用。
4、过滤器方法
方法 | 描述 |
---|---|
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) | 该方法完成实际的过滤操作,当客户端请求方法与过滤器设置匹配的URL时,Servlet容器将先调用过滤器的doFilter方法。 |
public void init(FilterConfig fConfig) | web 应用程序启动时,web 服务器将创建Filter 的实例对象,并调用其init方法,读取web.xml配置,完成对象的初始化功能 |
public void destroy() | 销毁过滤器 |
注:Web服务器在调用doFilter()时,会传递一个filterChain对象进来,filterChain对象也提供了一个doFilter方法,调用该方法,则Web服务器就会调用Web资源的service方法,即Web资源就会被访问,否则Web资源不会被访问。
5、多个过滤器应用顺序
(1)在web.xml中按<filter-mapping>的顺序;
(2)注解@WebFilter方式时按过滤器字母顺序;
(3)都存在时优先应用web.xml中的配置。
6、配置
(1)使用注解@WebFilter
(2)web.xml中配置
<filter>
<description>登入权限访问控制</description>
<filter-name>LoginFilter</filter-name>
<filter-class>com.xinx.own.LoginFilter</filter-class>
<!-- FilterConfig 对象参数(初始化),根据需求自行设置-->
<init-param>
<param-name>charset</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<!-- 映射路径 -->
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<!-- 要过滤的路径 -->
<url-pattern>/*</url-pattern>
<!-- 过滤类型 -->
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
7、过滤器的过滤类型:
<dispatcher>
标签中配置
- REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。
- INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
- FORWARD:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。
- ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。
8、示例
public class LoginFilter implements Filter {
/**
* Default constructor.
*/
public LoginFilter() {}
/**
* @see Filter#destroy()
*/
public void destroy() {}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
//获取初始化参数
String fName = fConfig.getFilterName();
System.out.print("过滤器名字:"+fName);
......
}
/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// place your code here
System.out.print("开始#######################");
//获取request、response、session对象
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
HttpSession session = req.getSession();
/**
* 对request执行过滤操作
* 续自己的业务
*/
......
// pass the request along the filter chain
chain.doFilter(request, response);
}
}