介绍
自定义的Filter类必须实现Filter接口,并且实现Filter接口定义的init() doFilter() destory()方法。其中init为初始化,destory为销毁 doFilter为实现过滤。
doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
该方法的三个参数:request、response用来传递给下一个Filter或者JSP和Servlet,
chain通过调用其doFilter方法来调用下一个Filter,获得调用原始JSP或Servlet等其他内容。
该方法完成实际的过滤操作,当客户端请求方法与过滤器设置匹配的URL时,Servlet容器将先调用过滤器的doFilter方法。FilterChain用户访问后续过滤器。
这里的ServletRequest和ServletResponse一般需要转换成具体的Servlet实现对于的对象,如:HttpServletRequest和HttpServletResponse。
有些过滤器比较消耗资源,所以需要防止重复过滤,可以在doFilter()方法中判断。
定义过滤器
public class MyFilter implements Filter { public void init(FilterConfig fc) { //过滤器初始化代码 } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain){ //在这里可以对客户端请求进行检查 //沿过滤器链将请求传递到下一个过滤器。 chain.doFilter(request, response); //在这里可以对响应进行处理 } public void destroy( ) { //过滤器被销毁时执行的代码 } }
过滤器映射
<filter> <filter-name>MyFilter</filter-name> <filter-class> com.servlet.TimeTrackFilter </filter-class> <init-param> <param-name>developer</param-name> <param-value>Developername</param-value> </init-param> </filter> <!--针对一个Servlet做过滤--> <filter-mapping> <filter-name>MyFilter</filter-name> <servlet-name>MyServlet</servlet-name> </filter-mapping> <!--针对URL Pattern做过滤--> <filter-mapping> <filter-name>MyFilter</filter-name> <url-pattern>/book/*</url-pattern> </filter-mapping>
注意:/* 表示拦截所有资源及不存在的资源
*.jsp 表示拦截所有jsp文件
===========================================================================
例子:登录验证过滤器
dl.html 登录界面
<!DOCTYPE HTML PUBLIC "=//w3c//dtd html 4.0 transitional/cn"> <html lang='zh'> <head> <title>登录</title> </head> <body bgcolor="#FFFFFF"> <h1 align="center"><b>欢迎登陆系统</b></h1> <form name="login" method = "post" action="servlet/Main"> <p></p> <table width = "52%"border="2" align ="center"> <tr bgcolor ="#FFFFCC"> <td align = "center" width="43%"><div align="center">用户名:</div></td> <td width="57%"> <div align="left"> <input type ="text" name = "userID" value=""> </div> </td> </tr> <tr bgcolor = "#ccff99"> <td align = "center" width = "43%"> <div align= "center">密码:</div> </td> <td width = "57%"> <div align = left> <input type="password" name= "password" value=""> </div> </td> </tr> </table> <p align="center"> <input type="reset" name= "reset" value = "重置"> <input type="submit" name= "tj" value = "提交"> </form> </body> </html>
Main.java 进行页面重定向,判断用户名密码是否正确
public class TimeTrackFilter implements Filter { private FilterConfig filterConfig=null; public void destroy() { this.filterConfig=null; } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { Date startTime , endTime; double totalTime; StringWriter sw = new StringWriter(); System.out.println("我在Filter中1"); try{ Thread.sleep(2000); }catch(InterruptedException e){ System.out.println(e.toString()); } startTime = new Date(); String login=(String) request.getParameter("userID"); if(login==null||"".equals(login)){ //如果没有输入用户名,重定位 HttpServletResponse resp =( HttpServletResponse )response; resp.sendRedirect("../dl.html"); } else chain.doFilter(request, response); //对响应进行处理 endTime = new Date(); totalTime = endTime.getTime()- startTime.getTime(); System.out.println("我在Filter中2"); PrintWriter writer = new PrintWriter(sw); writer.println("============== 耗时"+totalTime+"毫秒 =============="); filterConfig.getServletContext().log(sw.getBuffer().toString()); } public void init(FilterConfig fConfig) throws ServletException { this.filterConfig=fConfig; } }
TimeTrackFilter.java Main的过滤器,如果没有输入用户名,则重定位到dl.html,否则就继续
public class TimeTrackFilter implements Filter { private FilterConfig filterConfig=null; public void destroy() { this.filterConfig=null; } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { Date startTime , endTime; double totalTime; StringWriter sw = new StringWriter(); System.out.println("我在Filter中"); try{ Thread.sleep(2000); }catch(InterruptedException e){ System.out.println(e.toString()); } startTime = new Date(); String login=(String) request.getParameter("userID"); if(login==null||"".equals(login)){ //如果没有输入用户名,重定位 HttpServletResponse resp =( HttpServletResponse )response; resp.sendRedirect("../dl.html"); } else chain.doFilter(request, response); //对响应进行处理 endTime = new Date(); totalTime = endTime.getTime()- startTime.getTime(); System.out.println("我在Filter中"); PrintWriter writer = new PrintWriter(sw); writer.println("============== 耗时"+totalTime+"毫秒 =============="); filterConfig.getServletContext().log(sw.getBuffer().toString()); } public void init(FilterConfig fConfig) throws ServletException { this.filterConfig=fConfig; } }
LoginSuccess.jsp登录成功页面:
<%@ page language="java" import="java.util.*" pageEncoding="gb2312"%> <html> <head> <title>登录成功</title> </head> <body> <%String name = request.getParameter("userID"); %> <h1>欢迎!"<%out.print(name);%> "您已成功登录系统...</h1> </body> </html>
LoginFail.java 登录失败页面
<%@ page language="java" import="java.util.*" pageEncoding="gb2312"%> <html> <head> <title>登录失败</title> </head> <body> <h1>登录失败,请重新登录...</h1> </body> </html>
控制台输出效果:
我在Filter中1
我在Servlet Main中
重定向
我在Filter中2
七月 08, 2015 10:22:21 上午 org.apache.catalina.core.ApplicationContext log
信息: ==============
耗时2015.0毫秒
==============