filter过滤器(java、servlet)
什么是filter
前端发起请求,服务器接收到请求,先触发filter,做一些过滤或者限制的操作。比如没有登陆的就不能访问某某页面。
- 执行顺序:
- web.xml中元素执行的顺序filter->servlet
生命周期:
- 初始化 init()
- Filter生命周期中仅执行一次,web容器在其创建时调用
- 逻辑处理 doFilter(){chain.doFilter(request, response);}
- 可以在HttpServletRequest或者HttpServletResponse到达Servlet之前对其进行拦截
- 可以检查或修改HttpServletRequest或者HttpServletResponse的头信息、数据
- 执行权的传递 chain.doFilter(request, response)
- 在doFilter里面调用
- 是个典型的处理链,不执行chain.doFilter()就不会再执行后面的过滤器和请求的内容
- 销毁 destroy()
- 在Web容器卸载 Filter 对象之前被调用。该方法在Filter的生命周期中仅执行一次。在这个方法中,可以释放过滤器使用的资源
- 初始化 init()
作用:
- 检查用户请求,过滤非法,比如没有登录的转到登录界面
- 记录用户请求,生成日志,比如记录用户的每个请求url
- 设置统一编码格式
- 等
怎么用
声明(web.xml,可以配置参数的,比如encoding)
<filter> <filter-name>BaseFilter</filter-name> <filter-class>com.iamzhuwh.system.filter.BaseFilter</filter-class> <init-param> <param-name>encoding</param-name>//设置初始参数 <param-value>GBK</param-value> </init-param> </filter> <filter-mapping> <filter-name>BaseFilter</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher>//对转发也过滤 <dispatcher>FORWARD</dispatcher>//对转发也过滤 </filter-mapping>
写法
public class BaseFilter implements Filter { FilterConfig mConfig; public BaseFilter() { System.out.println("BaseFilter 构造"); } public void destroy() { System.out.println("BaseFilter destroy"); } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { //从web.xml中获取该Filter的配置参数 String encoding = mConfig.getInitParameter("encoding"); //输出 System.out.println("BaseFilter doFilter , getInitConfig ,encoding: "+encoding); //传递 chain.doFilter(request, response); } public void init(FilterConfig fConfig) throws ServletException { System.out.println("BaseFilter init"); mConfig = fConfig; } }
另类写法
<filter-mapping> <filter-name>TestFilter</filter-name> <servlet-name>TestServlet</servlet-name>//这个过滤器只处理对TestServlet的请求 </filter-mapping>
执行过程
- web.xml
<filter>
<filter-name>BaseFilter</filter-name>
<filter-class>com.iamzhuwh.pmc.filter.BaseFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>BaseFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>SecondFilter</filter-name>
<filter-class>com.iamzhuwh.pmc.filter.SecondFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SecondFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
输出
- 第一次请求
SecondFilter 构造
SecondFilter init
BaseFilter 构造
BaseFilter init
- 第二次请求
BaseFilter doFilter
SecondFilter doFilter
BaseFilter doFilter
SecondFilter doFilter
- 停止tomcat服务器
SecondFilter destroy
BaseFilter destroy
- 第一次请求
顺序 根据web.xml中filter-mapping的顺序从下往上加载
- 这样配置
<filter-mapping>
<filter-name>BaseFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>SecondFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
- 输出
SecondFilter
BaseFilter
- 这样配置
<filter-mapping>
<filter-name>SecondFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>BaseFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
- 输出
BaseFilter
SecondFilter
- 这样配置
- web.xml
过滤
登录检查
<filter> <filter-name>SecurityFilter</filter-name> <filter-class>xxxx</filter-class> </filter> <filter-mapping> <filter-name>SecurityFilter</filter-name> <url-pattern>/home/*</url-pattern> </filter-mapping> public void doFilter(ServletRequest request,ServletResponse response,FilterChain chain)throws IOException, ServletException { //Servlet里面的是HttpServletRequest //filter里面的是ServletRequest HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; //当用户登陆过,则把登陆信息放到session里面,以便检查 HttpSession session = req.getSession(); //这里就是获取登陆信息来检查是否已经登陆 if (session.getAttribute("username") != null) { //已登陆,跳转 chain.doFilter(request, response); } else { //没登陆,转到登陆界面取登陆 res.sendRedirect("../login.jsp"); } }