简介
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()
因为此过滤器配置的是所有请求拦截,所以发送请求时,调用doFilter()
项目更新或销毁时,调用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 { ... }