过滤器是一个java组件,可以拦截发送至某个servelet,jsp页面或静态页面的请求,可以在响应发送到客户之前进行拦截
工作原理: 过滤器类必须实现 Filter 接口,包含的方法如下: void destroy() //销毁方法 void init(FilterConfig filterConfig) throws ServletException //初始化方法 //主要的工作方法 void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException, ServletException { //这里写request的相关代码 chain.doFilter(request, resp); //这里写response的相关代码 } FilterChain chain 过滤器链FilterChain 接口用于调用过滤器链中的下一个过滤器或调用过滤器结束后的资源
过滤器链如图: 过滤器生命周期的各个阶段: 实例化:Web容器在不是web应用程序的时候对所有过滤器进行实例化 web容器回调它的无参构造方法 初始化:实例化完成之后,马上进行初始化工作 web容器回调init方法 过滤:请求路径匹配过滤器的URL映射 web容器回调 doFilter方法 --> 主要工作方法 销毁:web容器在卸载web应用之前 web容器回调 destroy方法 过滤器的实际应用: 1.对请求消息体中的数据设置统一的编码 2.阻止非法用户的请求 3.过滤非法数据 注意:过滤器使用时需要在web.xml中配置,需要在“url-pattern”标签中指明过滤的对象 如“/*”过滤项目中所有文件,代码如下:
<filter> <display-name>OurFilter</display-name> <filter-name>OurFilter</filter-name> <filter-class>nm.filter.OurFilter</filter-class> </filter> <filter-mapping> <filter-name>OurFilter</filter-name> <url-pattern>/show.do</url-pattern> </filter-mapping> 过滤器的简单实例应用我们都知道当我们百度搜索关键词的时候,搜索出的关键词会变成着重飘红。
接下来的通过过滤器,来简单的模仿百度的这种功能:
用户请求的页面
package nm.filter; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class OurServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); //这里我们向页面输出4段带"我们"的句子 out.println("我们去玩吧<br/>"); out.println("你打不过我们<br/>"); out.println("我们一起吃饭去<br/>"); out.println("看我们的儿子<br/>"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }在这里我们写一个MyWriter类继承PrintWriter类 重写里面的write方法,将原来输出字符串的方法,改变成保存字符串的方法,另外再写一个获取字符串的方法,如下:
package nm.filter; import java.io.PrintWriter; import java.io.Writer; public class MyWriter extends PrintWriter{ private StringBuilder buffer; public MyWriter(Writer out) { super(out); buffer = new StringBuilder(); } @Override public void write(String s) { buffer.append(s); } // 将write流中的内容全部转换为String public String getContent(){ return buffer.toString(); } }这里我们写一个MyResponse类继承HttpServletResponseWrapper类(HttpServletResponse接口的实现类),来获取我们上面所写的MyWriter类:
package nm.filter; import java.io.IOException; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponseWrapper; public class MyResponse extends HttpServletResponseWrapper{ private MyWriter myWriter; public MyResponse(HttpServletResponse response) { super(response); } @Override public MyWriter getWriter() throws IOException { myWriter = new MyWriter(super.getWriter()); return myWriter; } public MyWriter getMyWriter(){ return myWriter; } }完成上面两个类之后,我们来写过滤器。通过过滤器我们将用户访问的页面拦截,将原本输出的信息用我们所写的类和方法代替,将里面的关键词“我们”进行修改,之后再利用原始的类和方法将信息输出:
package nm.filter; 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.http.HttpServletResponse; public class OurFilter implements Filter { public void destroy() { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { MyResponse resp = new MyResponse((HttpServletResponse)response); chain.doFilter(request, resp); MyWriter writer = resp.getMyWriter(); if(writer!=null){ String content = writer.getContent(); String new_content = content.replace("我们","<span>我们</span>"); response.getWriter().write(new_content); } } public void init(FilterConfig fConfig) throws ServletException { } } 最终的结果如图: