一、定义

应用场景
自动登录
统一设置编码格式
访问权限控制
敏感字符过滤等
二、创建Filter
1、配置web.xml
<filter>
<filter-name>first</filter-name>
<filter-class>net.pp.Filter.FirstFilter</filter-class>
<init-param>
<param-name>param</param-name>
<param-value>value</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>first</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
2、实现Filter接口
FirstFilter.java
package net.pp.Filter;
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 java.io.IOException;
public class FirstFilter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
String filterName = filterConfig.getFilterName();
String initParameter = filterConfig.getInitParameter("param");
ServletContext servletContext = filterConfig.getServletContext();
System.out.println(filterName+"--"+initParameter);
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("FirstFilter已经执行拦截!");
//解除拦截
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
}
}
3、在Servlet中测试
TestFilter
package net.pp.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(name = "TestServlet" ,urlPatterns = "/testFilter")
public class TestServlet extends HttpServlet {
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("test/html;charset=utf-8");
response.getWriter().write("testFilter已经被访问了!");
}
}
结果:
三、配置Filter
1)url-Pattern配置
配置要拦截的资源
- 以指定资源匹配。例如
"/index.jsp"
- 以目录匹配。例如
"/servlet/*"
- 以后缀名匹配,例如
"*.jsp"
- 通配符,拦截所有web资源。
"/*"
<filter-mapping>
<filter-name>first</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
2)dispatcherTypes **
配置拦截的类型,可配置多个。
FORWARD,//转发的
INCLUDE,//包含在页面的
REQUEST,//请求的
ASYNC,//异步的
ERROR;//出错的
3)注解方式配置
package filter;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import java.io.IOException;
@WebFilter(filterName = "CharsetFilter",
urlPatterns = "/*",/*通配符(*)表示对所有的web资源进行拦截*/
initParams = {
@WebInitParam(name = "charset", value = "utf-8")/*这里可以放一些初始化的参数*/
})
public class CharsetFilter implements Filter {
private String filterName;
private String charset;
public void destroy() {
/*销毁时调用*/
System.out.println(filterName + "销毁");
}
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
/*过滤方法 主要是对request和response进行一些处理,然后交给下一个过滤器或Servlet处理*/
System.out.println(filterName + "doFilter()");
req.setCharacterEncoding(charset);
resp.setCharacterEncoding(charset);
chain.doFilter(req, resp);
}
public void init(FilterConfig config) throws ServletException {
/*初始化方法 接收一个FilterConfig类型的参数 该参数是对Filter的一些配置*/
filterName = config.getFilterName();
charset = config.getInitParameter("charset");
System.out.println("过滤器名称:" + filterName);
System.out.println("字符集编码:" + charset);
}
}
多个Filter的执行顺序
在我们的请求到达Servle之间是可以经过多个Filter的,一般来说,建议Filter之间不要有关联,各自处理各自的逻辑即可。
如果一定要确保执行顺序,就要对配置进行修改了,执行顺序如下
在web.xml中,filter执行顺序跟<filter-mapping>的顺序有关,先声明的先执行
使用注解配置的话,filter的执行顺序跟名称的字母顺序有关,例如AFilter会比BFilter先执行
如果既有在web.xml中声明的Filter,也有通过注解配置的Filter,那么会优先执行web.xml中配置的Filter