一、过滤器的基本工作原理
1、过滤器的基本工作原理
过滤器的基本工作原理如图4-8示。
2、过滤器的特点
过滤器具备有以下特点:
(1)它是声明式的
(2)它是动态的
(3)它是模块化的
(4)它是可移植的
(5)它是可重用的
(6)它是透明的
二、过滤器的API接口及部署信息
1、javax.servlet.Filter接口
(1)public void init(FilterConfig filterConfig) throws ServletException
init()方法执行初始化操作
(2) public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws java.io.IOException,ServletException
过滤器的业务逻辑代码在doFilter()方法内实现
(3)public void destroy()
在销毁一个过滤器对象之前,此方法被调用来释放init()中申请的资源,这个方法的执行,表示一个过滤器的生命期结束
2、 javax.servlet.FilterConfig接口
(1)public java.util.Enumeration getInitParameterNames()
将初始化参数的变量名读至枚举型对象中。
(2)public java.lang.String
getInitParameter(java.lang.String name)
读取指定变量名的初始化参数值,如果没有此参数,则返回Null值。
(3)public ServletContext getServletContext()
获得当前Web应用的ServletContext对象。
3、javax.servlet. FilterChain接口
接口中关键的方法为:
public void doFilter(ServletRequest request,
ServletResponse response) throws java.io.IOException,ServletException
4、过滤器的部署
在WEB-INF\web.xml中部署一个过滤器的过程有:注册过滤器、映射过滤器
(1)注册过滤器
过滤器在Web应用中注册后才会被容器加载运行。在web.xml中注册过滤器的方法如下示:
<filter>
<filter-name>my1</filter-name>
<filter-class>com.abc.mis.Filter1</filter-class>
<init-param>
<param-name>password</param-name>
<param-value>123</param-value>
</init-param>
</filter>
容器为一个<filter></filter>元素创建一个过滤器实例,同一个过滤器类可以生成多个实例,此时只需要部署多个<filter></filter>元素,例如:
<filter>
<filter-name>my1</filter-name>
<filter-class>com.abc.mis.Filter1</filter-class>
<init-param>
<param-name>password</param-name>
<param-value>123</param-value>
</init-param>
</filter>
(2)映射过滤器
过滤器映射就是定义此过滤器的激活条件,一般是通过目标资源的URI模式和请求的类型来定义。URI中可以使用通配符“*”来表达请求的URI模式。过滤器映射的基本方法如下示:
<filter-mapping>
<filter-name>my1</filter-name>
<url-pattern>/test/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
三、第一个过滤器程序
过滤器的基本编程过程是:
第一步:编辑与编译过滤器程序,把编译后得到的包文件夹及*.class类发布到ROOT\WEB-INF\classes文件夹下。
第二步:编辑WEB-INF\web.xml文件,添加过滤器的部署信息。
第三步:重启Tomcat或重载Web应用,使过滤器生效。
【例】:定义三个过滤器:
如果用户访问“/test”下的资源时,过滤器1被激活,它判断用户是否已经登录,如果没有登录则中断请求,并返回404错误信息,如果已经登录则将请求转发给下一个过滤器。
定义过滤器2,当请求“/*”资源并且请求是来自客户端时它才被激活,显示提示信息,然后把请求转发给下一个过滤器。
过滤器3的功能同过滤器2,但它的请求类型为REQUEST或FORWARD。
操作步骤如下:
(1) 启动JC4,新建一个类“Filter1”,在代码编辑窗口中输入如下的代码:
<span style="font-family:SimSun;"><span style="font-family:FangSong_GB2312;font-size:14px;">package my; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class Filter1 implements Filter { private FilterConfig config = null; public void init(FilterConfig config) throws ServletException { this.config = config; } public void destroy() { config = null; } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { response.setCharacterEncoding("GB2312"); PrintWriter out=response.getWriter(); HttpSession session=((HttpServletRequest)request).getSession(); System.out.println("过滤器1工作,请求转下一个处理.."); out.print("<br>请求到达目标资源前过滤器2添加的信息<br>"); String loginStatus=(String)session.getAttribute("loginName"); if(loginStatus==null) { out.print("<br>你没有登陆,无房访问资源!<br>"); return; } else chain.doFilter(request, response); System.out.println("目标资源输出信息返回到过滤器1..."); out.print("<br>目标资源输出信息返回时过滤器2添加的信息<br>"); } }</span></span>
(2)编译Filter1程序,成功后,Filter1.class文件会被JC4自动存放至c:\tomcat\webapps\ROOT\WEB-INF\classes文件夹下,用“我的电脑”查看并核实。
(3)启动JC4,新建一个类“Filter2”,在代码编辑窗口中输入如下的代码:
<span style="font-family:SimSun;"><span style="font-family:FangSong_GB2312;font-size:14px;">package my; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class Filter2 implements Filter { private FilterConfig config = null; public void init(FilterConfig config) throws ServletException { this.config = config; } public void destroy() { config = null; } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { response.setCharacterEncoding("GB2312"); PrintWriter out=response.getWriter(); System.out.println("过滤器2工作,请求转下一个处理.."); out.print("<br>请求到达目标资源前过滤器2添加的信息<br>"); chain.doFilter(request, response); </span><pre name="code" class="java"><span style="font-family:FangSong_GB2312;font-size:14px;"> <span style="white-space:pre"> </span>System.out.println("目标资源输出信息返回到过滤器2..."); out.print("<br>目标资源输出信息返回时过滤器2添加的信息<br>"); </span></span>
}}
(4)编译Filter2程序。 (5)启动JC4,新建一个类 “Filter3”,在代码编辑窗口中输入如下的代码:
<span style="font-family:SimSun;"><span style="font-family:FangSong_GB2312;font-size:14px;">package my; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class Filter3 implements Filter { private FilterConfig config = null; public void init(FilterConfig config) throws ServletException { this.config = config; } public void destroy() { config = null; } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { </span><pre name="code" class="java"><span style="font-family:FangSong_GB2312;font-size:14px;"><span style="white-space:pre"> </span>System.out.println("过滤器3工作,请求转下一个处理.."); out.print("<br>请求到达目标资源前过滤器3添加的信息<br>"); chain.doFilter(request, response); </span><pre name="code" class="java"><span style="font-family:FangSong_GB2312;font-size:14px;"> <span> </span>System.out.println("目标资源输出信息返回到过滤器3..."); out.print("<br>目标资源输出信息返回时过滤器3添加的信息<br>"); </span></span>
}}
(6)编译Filter3程序。
(7)部署以上三个过滤器,得到一个过滤器链为:过滤器3→过滤器1→过滤器2。
编辑WEB-INF\web.xml文件,添加如下的部署信息:
(8)定义实验用JSP资源。启动DW8,完成以下任务:
新建exam406.jsp,在设计视图中输入提示文字“当前是/exam406.jsp 资源”。
新建exam407.jsp,在代码视图中输入以下代码:
<body>
<%
session.setAttribute("loginName","tom");
out.print("成功登录,可以访问/test下的资源了!");
%>
</body>
新建exam408.jsp,在设计视图中,将站点中的“ROOT\tomcat.gif”图片插入文档中。
在站点根文件夹下新建一个/test下级文件夹。
在/test文件夹下建立一个index.jsp文件,在设计视图中输入提示文字“/test的首页”。
新建exam409.jsp,在代码视图中输入以下代码:
<body>
<%
RequestDispatcher go=application.getRequestDispatcher("/exam406.jsp");
go.forward(request,response);
%>
</body>
(9)启动Tomcat,自行完成测试即可。