Filter :Java中的Filter 并不是一个标准的Servlet ,它不能处理用户请求,也不能对客户端生成响应。 主要用于对HttpServletRequest 进行预处理,也可以对HttpServletResponse 进行后处理,是个典型的处理链。
优点:过滤链的好处是,执行过程中任何时候都可以打断,只要不执行chain.doFilter()就不会再执行后面的过滤器和请求的内容。而在实际使用时,就要特别注意过滤链的执行顺序问题
创建Filter类:
@WebFilter(filterName="log",urlPatterns{"/*"}) //filterName指定该Filter的名称,urlPatterns指定该Filter所拦截的URL
public class LogFilter implements Filter //LogFilter类继承Filter
{
//FilterConfig可用于访问Filter配置信息
private FilterConfig config; //定义私有成员FilterConfig型的 config
// 实现初始化方法
public void init(FilterConfig config) //init方法初始化建立设置操作
{
this.config = config; //将config赋值给当前的config
}
// 实现销毁方法
public void destroy() //destroy方法实现清除销毁功能
{
this.config = null; //将当前的config设置为空
}
//执行过滤的核心方法
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) // 在doFilter方法中放入过滤行为
//doFilter方法的第一个参数为ServletRequest对象。此对象给过滤器提供了对进入的信息(包括表单数据、cookie和HTTP请求头)的完全访问。
//第二个参数为ServletResponse,通常在简单的过滤器中忽略此参数。最后一个参数为FilterChain,此参数用来调用servlet或JSP页
thows IOException,ServletException //抛出IO异常
{
//-----下面代码用于对用户请求执行预处理-----
// 获取ServletContext 对象,用于记录日志
ServletContext context = this.config.getServletContext(); //用get放法将当前的config的值赋给 ServletContext型的context
long before = System.currentTimeMillis(); //将currentTimeMillis()获取的系统的当前时间值赋给long型的对象before.
System.out.println("开始过滤... "); //打印过滤开始提示信息
// 将请求转换成HttpServletRequest 请求
HttpServletRequest hrequest = (HttpServletRequest) request;//将请求强制转换为HttpServletRequest型再赋给HttpServletRequest 请求对象hrequest
// 输出提示信息
System.out.println("Filter已经截获到用户的请求的地址: " + hrequest.getServletPath());//通过getServletPath()函数打印请求的地址
// Filter 只是链式处理,请求依然转发到目的地址。
chain.doFilter(request, response); //调用FilterChain对象的doFilter方法。
//Filter接口的doFilter方法取一个FilterChain对象作为它的一个参数。在调用此对象的doFilter方法时,激活下一个相关的过滤器。
如果没有另一个过滤器与servlet或JSP页面关联,则servlet或JSP页面被激活。
//-----下面代码用于对服务器响应执行后处理-----
long after = System.currentTimeMillis(); //将currentTimeMillis()获取的系统的当前时间值赋给long型的对象after
// 输出提示信息
System.out.println("过滤结束... "); //打印过滤结束提示信息
// 输出提示信息
System.out.println("请求被定位到: " + hrequest.getRequstURI() + "所花的时间为:" + (after-before));
//通过getRequstURI()和(after-before)函数打印定位的路径及话费的时间
}
}