Filter学习笔记
2016-11-27 12:31
323 查看
1、过滤器介绍
java中的Filter接口就是过滤器的接口,通过是实现该接口,就可以自定义过滤器。过滤器存在的目的就是对请求进行预处理和后处理。主要的过滤器有身份验证过滤器、数据压缩过滤器、加密过滤器、触发资源访问事件过滤器、图像转换过滤器、日志记录和审核过滤器、MIME-TYPE链过滤器、标记化过滤器、XSL/T过滤器(转换xml内容)。2、过滤器的执行流程:
1、客户端发送请求2、服务器接收到请求并将其交给指定Filter对请求进行预处理,并在FilterChain上传递,直到最后一个过滤器。请求在过滤器传递中,如果如果请求被被过滤器拦截,那么请求将不会到达Servlet,直接跳过步骤3。
3、Servlet对请求进行处理
4、返回过滤器,这时候可以对响应response进行修改
5、最后由服务器将处理的最后结果response返回给客户端
接下来我们再来看看Filter接口:
public interface Filter { /** * 实现类的构造方法是在服务器启动的时候执行, * 即FIilter实例是在启动服务器的时候就创建好了 * 只执行一次 */ // 在服务器启动的时候执行,执行一些初始化工作,只执行一次 public void init(FilterConfig config) throws ServletException; /** * FilterChain.doFilter(request, response)方法表示请求链 * 式向下传递(如果该Filter后面还有Filter,则将请求传给下一个Filter, * 如果没有请求,则将请求传给Servlet处理,处理过后,再返回Filter中) */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException; /** * 销毁释放资源是在服务器关闭的时候执行 */ public void destroy(); }
其中有FilterConfig接口(其默认实现类为org.apache.catalina.core.ApplicationFilterConfig)的参数,其作用是通过该接口方法,获取声明式参数(即在声明Filter时使用init-param声明的参数)的值,那么我们来看看FilterConfig接口方法:
public interface FilterConfig { // 获取Filter声明时的名字 public String getFilterName(); // 获得ServletContext实例 public ServletContext getServletContext(); // 通过参数名获取InitFilter的声明式参数 public String getInitParameter(String s); // 获取所有的声明式参数的参数名 public Enumeration getInitParameterNames(); }
FilterChain接口(其默认实现类为org.apache.catalina.core.ApplicationFilterChain)的方法如下:
public interface FilterChain{ // 其中用用为让请求在Filter链中传递,如果没有下一个Filter,那么就传给Servlet处理 public void doFilter(ServletRequest servletrequest, ServletResponse servletresponse) throws IOException, ServletException; }
3、过滤器的使用
接下来我们来看看过滤器的使用(使用过滤器处理请求编码的问题):1、实现过滤器接口
public class EncodingFilter implements Filter { private static final String DEFAULT_ENCODING = "UTF-8"; private static final String DEFAULT_BCHARSET = "ISO-8859-1"; private static final String GET_PARAMETER = "getParameter"; private static final String GET_PARAMETER_VALUES = "getParameterValues"; // private String bCharset; private String aCharset; public void init(FilterConfig config) throws ServletException { String encoding = config.getInitParameter("encoding"); String beforeCharset = config.getInitParameter("bcharset"); this.bCharset = beforeCharset == null ? DEFAULT_BCHARSET : beforeCharset; this.aCharset = encoding == null ? DEFAULT_ENCODING : encoding; } public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { // 对请求转型 final HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) resp; // 处理POST请求的参数 request.setCharacterEncoding(aCharset); response.setCharacterEncoding(aCharset); // 处理GET请求的参数,当然,这个并不是必要的 HttpServletRequest proxy = (HttpServletRequest) Proxy.newProxyInstance( request.getClass().getClassLoader(), new Class[]{HttpServletRequest.class}, new InvocationHandler() { public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String requestType = request.getMethod(); Object result = method.invoke(request, args); String methodName = method.getName(); if( GET_PARAMETER.equals(methodName) && "GET".equals(requestType) && result != null ) { String rst = (String) result; result = new String(rst.getBytes(bCharset), aCharset); } else if( GET_PARAMETER_VALUES.equals(methodName) && "GET".equals(requestType) && result != null ) { String[] rst = (String[]) result; String[] temp = new String[rst.length]; for(int i = 0; i < rst.length; i++ ) { temp[i] = new String(rst[i].getBytes(aCharset), bCharset); } result = temp; } return result; } }); chain.doFilter(proxy, response); // 传入代理对象 } public void destroy() { } }
2、过滤器配置
Filter和Servlet一样,都可以在web.xml中配置,也可以使用注解来实现配置,使用注解的优势在于操作简单,但缺点是,当有多个Filter时,其没办法控制Filter的执行顺序。
1) 在web.xml中配置
<filter> <filter-name>EncodingFilter</filter-name> <filter-class>com.yanshujie.< a8cb span class="hljs-built_in">filter.EncodingFilter</filter-class> </filter> <filter-mapping> <filter-name>EncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
在web.xml中配置时,Filter链执行的顺序为Filter配置的先后,先配置的先执行,后配置的后执行。
2) 使用注解
使用@WebFilter注解,可以实现Filter的配置,其属性和在xml中一样。在网上看到很多说使用Filter的类名来控制Filter的执行顺序,但我测试的时候还是没有实现顺序的控制。
其中,Filter可以配置的属性有:
其中dispatcherTypes的参数含义如下:
REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。
INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时(例如jsp:include 包含的页面请求),那么该过滤器将被调用。除此之外,该过滤器不会被调用。
FORWARD:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。
ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。
相关文章推荐
- 有关AutoCompleteBox组件的研究[3]_FilterMode和ItemFilter——Silverlight学习笔记[38]
- 强大的DataGrid组件[13]_字段过滤(Filter)——Silverlight学习笔记[21]
- JUint学习笔记12---对servlet和filter进行单元测试1
- ASP.NET MVC学习笔记-----Filter
- filter修改response学习笔记
- PCL学习笔记三:filter
- DirectShow 学习笔记(二)Filter
- Listener和Filter学习笔记
- Intent进阶 和 Intent-filter 学习笔记
- MonoRail学习笔记六:Filter功能使用
- 学习笔记: CIC filter及其matlab实现(转)
- 学习笔记: CIC filter及其matlab实现
- JUnit学习笔记13---对servlet和filter进行单元测试2
- JUnit学习笔记13---对servlet和filter进行单元测试2
- asp.net mvc的Routing、Controller、Filter学习笔记
- Intent进阶 和 Intent-filter 学习笔记
- Intent进阶 和 Intent-filter 学习笔记
- ASP.NET MVC学习笔记-----Filter
- Filter学习笔记
- ASP.NET MVC学习笔记-----Filter2