1. Filter也称为过滤器,是用来拦截过滤来自客户端的请求,以及服务端返回的响应资源,如Jsp、Servlet,js等,凭借过滤器能够实现某些功能。过滤器不是请求的目标资源,而是在请求被服务器处理前,以及返回响应时执行的,也就是说过滤器的拦截是双向的,而且能够有多个。html
2. Filter的编写:实现Filter接口,便可编写一个过滤器类,而后将实现的Filter类在web.xml中进行配置便可。java
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.annotation.WebFilter; public class FilterTest1 implements Filter { /** * @see Filter的销毁方法 */ public void destroy() { } /** * @see Filter的拦截处理代码 */ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { System.out.println("拦截请求"); chain.doFilter(request, response);//必须有这行代码 System.out.println("拦截响应"); } /** * @see Filter初始化方法 */ public void init(FilterConfig fConfig) throws ServletException { } }
<!-- web.xml中配置过滤器 --> <filter> <filter-name>FilterTest1</filter-name> <filter-class>servlet.filter.FilterTest1</filter-class> <!-- 配置Filter初始化参数 <init-param> <param-name></param-name> <param-value></param-value> </init-param> --> </filter> <filter-mapping> <filter-name>FilterTest1</filter-name> <url-pattern>/*</url-pattern> <!-- 路径配置与Servlet中的配置方法相同--> <!-- 其它配置 <dispatcher></dispatcher>指定过滤器所拦截的资源被服务器调用的方式,有4个参数,分别是 REQUEST,INCLUDE,FORWARD和ERROR四种,默认为REQUEST。REQUEST表示拦截全部的请求, FORWARD表示只拦截全部的转发的请求, ERROR表示只拦截错误响应,须要<error-page>标签对错误进行配置 <servlet-name></servlet-name>过滤器过滤访问指定Servlet的请求 --> </filter-mapping>
3. FilterChain:即Filter链,因为Filter能够有多个,全部它们组合起来就是Filter链,服务器依据Filter在web.xml中<filter-mapping>的配置顺序来依次调用,服务器会建立一个FilterChain对象来表示Filter链,在调用FilterChain对象的doFilter方法时,就会依照FilterChain对象中保存的Filter链依次执行下去。web
4. FilterConfig接口:获取Filter配置参数,其API主要有浏览器
5. Filter在web.xml中的其余几个配置标签的用处:缓存
1. 设置全局编码:在服务端,每一个请求对应的每一个Servlet都须要设置其编码格式放置出现乱码,因此为了减小代码量,使用Filter就能够一次性实现设置全局编码格式。安全
public class FilterTest2 implements Filter{ @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //设置post请求编码 request.setCharacterEncoding("utf-8"); //设置响应编码格式 response.setContentType("text/html;charset=utf-8"); //放行 chain.doFilter(request, response); } @Override public void destroy() {} @Override public void init(FilterConfig filterConfig) throws ServletException {} }
再将该Filter配置到web.xml中便可。服务器
2. 禁用浏览器缓存:session
public class FilterTest3 implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException {} //设置禁用浏览器缓存 @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { chain.doFilter(request, response); HttpServletResponse res=(HttpServletResponse) response; res.setHeader("Cache-Control", "no-cache"); res.setHeader("Pragma", "no-cache"); res.setDateHeader("Expires", -1); } @Override public void destroy() {} }
3. 依据ip统计网站访问次数:app
public class FilterTest4 implements Filter { @Override public void init(FilterConfig filterConfig) throws ServletException {} @Override public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //ip绑定访问次数,数据必须放在域对象中,推荐ServletContext和session对象中 HttpServletRequest req=(HttpServletRequest) request; String ip=req.getRemoteAddr(); HttpSession s=req.getSession(); if(s.isNew()){ s.setAttribute(ip, 1); }else{ s.setAttribute(ip, (Integer)s.getAttribute(ip)+1); } chain.doFilter(request, response); } @Override public void destroy() {} }
4. URL级别(粗粒度)的权限验证:利用拦截器的特性,能够经过URL来判断是否容许请求获取对应响应资源,这是一种简单的网站安全措施。先定义正确的或者说拦截器容许经过的路径有哪些(能够在web.xml中配置Filter初始化参数<init-param>来直接定义),而后在拦截器中,获取请求的路径,而后进行处理对比,判断是否匹配,匹配就继续放行,不然拦截。ide