过滤器
当需要限制用户访问某些资源或者在处理请求时提前处理某些资源时,即可使用过滤器完成。
1、过滤器的基本概念
** 过滤器**,是一个服务器端的组件,它可以截取用户端的请求域响应信息,并对这些信息过滤。
过滤器是以一种组件的形式绑定到Web应用程序当中的,与其他的Web用用程序组件不同的是,过滤器是采用“链”的方式进行处理。
2、过滤器的工作原理
过滤器的工作原理在没有使用过滤器以前,客户端都是直接请求Web资源的,但是一旦加入了过滤器,所有的请求都是先交给了过滤器处理,然后再访问相应的Web资源,可以达到对某些资源的访问限制。
3、过滤器的生命周期
过滤器的生命周期实例化和初始化都只执行一次。
4、实现过滤器
定义一个过滤器,直接让一个类实现javax.servlet.Filter接口即可。并覆写相应的方法,所有的过滤器要执行两次。
此接口定义了3个操作方法:
public void init(FilterConfig filterConfig) throws ServletException
这是过滤器的初始化方法,Web容器创建过滤器实例化后将调用这个方法,这个方法中可以读取web.xml文件中过滤器的参数。
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException ServletException
这个方法完成实际的过滤操作,这个是过滤器的核心方法,当用户请求访问与过滤器关联的URL时,Web容器将先调用过滤器的doFilter()方法。
FilterChain参数可以调用chain.doFilter()方法,将请求传给下一个过滤器(或目标资源),或利用转发、重定向将请求转发到其他资源。
public void destroy()
Web容器在销毁过滤器销毁实例前调用该方法,在这个方法中可以释放过滤器占用的资源。(大多数情况用不到)
需要配置web.xml,配置与Servlet的配置时非常的类似。
<filter>
<filter-name>SimpleFilter</filter-name>
<filter-class>com.meng.filter.SimpleFilter</filter-class>
<init-param>
<description>描述信息</description>
<param-name>name</param-name>
<param-value>xiaoli</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>SimpleFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher></dispatcher>
</filter-mapping>
<url-pattern>表示过滤器的过滤(路径)位置。
<dispatcher>定义过滤器的分类类型。
过滤器能改变用户请求的Web资源,也就是能改变用户请求的路径。
过滤器不能直接返回数据,不能直接处理用户请求。
5、过滤器链
过滤器的操作原理服务器会按照在web.xml中过滤器定义的先后顺序组装成一条链。
过滤器链执行过程6、过滤器分类
过滤器的分类在Servlet3.0中加入了@WebFilter
@WebFilter 用于将一个类声明为过滤器,该注解将会在部署时被容器处理,容器将根据具体的属性配置将相应的类部署为过滤器。
@WebFilter(servletNames={"SimpleServlet"},filterName="SimpleFilter")
public class SimpleFilter implements Filter {
.........
}
注解的方式等同于
<filter>
<filter-name>SimpleFilter</filter-name>
<filter-class>com.meng.filter.SimpleFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SimpleFilter</filter-name>
<servlet-name>SimpleServlet</servlet-name>
</filter-mapping>
@WebFilter 常用的属性
7、过滤器应用
过滤器在实际应用中的一些场景:
- 对用户请求进行统一认证
- 编码转换
- 对用户发送的数据进行过滤替换
- 转换图像格式
- 对相应的内容进行压缩
- 等等。。。。
案例一:编码转换
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;
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// 设置统一编码
request.setCharacterEncoding(this.charSet);
}
@Override
public void init(FilterConfig config) throws ServletException {
// 取得初始化的参数
this.charSet = config.getInitParameter("charset");
}
}
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>com.meng.filter.EncodingFilter</filter-class>
<init-param>
<param-name>charset</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
案例二:登录验证
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 {
@Override
public void destroy() {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpSession session = req.getSession();
if (session.getAttribute("userid") != null ) {
chain.doFilter(request, response);
} else {
request.getRequestDispatcher("login.jsp").forward(request, response);
}
}
@Override
public void init(FilterConfig config) throws ServletException {
}
}