您的位置:首页 > 其它

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:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  filter