WEB中的Filter技术
Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
Filter开发分为二个步骤:
1.编写java类实现Filter接口,并实现其doFilter方法。
2.在 web.xml 文件中使用和元素对编写的filter类进行注册,并设置它所能拦截的资源。
<java>
import java.io.IOException;
import java.io.UnsupportedEncodingException;
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.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
/**
*
* @author
* @data
* @version 1.0
* @See功能介绍 :解析字符编码
*/
public class CharEncodingFilter implements Filter {
private FilterConfig config = null;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.config = filterConfig;
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
if ("get".equalsIgnoreCase(httpRequest.getMethod())) {
System.out.println("get请求");
GetHttpServletRequest wrapper = new GetHttpServletRequest(httpRequest, "UTF-8");
System.out.println("----请求被" + this.config.getFilterName() + "过滤----");
chain.doFilter(wrapper, response);
System.out.println("----响应被" + this.config.getFilterName() + "过滤----");
} else {
System.out.println("post请求");
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
System.out.println("----请求被" + this.config.getFilterName() + "过滤----");
//执行下一个过滤器(如果有的话,否则执行目标servlet)
chain.doFilter(request, response);
System.out.println("----响应被" + this.config.getFilterName() + "过滤----");
}
}
@Override
public void destroy() {
System.out.println(this.config.getFilterName() + "被销毁");
this.config = null;
}
}
//定义GetHttpServletRequest类
class GetHttpServletRequest extends HttpServletRequestWrapper {
private String encoding;
public GetHttpServletRequest(HttpServletRequest request) {
super(request);
}
public GetHttpServletRequest(HttpServletRequest request, String encoding) {
super(request);
this.encoding = encoding;
}
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
if (null != value) {
try {
// tomcat默认以ISO8859-1处理GET传来的参数。把tomcat上的值用ISO8859-1获取字节流,再转换成UTF-8字符串
value = new String(value.getBytes("ISO8859-1"), encoding);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
return value;
}
}
</java>
2.Filter的部署
Filter的部署分为两个步骤:
1、注册Filter
开发好Filter之后,需要在web.xml文件中进行注册,这样才能够被web服务器调用
在web.xml文件中注册Filter范例:
<filter>
<description>FilterDemo02过滤器</description>
<filter-name>FilterDemo02</filter-name>
<filterclass>com.mis.filter.FilterDemo02</filter-class>
<!--配置FilterDemo02过滤器的初始化参数-->
<init-param>
<description>配置FilterDemo02过滤器的初始化参数</description>
<param-name>name</param-name>
<param-value>gacl</param-value>
</init-param>
<init-param>
<description>配置FilterDemo02过滤器的初始化参数</description>
<param-name>like</param-name>
<param-value>java</param-value>
</init-param>
</filter>
<description>
用于添加描述信息,该元素的内容可为空,<description>
可以不配置。
用于为过滤器指定一个名字,该元素的内容不能为空。
元素用于指定过滤器的完整的限定类名。
元素用于为过滤器指定初始化参数,它的子元素指定参数的名字,指定参数的值。在过滤器中,可以使用FilterConfig接口对象来访问初始化参数。如果过滤器不需要指定初始化参数,那么元素可以不配置。
2、映射Filter
在web.xml文件中注册了Filter之后,还要在web.xml文件中映射Filter
<!--映射过滤器-->
<filter-mapping>
<filter-name>FilterDemo02</filter-name>
<!--“/*”表示拦截所有的请求 -->
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
元素用于设置一个 Filter 所负责拦截的资源。一个Filter拦截的资源可通过两种方式来指定:Servlet 名称和资源访问的请求路径
子元素用于设置filter的注册名称。该值必须是在元素中声明过的过滤器的名字
设置 filter 所拦截的请求路径(过滤器关联的URL样式)
指定过滤器所拦截的Servlet名称。
指定过滤器所拦截的资源被 Servlet 容器调用的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默认REQUEST。用户可以设置多个 子元素用来指定 Filter 对资源的多种调用方式进行拦截。如下:
<filter-mapping>
<filter-name>testFilter</filter-name>
<url-pattern>/index.jsp</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</filter-mapping>
子元素可以设置的值及其意义:
- REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。 - INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
- FORWARD:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。
- ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。