Servlet 过滤器
Servlet 过滤器可以动态地拦截请求和响应,以变换或使用包含在请求或响应中的信息。
可以将一个或多个 Servlet 过滤器附加到一个 Servlet 或一组 Servlet。Servlet 过滤器也可以附加到 JavaServer Pages (JSP) 文件和 HTML 页面。调用 Servlet 前调用所有附加的 Servlet 过滤器。
Servlet 过滤器是可用于 Servlet 编程的 Java 类,可以实现以下目的:
- 在客户端的请求访问后端资源之前,拦截这些请求。
- 在服务器的响应发送回客户端之前,处理这些响应。
Servlet 过滤器方法
过滤器是一个实现了 javax.servlet.Filter 接口的 Java 类。javax.servlet.Filter 接口定义了三个方法:
| 序号 | 方法 & 描述 |
|---|---|
| 1 | public void doFilter(ServletRequest, ServletResponse, FilterChain) 该方法完成实际的过滤操作,当客户端请求方法与过滤器设置匹配的 URL 时,Servlet 容器将先调用过滤器的 doFilter 方法。FilterChain 用于访问后续过滤器。 |
| 2 | public void init(FilterConfig filterConfig) web 应用程序启动时,web 服务器将创建 Filter 的实例对象,并调用其 init 方法,读取 web.xml 配置,完成对象的初始化功能,从而为后续的用户请求作好拦截的准备工作(filter 对象只会创建一次,init 方法也只会执行一次)。开发人员通过 init 方法的参数,可获得代表当前 filter 配置信息的 FilterConfig 对象。 |
| 3 | public void destroy() Servlet 容器在销毁过滤器实例前调用该方法,在该方法中释放 Servlet 过滤器占用的资源。 |
FilterConfig 使用
Filter 的 init 方法中提供了一个 FilterConfig 对象。
如 web.xml 文件配置如下:
<filter>
<filter-name>visitfilter</filter-name>
<filter-class>VisitFilter</filter-class>
<init-param>
<param-name>Enable</param-name>
<param-value>1</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>visitfilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>Code language: HTML, XML (xml)
以上配置表示所有 URL 地址都需要先经过该过滤器,并且配置了一个参数 Enable,在过滤器里面可以获取这个参数的值,达到控制目的。
添加 VisitFilter 类,实现 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 VisitFilter implements Filter {
private FilterConfig config;
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)
throws IOException, ServletException {
String enable = config.getInitParameter("Enable");
if ("1".equals(enable)) {
if (arg0.getParameter("password") != null) {
// 设置响应内容类型
arg1.setContentType("text/html;charset=UTF-8");
arg1.getWriter().append("对不起,系统检测到危险字符。已经屏蔽您的请求。");
arg1.getWriter().close();
arg1.getWriter().flush();
}
}
// 把请求传回过滤链
arg2.doFilter(arg0, arg1);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
config = arg0;
}
}Code language: JavaScript (javascript)
当任何 URL 带有 password 参数时,就提示有危险操作,防止有人进行系统攻击。
访问以下地址,只要带上 password 参数就会报该错误:
http://localhost:8080/ServletDemo/home?password=1Code language: JavaScript (javascript)
如果不带 password 参数则正常显示。
注意:过滤的时候如果不希望继续执行后续的输出,记得调用
arg1.getWriter().close()和arg1.getWriter().flush()。
Previous: Servlet之间的参数传递
Next: Servlet 异常错误处理