Servlet 请求/响应过滤器
1、Servlet 过滤器可以动态地拦截请求和响应,以变换或使用包含在请求或响应中的信息;
可以将一个或多个 Servlet 过滤器附加到一个 Servlet (或一组 Servlet),或者 JSP 、 HTML 页面,调用 Servlet 前调用所有附加的 Servlet 过滤器。
2、Servlet 过滤器是可用于 Servlet 编程的 Java 类,可以实现以下目的:
- 在客户端的请求访问后端资源之前,拦截这些请求。
- 在服务器的响应发送回客户端之前,处理这些响应。
3、过滤器通过 web.xml 中的 <filter> 标签来声明,然后映射到 web.xml 中的 <servlet> 或 <servlet-mapping> ;
当 Servlet 容器启动 Web 应用程序时,会为 web.xml 声明的每一个过滤器创建一个实例;
Filter 的执行顺序与在 web.xml 配置文件中的配置顺序一致,一般把Filter配置在所有的Servlet之前。
4、Servlet 过滤器的具体实现的
javax.servlet.Filter ,主要的 API 如下:
void doFilter (ServletRequest, ServletResponse, FilterChain)
|
完成实际的过滤操作,当客户端请求方法与过滤器设置匹配的URL时,Servlet容器将先调用过滤器的doFilter方法。FilterChain用户访问后续过滤器
|
void init(FilterConfig filterConfig)
|
web 应用程序启动时,web 服务器将创建Filter 的实例对象,并调用其init方法,读取web.xml配置,完成对象的初始化功能,从而为后续的用户请求作好拦截的准备工作(filter对象只会创建一次,init方法也只会执行一次)。开发人员通过init方法的参数,可获得代表当前filter配置信息的FilterConfig对象。
|
void destroy()
|
Servlet容器在销毁过滤器实例前调用该方法,在该方法中释放Servlet过滤器占用的资源
|
5、Filter 的 init() 方法中提供了一个 FilterConfig 对象,用于获取 Filter 参数;
如 web.xml 的文件配置如下:
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>control.LogFilter</filter-class>
<init-param>
<param-name>Site</param-name>
<param-value>真正的粉丝集社</param-value>
</init-param>
</filter>
在 Filter 中的 init() 方法中使用 FilterConfig 对象获取参数
public void init(FilterConfig config) throws ServletException {
// 获取初始化参数
String site = config.getInitParameter("Site");
// 输出初始化参数
System.out.println("网站名称: " + site);
}
6、一个简单的 Servlet 过滤器实例
这个例子展示在 DemoServlet 接收客户端的请求之前,先由 IPFilter 过滤器处理,检测该改请求的IP如果在IP列表中(ip列表从数据库中获取的方法参数,描述在 web.xml 中),则在向请求范围写入一个标记的属性值;
demoFilter.java
public class IPFilter implements Filter{
private ArrayList<String> IPtable = null; //IP列表
//获取Filter起始参数
public void init(FilterConfig config) throws ServletException{
String tableName = config.getInitParameter("tableName"); //在web.xml中获取Filter配置参数
IPtable = getIPtableFromDataBase(tableName); //从数据库中获取该IP列表,该方法实现省略
}
//Filter过滤过程
public void doFilter(ServletRequest request,ServletRespone response,FilterChain chain) throws ServletException,IOException{
String ip = request.getRemoteAddr();
if(IPtable.contains(ip))
request.setAttribute("ip","unsafe");
else
request.setAttribute("ip","safe");
//将请求传回过滤链,供后续Filter进行过滤(也可以不调用该方法,直接将请求转发给响应的Servlet)
chain.doFilter(request,response);
}
}
web.xml
<web-app>
<filter>
<filter-name>IPFilter</filter-name>
<filter-class>test.LogFilter</filter-class>
<init-param>
<param-name>tableName</param-name>
<param-value>ip_unSafe</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>LogFilter</filter-name>
<url-pattern>/demo</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>DempServlet</servlet-name>
<servlet-class>test.DemoServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DemoServlet</servlet-name>
<url-pattern>/demo</url-pattern>
</servlet-mapping>
</web-app>
以上的 <filter-mapping>中的<url-pattern> 指定 IPFilter 映射到 "/demo",如果想要将该 Filter 映射到所有 Servlet,只需修改该
<filter-mapping><url-pattern>值为 " /* ";