一、过滤器简介:
过滤器(Filter)是JavaWeb中最常用到的技术,常用于URL的权限访问控制,编码转换,错误页面跳转,拦截过滤图片,html文件,指定文字等功能。
二、过滤器如何工作:
大致过程:在客户端发送一个请求时,即HttpServletRequest或HttpServletResponse到达Servlet之前,Filter会将其拦截下来,并对其进行数据检查和相应的过滤后,再进行放行或相应的跳转,然后再生成响应返回时,Filter再次对服务器的响应进行最后处理并到达视图层,总的来讲: 请求 ——> 过滤 ——> 响应 ——> 过滤 ——> 显示。 在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称之为一个Filter链。web服务器根据Filter在web.xml文件中的注册顺序,决定先调用哪个Filter,如果使用的是注解方式来注册,那么执行顺序应该是过滤器的文件名的首字母的顺序。当第一个Filter的doFilter方法被调用时,web服务器会创建一个代表Filter链的FilterChain对象传递给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2个filter,如果没有,则调用目标资源。
生命周期:Filter接口实现类中要实现三个方法:init方法,doFilter方法,destroy方法。
(1) init(FilterConfig):
初始化接口,在web服务器启动时Filter初始化被调用,它与Servlet的init方法的作用是一样的,FilterConfig能得到容器的初始化参数及相应的一些数据。
1 String getFilterName();//得到filter的名称。 2 String getInitParameter(String name);//返回在部署描述中指定名称的初始化参数的值。如果不存在返回null. 3 Enumeration getInitParameterNames();//返回过滤器的所有初始化参数的名字的枚举集合。 4 public ServletContext getServletContext();//返回Servlet上下文对象的引用。(2) doFilter(ServletRequest, ServletResponse, FilterChain):
每个用户的请求进来时这个方法都会被调用,这个方法会在Servlet的service方法之前被调用,是过滤器的主体。FilterChain代表当前的整个请求链,通过调用FilterChain.doFilter可以将请求继续传递下去,如何拦截这个请求,只需不调用该方法,那么这个请求就直接返回。所以Filter是一种责任链设计模式。doFilter可以做到:调用目标资源之前,让一段代码执行。 是否调用目标资源(即是否让用户访问web资源)。web服务器在调用doFilter方法时,会传递一个filterChain对象进来,filterChain对象是filter接口中最重要的一个对象,它也提供了一个doFilter方法,开发人员可以根据需求决定是否调用此方法,调用该方法,则web服务器就会调用web资源的service方法,即web资源就会被访问,否则web资源不会被访问。
(3) destroy
Filter对象创建后会驻留在内存,当web应用移除或服务器停止时才销毁,当Filter对象被销毁时,这个方法被调用。值得注意的时,根据上面所提到的响应时还会进行一次过滤,所以当Web容器调用这个方法之后,容器还会再调用一次doFilter方法。
三、简单实例: 在这里我们用的是Servlet3.0新增的注解方式来代替以前使用的xml配置:
package Filter; import javax.servlet.*; import javax.servlet.annotation.WebFilter; import javax.servlet.annotation.WebInitParam; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; @WebFilter(filterName = "LoginFilter", urlPatterns = "/*", //对所有url进行过滤 initParams = {@WebInitParam(name = "url", value = "index.jsp;LoginServlet;error.jsp"), @WebInitParam(name = "encoding", value = "UTF-8")}) public class LoginFilter implements Filter { private FilterConfig config = null; public void destroy() { config = null; } public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException { HttpServletRequest request = (HttpServletRequest)req; HttpServletResponse response = (HttpServletResponse)resp; //编码转换过滤 String charset = config.getInitParameter("encoding"); request.setCharacterEncoding(charset); response.setCharacterEncoding(charset); //对登陆页面及指定页面不进行过滤 String url = config.getInitParameter("url"); String[] urlList = url.split(";"); for (String urlFilt : urlList) { if (request.getRequestURI().indexOf(urlFilt) != -1) { chain.doFilter(req, resp); return; } } //判断用户是否登录 if (request.getSession().getAttribute("username") != null) { chain.doFilter(req, resp); } else { response.sendRedirect("../index.jsp"); } } public void init(FilterConfig config) throws ServletException { this.config = config; //获取初始化参数 } }
一些知识来源:https://www.cnblogs.com/coderland/p/5902878.html
转载于:https://www.cnblogs.com/chenloveslife/p/8946260.html