在Servlet2.3规范中定义了过滤器,它对servlet容器调用servlet的过程进行拦截,从而在servlet进行响应处理的先后实现一些特殊的功能。 java
过滤器实现了一个责任链的模式。多个过滤器造成一个过滤器链,过滤器链中不一样过滤器的前后顺序由部署文件web.xml中过滤器映射<filter-mapping>的顺序决定。 web
最早截获客户端请求的过滤器将最后截获Servlet/JSP的响应信息。 浏览器
Servlet过滤器能够过滤的Web组件包括Servlet,JSP和HTML等文件。 缓存
Servlet过滤器能够应用在客户端和servlet之间、servlet和servlet或JSP页面之间,以及所包括的每一个JSP页面之间。 tomcat
全部的Servlet过滤器都必须实现javax.servlet.Filter接口,并实现该接口中的三个方法: app
init(FilterConfig filterConfig) jsp
Servlet过滤器的初始化方法,Servlet容器建立Servlet过滤器实例后将调用该方法。该方法将读取web.xml文件中Servlet过滤器的初始化参数。 ide
该方法在tomcat启动的时候执行。doFilter(ServletRequest request, ServletResponse response, FilterChain chain) ui
该方法完成实际的过滤操做,当客户端请求方法与过滤器设置匹配的URL时,Servlet容器将先调用过滤器的doFilter方法。FilterChain用户访问后续过滤器。 编码
这里的ServletRequest和ServletResponse通常须要转换成具体的Servlet实现对于的对象,如:HttpServletRequest和HttpServletResponse。
有些过滤器比较消耗资源,因此须要防止重复过滤,能够在doFilter()方法中判断。
destroy()
Servlet容器在销毁过滤器实例前调用该方法,在该方法中释放Servlet过滤器占用的资源。
Filter的init方法中提供了一个FilterConfig对象,提供相关的操做:
如获取Filter中配置的初始化参数:<filter> <filter-name>LoginFilter</filter-name> <filter-class>cn.heimar.LoginFilter</filter-class> <init-param> <param-name>username</param-name> <param-value>admin</param-value> </init-param> </filter>在init方法中获取:
@Override public void init(FilterConfig filterConfig) throws ServletException { //获取Filter初始化参数 String username = filterConfig.getInitParameter("username"); }
ServletContext context = filterConfig.getServletContext();或者在doFilter方法中根据转换好的request获取:
HttpServletRequest req = (HttpServletRequest)request; ServletContext context = req.getSession().getServletContext();
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> cn.edu.uibe.webdev.MyFilter </filter-class> <init-param> <param-name>developer</param-name> <param-value>TongQiang</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文件
默认状况下forward方式不会被过滤。通常是须要过滤的,方式是在filter-mapping中添加<dispatcher>FORWARD</dispatcher>,该值默认是request,添加时为了防止覆盖request,须要把该值也添加。能够验证用户是否登陆。
对客户端提交的数据进行从新编码示例:
EncodingFilter.java
package cn.heimar.filter.encoding; 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.HttpServletResponse; public class EncodingFilter implements Filter { /** * 设置编码格式 */ private String encoding; /** * 是否须要强制转码 */ private boolean forceEncoding = false; @Override public void init(FilterConfig config) throws ServletException { encoding = config.getInitParameter("ENCODING"); String force = config.getInitParameter("FORCE_ENCODING"); if (force != null) forceEncoding = Boolean.valueOf(force); } @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; if ((request.getCharacterEncoding() == null || forceEncoding) && encoding != null){ request.setCharacterEncoding(encoding); } response.setCharacterEncoding(encoding); chain.doFilter(req, resp); } @Override public void destroy() { } }web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <filter> <filter-name>EncodingFilter</filter-name> <filter-class>cn.heimar.filter.encoding.EncodingFilter</filter-class> <!-- 配置编码格式 --> <init-param> <param-name>ENCODING</param-name> <param-value>utf-8</param-value> </init-param> <!-- 配置是否强转 --> <init-param> <param-name>FORCE_ENCODING</param-name> <param-value>true</param-value> </init-param> </filter> <servlet> <servlet-name>LoginServlet</servlet-name> <servlet-class>cn.heimar.filter.encoding.LoginServlet</servlet-class> </servlet> <filter-mapping> <filter-name>EncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet-mapping> <servlet-name>LoginServlet</servlet-name> <url-pattern>/login</url-pattern> </servlet-mapping> </web-app>