1,什么是过滤器(filter)?
它是以一种组件的形式绑定到web应用程序当中的,与其他的Web应用程序组件不同的是:过滤器是采用“链”的方式进行处理(当需要限制用户访问某些资源或者处理请求时时提前处理某些资源时);当用户发出请求到web服务器,web服务器并没有直接去找到那个相应的web资源,而是交给了过滤器,所有的请求由过滤器去处理,然后在访问相应的web资源;这样可以达到对某些资源的访问限制;
2,实现过滤器!
如果要定义一个过滤器,则直接让一个类实现javax.servlet.Filter接口;此接口定义了3个操作方法:
No | 方法 | 类型 | 描述 |
1 | public void init(FilterConfig filterConfig) throws ServletException | 普通 | 过滤器初始化(容器启动时调用),可以通过FilterConfig配置的初始化参数 |
2 | public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain) throws IOException,ServletException | 普通 | 完成具体的过滤操作,然后通过FilterChain让请求继续向下传递 |
3 | public void destory() | 普通 | 过滤器销毁时使用 |
上面的doFilter()方法中定义了ServletRequest,ServletResponse和FilterChain3个参数,都是ServletRequest/ServletResponse说明过滤器可以完成对任意协议的操作。FilterChain接口的主要作用是将用户的请求向下传递给其他的过滤器或者Servlet,此接口的方法如下:
No | 方法 | 类型 | 描述 |
1 | public void doFilter(ServletRequest request,ServletResponse response)throws IOException,ServletException | 普通 | 将请求向下继续传递 |
在FilterChain接口中依然定义了一个同样的doFilter()方法,这样是因为一个过滤器后面可能存在另外一个过滤器,也可能是请求的最终目标(Servlet),这样就通过FilterChain形成一个"过滤链"的操作;
3,看一个简单的过滤器!
SimpleFilter:
package com.keith.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 SimpleFilter implements Filter {
/**
* 初始化过滤器
*/
public void init(FilterConfig config) throws ServletException {
// 取得初始化参数
String initParam = config.getInitParameter("ref");
System.out.println("过滤器被初始化,初始参数:" + initParam);
}
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
System.out.println("-------执行doFilter()之前---------------");
chain.doFilter(req, resp);
System.out.println("-------执行doFilter()之后---------------");
}
public void destroy() {
System.out.println("-------filter销毁--------");
}
}
在web.xml中配置:
<filter> <filter-name>simple</filter-name> <filter-class>com.keith.filter.SimpleFilter</filter-class> <init-param> <param-name>ref</param-name> <param-value>Hello Filter</param-value> </init-param> </filter> <filter-mapping> <filter-name>simple</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
当服务器(tomcat)启动的时候:会输出:过滤器被初始化,初始参数:Hello Filter
当我们在浏览器访问目录的时候:会在控制台上:
-------执行doFilter()之前---------------
-------执行doFilter()之后---------------
过滤器(Filter)和servlet的配置很相似,其中的<url-pattern>标签中,是拦截的内容,/*将对所有访问进行拦截,而如果我们只想对某些目录进行拦截可以这样:
<url-pattern>/jsp/*</url-pattern> <url-pattern>/js/*</url-pattern>
4,过滤器的应用:
过滤器(Filter)属于是以一个组件的形式加入到应用程序中,
- 编码过滤
如果我们在每一个jsp或者servlet中都写一个request.setCharsetEncoding("UTF-8");这样的工作太无趣和累赘,这个时候,我们就可以用到Filter:
EncodingFilter:
package com.keith.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 EncodingFilter implements Filter {
// 设置字符编码
private String charSet;
public void init(FilterConfig filterConfig) throws ServletException {
// 取得初始化参数
this.charSet = filterConfig.getInitParameter("charSet");
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// 设置统一编码
request.setCharacterEncoding(this.charSet);
}
public void destroy() {
}
}
在web.xml里:
<filter> <filter-name>encoding</filter-name> <filter-class>com.keith.filter.EncodingFilter</filter-class> <init-param> <param-name>charset</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>encoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
- 登陆验证:验证登陆是Web开发中不可缺少的一部分,以前都是通过验证session的方式完成,如果每个页面都这样做的话,会造成大量的冗余代码,这时候就可以通过Filter轻松的完成;
LoginFilter:
package com.keith.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;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
public class LoginFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpSession session = req.getSession();
if (session.getAttribute("user") != null) {
chain.doFilter(request, response);
}else{
request.getRequestDispatcher("login.jsp").forward(request, response);
}
}
public void destroy() {
}
}
以上2个过滤器只是个演示,在实际开发中,并不是这么简单!