一、什么是Filter?
Filter:过滤器。顾名思义就是对请求资源进行过滤 ,符合条件放行,不符合条件不放行,并且可以对目标资源访问前后进行逻辑处理.
二、实现一个简单的过滤器
1、实现Filter接口
2、配置Filter
packagecn.xy.filter;import javax.servlet.*;importjavax.servlet.annotation.WebFilter;importjava.io.IOException;
@WebFilter("/*")public class FilterDemo implementsFilter {
@Overridepublic void init(FilterConfig filterConfig) throwsServletException {
}
@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throwsIOException, ServletException {
System.out.println("Filter running----------");
filterChain.doFilter(servletRequest, servletResponse);
}
@Overridepublic voiddestroy() {
}
}
三、Filter的生命周期
1. init:在服务器启动后,会创建Filter对象,然后调用init方法。只执行一次。用于加载资源
2. doFilter:每一次请求被拦截资源时,会执行。执行多次
3. destroy:在服务器关闭后,Filter对象被销毁。如果服务器是正常关闭,则会执行destroy方法。只执行一次。用于释放资源
四、Filter的API
1、init(FilterConfig)
config代表Filter对象的配置信息的对象,内部封装是该filter的配置信息.
String getFilterName();//得到filter的名称。
String getInitParameter(String name);//返回在部署描述中指定名称的初始化参数的值。如果不存在返回null.
Enumeration getInitParameterNames();//返回过滤器的所有初始化参数的名字的枚举集合。
public ServletContext getServletContext();//返回Servlet上下文对象的引用。
2、destory()
filter对象销毁时执行
3、doFilter(ServletRequest,ServletResponse,FilterChain)
FilterChain:过滤器链对象,通过该对象的doFilter方法可以放行该请求
ServletRequest/ServletResponse:每次在执行doFilter方法时 web容器负责创建一个request和一个response对象作为doFilter的参数传递进来。该request个该response就是在访问目标资源的service方法时的request和response。
五、Filter的配置
拦截路径配置:
1. 具体资源路径: /index.jsp 只有访问index.jsp资源时,过滤器才会被执行
2. 拦截目录: /user/*访问/user下的所有资源时,过滤器都会被执行
3. 后缀名拦截: *.jsp访问所有后缀名为jsp资源时,过滤器都会被执行
4. 拦截所有资源:/*访问所有资源时,过滤器都会被执行
拦截方式配置:资源被访问的方式
dispatcherTypes属性:
1. REQUEST:默认值。浏览器直接请求资源
2. FORWARD:转发访问资源
3. INCLUDE:包含访问资源
4. ERROR:错误跳转资源
5. ASYNC:异步访问资源
1、web.xml方式配置
与servlet的配置差不多
FilterDemo
cn.xy.filter.FilterDemo
REQUEST
FORWARD
2、注解方法配置
@WebFilter(urlPatterns = {"/*","*.jsp"},dispatcherTypes = {DispatcherType.ERROR,DispatcherType.FORWARD})
六、过滤器链(配置多个过滤器)
执行顺序:如果有两个过滤器:过滤器1和过滤器2
1. 过滤器1
2. 过滤器2
3. 资源执行
4. 过滤器2
5. 过滤器1
过滤器先后顺序问题:
1. 注解配置:按照类名的字符串比较规则比较,值小的先执行
* 如: AFilter 和 BFilter,AFilter就先执行了。
2. web.xml配置: 谁定义在上边,谁先执行
七、全局解决中文乱码Demo
packagecn.xy.filter;import javax.servlet.*;importjavax.servlet.annotation.WebFilter;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletRequestWrapper;importjavax.servlet.http.HttpServletResponse;importjava.io.IOException;importjava.io.UnsupportedEncodingException;importjava.util.Map;
@WebFilter("/*")public class EncodingFilter implementsFilter {private FilterConfig filterConfig = null;private String encode = null;private boolean isNotEncode = true;
@Overridepublic void init(FilterConfig filterConfig) throwsServletException {this.filterConfig =filterConfig;
encode= filterConfig.getInitParameter("encode") == null ?"utf-8":filterConfig.getInitParameter("encode");
}
@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throwsIOException, ServletException {
HttpServletRequest request=(HttpServletRequest) servletRequest;
HttpServletResponse response=(HttpServletResponse) servletResponse;//针对post()
request.setCharacterEncoding("utf-8");
response.setContentType("text/html;charset=" +encode);//使用Wrapper模式、GET()
MyHttpRequest myRequst = newMyHttpRequest(request);
filterChain.doFilter(myRequst,servletResponse);
System.out.println("------");
}
@Overridepublic voiddestroy() {
}class MyHttpRequest extendsHttpServletRequestWrapper {private HttpServletRequest httpServletRequest = null;publicMyHttpRequest(HttpServletRequest request) {super(request);this.httpServletRequest =request;
}
@Overridepublic MapgetParameterMap() {
Map map =httpServletRequest.getParameterMap();if(isNotEncode) {for (Map.Entrym : map.entrySet()) {
String[] v=m.getValue();for (int i = 0; i < v.length; i++) {try{
v[i]= new String(v[i].getBytes("iso8859-1"), encode);
}catch(UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}
isNotEncode= false; //第二次是查询缓存 防止再次编码
}returnmap;
}
@OverridepublicString[] getParameterValues(String name) {return this.getParameterMap().get(name);
}
@OverridepublicString getParameter(String name) {return getParameterValues(name) == null ? null : getParameterValues(name)[0];
}
}
}