过滤器Filter
Web应用中一些通用处理,可以使用过滤器实现。本章将学习过滤器的基本概念,并学习Servlet API中的Filter、FilterConfig、FilterChain接口的作用和使用。另外通过实例展示在实际应用中如何开发并使用过滤器。
过滤器的概述:
过滤器运行在服务器端,遵守一定的编码规范
过滤器必须实现Servlet API中的Filter接口
过滤器用来执行应用中通用处理的程序,如记录日志、设置编码格式等等
在Web应用中,往往需要一些通用的处理,例如,访问某些资源前必须保证用户成功登陆过;访问某些资源后必须在日志文件中访问日志;访问某些资源之前必须验证用户的权限等。如果把这些通用的处理编写在每一个需要的资源文件中,代码就很冗沉,不好管理。而且只要需要修改,就得修改文件中的相关代码,造成维护困难。
过滤器就是用来执行这些通用处理的程序。可以提高代码的重用性和可维护性。
过滤器有关的API:
Filter:
void destroy()
Called by the web container to indicate to a filter that it is being taken out of service.
void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
The doFilter method of the Filter is called by the container each time a request/response pair is passed through the chain due to a client request for a resource at the end of the chain. filter进行过滤操作的方法是最重要的方法。方法体中可以对request对象和response对象进行预处理。其中FilterChain可以将处理后的request和response对象传递到过滤链上的下一个资源,可能是下一个filter,也可能是目标资源
void init(FilterConfig filterConfig)
Called by the web container to indicate to a filter that it is being placed into service. 对filter对象进行初始化,仅在容器实例化filter对象结束后调用一次,参数FilterConfig可以获取filter的初始化参数
FilterChain:
void doFilter(ServletRequest request, ServletResponse response)
Causes the next filter in the chain to be invoked, or if the calling filter is the last filter in the chain, causes the resource at the end of the chain to be invoked. 将请求和响应传递到下一个资源
FilterConfig:
String getFilterName()
Returns the filter-name of this filter as defined in the deployment descriptor.
String getInitParameter(String name)
Returns a String containing the value of the named initialization parameter, or null if the parameter does not exist. 获取初始化参数
Enumeration getInitParameterNames()
Returns the names of the filter's initialization parameters as an Enumeration of String objects, or an empty Enumeration if the filter has no initialization parameters.
ServletContext getServletContext()
Returns a reference to the ServletContext in which the caller is executing.
简单的字符编码过滤器:
package cn.itcast.utils.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.HttpServletResponse; public class CharacterEncodingFilter implements Filter{ public void destroy() { } public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain chain) throws IOException, ServletException { HttpServletRequest request=(HttpServletRequest) arg0; HttpServletResponse response=(HttpServletResponse) arg1; request.setCharacterEncoding("utf-8"); request.setCharacterEncoding("utf-8"); chain.doFilter(request, response); } public void init(FilterConfig arg0) throws ServletException { } } <filter> <filter-name>CharacterEndoding</filter-name> <filter-class>cn.itcast.utils.filter.CharacterEncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>CharacterEndoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
过滤器的配置:
1.初始化参数
在web.xml中,可以为一个过滤器配置初始化参数。一个过滤器可以配置多个初始化参数,该参数只能在该过滤器中使用,其他的过滤器无法使用,通过FilterConfig的getInitParameter方法可以获取初始化参数。
<filter> <filter-name>CharacterEncoding</filter-name> <filter-class>cn.itcast.utils.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> package cn.itcast.utils.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.HttpServletResponse; public class CharacterEncodingFilter implements Filter{ private String encoding; public void destroy() { } public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain chain) throws IOException, ServletException { HttpServletRequest request=(HttpServletRequest) arg0; HttpServletResponse response=(HttpServletResponse) arg1; System.out.println(encoding); request.setCharacterEncoding(encoding); request.setCharacterEncoding(encoding); chain.doFilter(request, response); } public void init(FilterConfig filterConfig) throws ServletException { this.encoding=filterConfig.getInitParameter("encoding"); //System.out.println(encoding); } }
2.<filter-mapping>中可以使用<servlet-name>指定过滤内容。过滤器的执行顺序和在web.xml中的顺序一致。
这里注意一点:
使用<url-pattern>配置的比使用<servlet-name>配置的优先级更高
<filter> <filter-name>TestFilter</filter-name> <filter-class>cn.itcast.service.filter.TestFilter</filter-class> </filter> <filter-mapping> <filter-name>TestFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter> <filter-name>CharacterEncoding</filter-name> <filter-class>cn.itcast.utils.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>utf-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>CharacterEncoding</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> package cn.itcast.service.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 TestFilter implements Filter{ public void destroy() { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("doFilter调用前,现在执行的是第一个过滤器"); chain.doFilter(request, response); System.out.println("doFilter调用后,现在执行的是第一个过滤器"); } public void init(FilterConfig filterConfig) throws ServletException { } } package cn.itcast.utils.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.HttpServletResponse; public class CharacterEncodingFilter implements Filter{ private String encoding; public void destroy() { } public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain chain) throws IOException, ServletException { HttpServletRequest request=(HttpServletRequest) arg0; HttpServletResponse response=(HttpServletResponse) arg1; System.out.println("doFilter方法调用前,"+encoding); request.setCharacterEncoding(encoding); request.setCharacterEncoding(encoding); chain.doFilter(request, response); System.out.println("doFilter方法调用后"+encoding); } public void init(FilterConfig filterConfig) throws ServletException { this.encoding=filterConfig.getInitParameter("encoding"); //System.out.println(encoding); } }
3.使用<dispatcher>设置过滤器过滤的url
request:请求方式,是一种默认的方式。即不配置dispatcher选项时,默认过滤request方式请求的URL,包括在地址栏输入url,表单提交,超级链接,响应重定向的方式。如果需要过滤器过滤其他访问方式的URL,可以通过配置dispatcher选项方式实现。
dispatcher有4个值:
REQUEST:请求方式,是一种默认的方式,如果配置了dispatcher选项,需要显式指定才能生效。
FORWARD:转发方式
INCLUDE:包含方式
ERROR:错误方式