1. 过滤器简介:
在一个Web应用中,有很多web组件,它们都用于响应特定的客户请求。不过,在这些web组件响应客户请求的过程中,可能都会完成一些相同的操作。如果在多个web组件中编写完成同样操作的程序代码,显然会导致重复编码,从而降低开发效率和软件的可维护性。
为了解决上述问题,过滤器Filter应运而生。它是在Java Servlet 2.3规范中出现的技术,Filter可认为是Servlet的一种加强版。过滤器能够对一部分客户请求先进行预处理,然后再把请求转发给相应的web组件,等到web组件生成了响应结果后,过滤器还能对响应结果进行检查和修改,然后再把修改后的响应结果发送给客户。各个web组件中的相同操作可以放到同一个过滤器中来完成,这样就能减少重复编码。
2. 过滤器的过滤功能:
1. 过滤器能够在目标web组件被调用之前检查ServletRequest对象,修改请求头和请求正文的内容,或者对请求进行预处理操作。 2. 过滤器能够在目标web组件被调用之后检查ServletResponse对象,修改响应头和响应正文。3. 过滤器Filter的常见种类:
1. 用户授权的Filter:Filter负责检查用户请求,根据请求过滤用户的非法请求。 2. 日志Filter:详细记录某些特殊的用户请求。 3. 负责解码的Filter:包括对非标准编码的请求进行解码。 4. 能改变XML内容的XSLT Filter等。 5. Filter可负责拦截多个请求或响应,一个请求或响应也可被多个Filter拦截。4. 过滤器Filter的实现:
创建Filter必须实现javax.servlet.Filter接口,在该接口中定义了如下三个方法:
1. void init(FilterConfig config):用于完成Filter的初始化。 2. void destroy():用于Filter销毁前,完成某些资源的回收。 3. void doFilter(ServletRequest request,ServletResponse response,FilterChain chain):实现过滤功能,该方法就是对每个请求及响应增加的额外处理。实现doFilter()方法就可实现对用户请求进行预处理,也可实现对服务器响应进行后处理。它们的分界线为是否调用了 chain.doFilter(...)。执行该方法之前,即对用户请求进行预处理,执行该方法之后,即对服务器响应进行后处理。
Filter的配置:
<filter> <filter-name>XXX</filter-name> <filter-class>XXX</filter-class> </filter> <filter-mapping> <filter-name>XXX</filter-name> <url-pattern>XXX</url-pattern> </filter-mapping>url-pattern配置Filter拦截的URL模式。Filter可以同时拦截多个请求,因此在配置Filter的URL模式时通常会使用模式字符串。譬如" /* "即表示该Filter会拦截所有用户请求。
看个例子吧:
各文件源代码:
web.xml:
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <filter> <filter-name>CommentContentFilter</filter-name> <filter-class>web.CommentContentFilter</filter-class> <init-param> <param-name>illegalString</param-name> <param-value>sex,gay</param-value> </init-param> </filter> <filter> <filter-name>CommentSizeFilter</filter-name> <filter-class>web.CommentSizeFilter</filter-class> </filter> <filter-mapping> <filter-name>CommentSizeFilter</filter-name> <url-pattern>/comment</url-pattern> </filter-mapping> <filter-mapping> <filter-name>CommentContentFilter</filter-name> <url-pattern>/comment</url-pattern> </filter-mapping> <servlet> <servlet-name>CommentServlet</servlet-name> <servlet-class>web.CommentServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>CommentServlet</servlet-name> <url-pattern>/comment</url-pattern> </servlet-mapping> </web-app>comment.jsp :
<%@ page contentType="text/html;charset=UTF-8" pageEncoding="UTF-8"%> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Insert title here</title> </head> <body> <form action="comment" method="post"> <input type="text" name="comment"><input type="submit" value="confirm"> </form> </body> </html>CommentServlet.java:
public class CommentServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter pw=response.getWriter(); String comment=request.getParameter("comment"); pw.println("<h3>"+comment+"</h3>"); } }CommentContentFilter.java:
public class CommentContentFilter implements Filter{ private FilterConfig config; @Override public void destroy() { System.out.println("destroy..."); } @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { System.out.println("Content doFilter..."); HttpServletRequest request=(HttpServletRequest)req; HttpServletResponse response=(HttpServletResponse)res; String comment=request.getParameter("comment"); String illegalString=config.getInitParameter("illegalString"); System.out.println(illegalString);//sex,gay PrintWriter pw=response.getWriter(); String[] illegals=illegalString.split(","); for(int i=0;i<illegals.length;i++){ String illegal=illegals[i]; if(comment.indexOf(illegal)>=0){ pw.println("<h3>illegal string...</h3>"); return; } } chain.doFilter(request, response); pw.println("<h3>Content doFilter has executed...</h3>"); } @Override public void init(FilterConfig config) throws ServletException { this.config=config; System.out.println("init..."); } }CommentSizeFilter.java:
public class CommentSizeFilter implements Filter { @Override public void destroy() { } @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { System.out.println("Size doFilter..."); HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; PrintWriter pw=response.getWriter(); String comment = request.getParameter("comment"); if(comment.length()>10){ pw.println("<h3>Comment's size illegal...</h3>"); return; } chain.doFilter(request, response); pw.println("<h3>Size doFilter has executed...</h3>"); } @Override public void init(FilterConfig filterConfig) throws ServletException { } }这两个过滤器会过滤长度超过10的评论以及含sex,gay等字眼的评论!