Filter概念
Filter被称为过滤器,web三大组件之一。通过Filter可以实现对请求的拦截,从而实现一些特殊的功能。
Filter在web中的位置
Filter原理
Filter接口有一个doFilter方法,Web服务器每次调用web资源的service方法前,都会调用Filter实现类的doFilter方法,因此该方法就达到了如下目的:
- 调用目标资源之前(servlet被调用之前),让一段代码执行
- 是否调用目标资源(是否让用户访问servlet)
- 调用目标资源之后(servlet执行完毕后),让一段代码执行
服务器在调用doFilter方法时,会传递一个FilterChain对象进来,该对象也有一个doFilger方法,开发者可根据需求决定是否调用该方法。调用则放行,用户可以访问servlet;不调用则拦截。
Filter特点
Filter可以被指定和特定的URL(Web服务器)关联,只有当请求访问该URL时才会触发该过滤器
同一个URL下,可配置多个Filter,形成过滤器链。web服务器根据Filter在web.xml的配置顺序决定先执行哪个过滤器。当第一个Filter的doFilter方法被调用时,web服务器会创建一个代表Filter链的FilterChain对象传递给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2个filter,如果没有,则调用目标资源。
Filter作用
- Filter本身并不是servlet,不能够产生request和response。在请求到达servlet之前,Filter可以对request作预处理,根据需要修改request头和request数据;在response离开servlet时,Filter也可以根据需要修改response头和response数据。
- Filter可实现如下功能(只列举部分功能)
- 认证过滤
- 登录和审核过滤
- 图像转换过滤
- 数据压缩过滤
- 加密过滤等
Filter开发步骤
编写Filter实现类,重写doFilter方法
在web.xml中对Filter实现类进行配置
Filter代码示例
日志过滤器
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
public class LogFilter implements Filter {
public FilterConfig config;
@Override
public void destroy() {
this.config=null;
System.out.println("logFilter被销毁了");
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
System.out.println("logFilter执行前");
HttpServletRequest request = (HttpServletRequest)req;
String path = request.getServletPath();
// StringBuffer path = request.getRequestURL();
int port = request.getRemotePort();
System.out.println("用户的请求地址是:"+path+";请求端口是:"+port);
chain.doFilter(req, res);
System.out.println("logFilter执行后");
}
@Override
public void init(FilterConfig config) throws ServletException {
System.out.println("logFilter被创建了");
this.config=config;
}
}
编码过滤器
package gz.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class EncodingFilter implements Filter {
@Override
public void destroy() {
System.out.println("encodingFilter被销毁了!");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
//对request和response的预处理
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;UTF-8");
System.out.println("encodingFilter执行前");
chain.doFilter(request, response);
System.out.println("encodingFilter执行后");
}
@Override
public void init(FilterConfig arg0) throws ServletException {
System.out.println("encodingFilter被创建了!");
}
}
xml配置
<!-- 配置日志过滤器 -->
<filter>
<filter-name>logFilter</filter-name>
<filter-class>gz.filter.LogFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>logFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- 配置编码过滤器 -->
<filter>
<filter-name>efilter</filter-name>
<filter-class>gz.filter.EncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>efilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>