Filter过滤器
简介
Filter:过滤器,通过Filter可以拦截访问web资源的请求与响应操作。
Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器。他可以拦截Jsp、Servlet、 静态图片文件、静态 html文件等,从而实现一些特殊的功能。
例如:实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
创建步骤
- 创建过滤器类并实现Filter接口
- 在web.xml文件中配置Filter
javax.servlet.Filter接口中的方法介绍:
方法 描述 init(FilterConfig fConfig) 初始化方法 doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 过滤方法 destroy() 销毁方法
1.创建过滤器类并实现Filter接口
public class Filter01 implements Filter {
public Filter01() {
}
public void init(FilterConfig fConfig) throws ServletException {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//chain过滤器链
//注意:如果拦截后不调用doFilter(),请求将无法传到下一个过滤器或服务器里
//chain.doFilter(request, response);//放行
}
public void destroy() {
}
}
2.在web.xml配置文件中配置过滤器信息
<filter>
<filter-name>Filter01</filter-name>
<filter-class>com.dream.filter.Filter01</filter-class>
</filter>
<filter-mapping>
<filter-name>Filter01</filter-name>
<url-pattern>/*</url-pattern><!-- 拦截所有请求 -->
</filter-mapping>
过滤器链
客户端对服务器请求之后,服务器在调用Servlet之前,会执行一组过滤器(多个过滤器),那么这组过滤器就称为一条过滤器链。
生命周期 - 单个过滤器
单个过滤器的生命周期:
项目启动时创建Filter01对象,调用Filter01()、init()
2. 因为此过滤器配置的是所有请求拦截,所以发送请求时,调用doFilter()
3. 项目更新或销毁时,调用destroy()
1.创建过滤器类并实现Filter接口
public class Filter01 implements Filter {
public Filter01() {
System.out.println("Filter01 - Filter01()");
}
public void init(FilterConfig fConfig) throws ServletException {
System.out.println("Filter01 - init()");
}
//doFilter(请求,响应,过滤器链)
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("Filter01执行前");
chain.doFilter(request, response);//放行
System.out.println("Filter01执行后");
}
public void destroy() {
System.out.println("Filter01 - destroy()");
}
}
2.在web.xml配置文件中配置过滤器信息
<filter>
<filter-name>Filter01</filter-name>
<filter-class>com.dream.filter.Filter01</filter-class>
</filter>
<filter-mapping>
<filter-name>Filter01</filter-name>
<url-pattern>/*</url-pattern><!-- 拦截所有请求 -->
</filter-mapping>
生命周期 - 多个过滤器
创建顺序:创建顺序无序
执行顺序:按照web.xml中配置的顺序执行
1.创建过滤器类并实现Filter接口
//----------- Filter01 -----------------------
public class Filter01 implements Filter {
public Filter01() {
System.out.println("Filter01 - Filter01()");
}
public void init(FilterConfig fConfig) throws ServletException {
System.out.println("Filter01 - init()");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("Filter01执行前");
chain.doFilter(request, response);//放行
System.out.println("Filter01执行后");
}
public void destroy() {
System.out.println("Filter01 - destroy()");
}
}
//----------- Filter02 -----------------------
public class Filter02 implements Filter {
public Filter02() {
System.out.println("Filter02 - Filter02()");
}
public void init(FilterConfig fConfig) throws ServletException {
System.out.println("Filter02 - init()");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("Filter02执行前");
chain.doFilter(request, response);//放行
System.out.println("Filter02执行后");
}
public void destroy() {
System.out.println("Filter02 - destroy()");
}
}
//----------- Filter03 -----------------------
public class Filter03 implements Filter {
public Filter03() {
System.out.println("Filter03 - Filter03()");
}
public void init(FilterConfig fConfig) throws ServletException {
System.out.println("Filter03 - init()");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
System.out.println("Filter03执行前");
chain.doFilter(request, response);//放行
System.out.println("Filter03执行后");
}
public void destroy() {
System.out.println("Filter03 - destroy()");
}
}
2.在web.xml配置文件中配置过滤器信息
<filter>
<filter-name>Filter01</filter-name>
<filter-class>com.dream.filter.Filter01</filter-class>
</filter>
<filter-mapping>
<filter-name>Filter01</filter-name>
<url-pattern>/*</url-pattern><!-- 拦截所有请求 -->
</filter-mapping>
<filter>
<filter-name>Filter02</filter-name>
<filter-class>com.dream.filter.Filter02</filter-class>
</filter>
<filter-mapping>
<filter-name>Filter02</filter-name>
<url-pattern>/*</url-pattern><!-- 拦截所有请求 -->
</filter-mapping>
<filter>
<filter-name>Filter03</filter-name>
<filter-class>com.dream.filter.Filter03</filter-class>
</filter>
<filter-mapping>
<filter-name>Filter03</filter-name>
<url-pattern>/*</url-pattern><!-- 拦截所有请求 -->
</filter-mapping>
案例一:编码过滤器
解决请求和响应乱码问题
public class EncodeFilter implements Filter {
private String encode;
public void init(FilterConfig fConfig) throws ServletException {
//获取web.xml中该过滤器的初始化属性
encode = fConfig.getInitParameter("encode");
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
resp.setContentType("text/html;charset="+encode);
req.setCharacterEncoding(encode);
chain.doFilter(req, resp);
}
public void destroy() {
}
}
<filter>
<filter-name>EncodeFilter</filter-name>
<filter-class>com.dream.filter.EncodeFilter</filter-class>
<init-param>
<param-name>encode</param-name><!-- 初始化参数名 -->
<param-value>UTF-8</param-value><!-- 初始化参数值 -->
</init-param>
</filter>
<filter-mapping>
<filter-name>EncodeFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
案例二:登录权限过滤器
解决权限的统一控制问题,没有登录,就不能直接跳转到其他详情页面
public class LoginFilter implements Filter {
public void init(FilterConfig fConfig) throws ServletException {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
//获取请求地址
String uri = req.getRequestURI();
//获取请求链接的Get数据
String queryString = request.getQueryString();
if(queryString == null){
queryString = "";
}
if(uri.contains("welcome.jsp") ||uri.contains("login.jsp")
|| uri.contains("register.jsp") || queryString.contains("action=login")
|| queryString.contains("action=register")){
chain.doFilter(request, response);
}else{
HttpSession session = req.getSession();
String user = (String) session.getAttribute("user");
if(user == null){//没登录过
resp.sendRedirect("login.jsp");
}else{//登录过
chain.doFilter(request, response);
}
}
}
public void destroy() {
}
}
<filter>
<filter-name>LoginFilter</filter-name>
<filter-class>com.dream.filter.LoginFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>LoginFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
案例三:关键字过滤器
解决文档内的一个敏感词汇
public class SensitiveWordsFilter implements Filter {
public void init(FilterConfig fConfig) throws ServletException {
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
chain.doFilter(new MyHttpServletRequestWapper((HttpServletRequest) request), response);//放行
}
public void destroy() {
}
///请求包装类
class MyHttpServletRequestWapper extends HttpServletRequestWrapper{
public MyHttpServletRequestWapper(HttpServletRequest request) {
super(request);
}
@Override
public String getParameter(String name) {
String value = super.getParameter(name);
value = value.replaceAll("傻逼", "**");
//把尖括号替换成字符尖括号,替换后不会认为是html里的尖括号符号
value = value.replaceAll("<", "<");
value = value.replaceAll(">", ">");
return value;
}
}
}
<filter>
<filter-name>SensitiveWordsFilter</filter-name>
<filter-class>com.dream.filter.SensitiveWordsFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SensitiveWordsFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
注解配置过滤器(简化配置)
@WebFilter(
value=“/*”,
initParams= {@WebInitParam(name = “encode”, value = “UTF-8”),
@WebInitParam(name = “name”, value = “java”)}
)
创建顺序:创建顺序无序
执行顺序:按照类名的顺序执行
@WebFilter(value="/*",initParams={@WebInitParam(name="encode",value="UTF-8")})
public class EncodeFilter implements Filter {
...
}