Filter的用处:
Web开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。
Filter的功能:
在HttpServletRequest到达 Servlet 之前,拦截客户的HttpServletRequest 。根据需要检查HttpServletRequest,也可以修改HttpServletRequest 头和数据。
在HttpServletResponse到达客户端之前,拦截HttpServletResponse 。根据需要检查HttpServletResponse,也可以修改HttpServletResponse头和数据。
Filter实现:
编写java类实现Filter接口,并实现其doFilter方法。
在web.xml文件中对编写的filter类进行注册,并设置它所能拦截的资源。
在web.xml中,监听器>过滤器>servlet。
<filter>
<filter-name>loginFilter</filter-name>//过滤器名称
<filter-class>com.ygj.control.loginFilter</filter-class>//过滤器类的包路径
<init—param> //可选
<param—name>参数名</param-name>//过滤器初始化参数
<param-value>参数值</param-value>
</init—pamm>
</filter>
<filter-mapping>//过滤器映射
<filter-name>loginFilter</filter-name>
<url—pattern>指定过滤器作用的对象</url-pattern>
Filter链
在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称之为一个Filter链。
web服务器根据Filter在web.xml文件中的注册顺序,决定先调用哪个Filter,当第一个Filter的doFilter方法被调用时,web服务器会创建一个代表Filter链的FilterChain对象传递给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2个filter,如果没有,则调用目标资源。
Example
1、批量设置请求编码
为了避免提交数据的中文乱码问题,需要在每次使用请求之前设置request.setCharacterEncoding("gb2312")编码格式。Filter可以批量拦截修改servlet的请求和响应。
<filter>
<filter-name>EncodingFilter</filter-name>
<filter-class>sam.EncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>EncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
/* 表示根路径下的所有请求。。 /表示根路径,* 代表所有请求。
这样,所有的请求都会先被EncodingFilter拦截,并在请求里设置上指定的gb2312编码。
public class EncodingFilter implements Filter {
public void init(FilterConfig config) throws ServletException {}
public void destroy() {}
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
request.setCharacterEncoding("gb2312");
chain.doFilter(request, response);
}
2、用户访问权限
项目中的一些页面要求用户满足了一定条件之后才能访问让用户输入帐号和密码,如果输入的信息正确就在session里做一个成功的标记,这里的成功标志就是session中的username有值。
假设要保护的页面是admin/index.jsp,编写SecurityFilter.java。
<filter>
<filter-name>SecurityFilter</filter-name>
<filter-class>sam.SecurityFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SecurityFilter</filter-name>
<url-pattern>/admin/*</url-pattern>
</filter-mapping>
public class SecurityFilter implements Filter {
public void doFilter(ServletRequest request,
ServletResponse response,
FilterChain chain)
throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
HttpSession session = req.getSession();
if (session.getAttribute("username") != null) {
chain.doFilter(request, response);
} else {
res.sendRedirect("../failure.jsp");
}
}
得到了http请求之后,可以获得请求对应的session,判断session中的username变量是否为null,如果不为null,说明用户已经登录,就可以调用doFilter继续请求访问的资源。如果为null,说明用户还没有登录,禁止用户访问,并使用页面重定向跳转到failure.jsp页面显示提示信息。
因为/failure.jsp的位置在/admin/目录的上一级,所以加上两个点才能正确跳转到failure.jsp,两个点(..)代表当前路径的上一级路径。