过滤器Filter
原创
©著作权归作者所有:来自51CTO博客作者yxkong的原创作品,请联系作者获取转载授权,否则将追究法律责任
过滤器是一个特殊的servlet,所有的过滤器都要实现Filter接口
注:定义过Filter以后一定要在web.xml中进行注册
在web.xml中进行注册
<filter>
<filter-name>注册过滤器的名称</filter-name>
<filter-class>过滤器所在类的完整名称</filter-class>
</filter>
<filter-mapping>
<filter-name>注册号的过滤器的名称</filter-name>
<url-pattern>配置拦截的资源/*拦截所有的</url-pattern>
* /* 表示拦截所有的资源
* *.jsp 表示拦截所有的jsp
* /c.jsp 表示只拦截根路径下的c.jsp
* *.do * 前不加/
<servlet-name>指定拦截的servlet名称,servlet-name标签中的值</servlet-name>
可以讲jsp页面配置成一个servlet,然后使用上面的方法拦截,访问的时候输入的是配置的servlet名称
<dispatcher>REQUEST</dispatcher>
当用户直接访问页面时,web容器将会调用过滤器,默认值
如果目标资源是通过getRequestDispatcher()的include或者forward,不会通过过滤器
<dispatcher>FORWARD</dispatcher>
当用户转发时走过滤器,
如果目标资源是通过getRequestDispatcher()的forward访问时要走过滤器
使用forward拦截的路径是要转发的那个页面的路径
<dispatcher>FORWARD</dispatcher>
如果目标资源是通过getRequestDispatcher()的include访问时要走过滤器
使用include时拦截的路径还是引入前的那个路径,不会发生变化
<dispatcher>ERROR</dispatcher>
如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用
** 可以同时配置REQUEST和FORWARD和INCLUDE和ERROR
<filter-mapping>
过滤器的生命周期
init,doFilter,destroy
过滤器中构造方法的优先级别大于init方法
构造方法执行一次,表示过滤器是单实例多线程的运行的,和servlet一样
init(FilterConfig filterConfig)
初始化,在服务器开启的时候就被初始化(由servlet容器调用)
doFilter(ServletRequest request, ServletResponse response,FilterChain chain)
在生命周期中执行多次,客户端每发送一次请求,该方法执行一次
destroy()
只在服务器关闭的时候执行一次
同一个过滤器可以配置多个映射
一个映射可以配置多个过滤器,也叫过滤器的串联
如果有多个过滤器拦截同一个资源,执行的顺序是按照过滤器在web.xml中配置的filter-mapping的先后顺序执行
案列:通过过滤器设置编码格式
web.xml配置文件中的内容
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.yxkong.filter.CharacterEncodingFilter</filter-class>
<!--配置字符编码 -->
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
<!-- 配置响应需要的MIME类型 -->
<init-param>
<param-name>contentType</param-name>
<param-value>text/html</param-value>
</init-param>
<!-- 配置是否设置响应的字符编码和MIME类型 -->
<init-param>
<param-name>isEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
过滤器中的实现
public class CharacterEncodingFilter implements Filter {
private String encoding; //接收编码
private String contentType;
private Boolean isEncoding;
public void init(FilterConfig filterConfig) throws ServletException {
this.encoding = filterConfig.getInitParameter("encoding");
this.contentType = filterConfig.getInitParameter("contentType");
String sisEncoding = filterConfig.getInitParameter("isEncoding");
if (sisEncoding != null && !"".equals(sisEncoding.trim())) {
this.isEncoding = Boolean.parseBoolean(sisEncoding);
}
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// 只对post请求有效
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
String method = req.getMethod();
if ("post".equalsIgnoreCase(method)) {
if (req.getCharacterEncoding() == null) {
if (this.encoding != null) {
req.setCharacterEncoding(this.encoding);
}
}
if (this.isEncoding) { // true 执行
if (this.encoding != null) {
response.setCharacterEncoding(this.encoding);
}
if (contentType != null) {
response.setContentType(contentType);
}
}
}
chain.doFilter(request, response);
}
public void destroy() {
}
}