过滤器

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等字眼的评论!







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值