1. Filter的简单使用
1. Filter也称为过滤器,是用来拦截过滤来自客户端的请求,以及服务端返回的响应资源,如Jsp、Servlet,js等,凭借过滤器可以实现某些功能。过滤器不是请求的目标资源,而是在请求被服务器处理前,以及返回响应时执行的,也就是说过滤器的拦截是双向的,并且可以有多个。
2. Filter的编写:实现Filter接口,即可编写一个过滤器类,然后将实现的Filter类在web.xml中进行配置即可。
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.annotation.WebFilter;
public class FilterTest1 implements Filter {
/**
* @see Filter的销毁方法
*/
public void destroy() {
}
/**
* @see Filter的拦截处理代码
*/
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("拦截请求");
chain.doFilter(request, response);//必须有这行代码
System.out.println("拦截响应");
}
/**
* @see Filter初始化方法
*/
public void init(FilterConfig fConfig) throws ServletException {
}
}
<!-- web.xml中配置过滤器 -->
<filter>
<filter-name>FilterTest1</filter-name>
<filter-class>servlet.filter.FilterTest1</filter-class>
<!-- 配置Filter初始化参数
<init-param>
<param-name></param-name>
<param-value></param-value>
</init-param>
-->
</filter>
<filter-mapping>
<filter-name>FilterTest1</filter-name>
<url-pattern>/*</url-pattern>
<!-- 路径配置与Servlet中的配置方法相同-->
<!-- 其它配置
<dispatcher></dispatcher>指定过滤器所拦截的资源被服务器调用的方式,有4个参数,分别是
REQUEST,INCLUDE,FORWARD和ERROR四种,默认为REQUEST。REQUEST表示拦截所有的请求,
FORWARD表示只拦截所有的转发的请求,
ERROR表示只拦截错误响应,需要<error-page>标签对错误进行配置
<servlet-name></servlet-name>过滤器过滤访问指定Servlet的请求
-->
</filter-mapping>
3. FilterChain:即Filter链,由于Filter可以有多个,所有它们组合起来就是Filter链,服务器依据Filter在web.xml中<filter-mapping>的配置顺序来依次调用,服务器会创建一个FilterChain对象来表示Filter链,在调用FilterChain对象的doFilter方法时,就会依照FilterChain对象中保存的Filter链依次执行下去。
4. FilterConfig接口:获取Filter配置参数,其API主要有
- public String getFilterName():获取Filter名,即<filter-name>FilterTest1</filter-name>
- public ServletContext getServletContext():获取Filter所在的web项目名
- public String getInitParameter(String name):依据参数名,获取配置Filter中的一些初始化参数值
- public Enumeration<String> getInitParameterNames():获取Filter配置中所有参数的名称
5. Filter在web.xml中的其他几个配置标签的用处:
2. Filter的应用
1. 设置全局编码:在服务端,每个请求对应的每个Servlet都需要设置其编码格式放置出现乱码,所以为了减少代码量,使用Filter就可以一次性实现设置全局编码格式。
public class FilterTest2 implements Filter{
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
//设置post请求编码
request.setCharacterEncoding("utf-8");
//设置响应编码格式
response.setContentType("text/html;charset=utf-8");
//放行
chain.doFilter(request, response);
}
@Override
public void destroy() {}
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
}
再将该Filter配置到web.xml中即可。
2. 禁用浏览器缓存:
public class FilterTest3 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
//设置禁用浏览器缓存
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
chain.doFilter(request, response);
HttpServletResponse res=(HttpServletResponse) response;
res.setHeader("Cache-Control", "no-cache");
res.setHeader("Pragma", "no-cache");
res.setDateHeader("Expires", -1);
}
@Override
public void destroy() {}
}
3. 依据ip统计网站访问次数:
public class FilterTest4 implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
//ip绑定访问次数,数据必须放在域对象中,推荐ServletContext和session对象中
HttpServletRequest req=(HttpServletRequest) request;
String ip=req.getRemoteAddr();
HttpSession s=req.getSession();
if(s.isNew()){
s.setAttribute(ip, 1);
}else{
s.setAttribute(ip, (Integer)s.getAttribute(ip)+1);
}
chain.doFilter(request, response);
}
@Override
public void destroy() {}
}
4. URL级别(粗粒度)的权限验证:利用拦截器的特性,可以通过URL来判断是否允许请求获取对应响应资源,这是一种简单的网站安全措施。先定义正确的或者说拦截器允许通过的路径有哪些(可以在web.xml中配置Filter初始化参数<init-param>来直接定义),然后在拦截器中,获取请求的路径,然后进行处理对比,判断是否匹配,匹配就继续放行,否则拦截。