过滤器

文章目录

    • 过滤器
      • 用过滤器的示例
      • Filter 生命周期
      • 实际开发中 Filter 的使用场景

过滤器

Filter

功能:

1、用来拦截 传入的请求传出的响应

2、修改或以某种方式处理正在客户端和服务端之间交换的数据流。

如何使用?

与使用Servlet 类似,Filter 是 Java Web 提供的一个接口,开发者只需要定义一个类并且实现该接口即可。

小知识点:Java1.8 以后接口的一个新特性

​ 在接口中可以存在 default 修饰的方法(带方法体),且带 default 关键字的方法在接口实现类中可以不重写。

​ 我们可以看一下 有的版本 Filter 接口的源代码

public interface Filter {
      
    default void init(FilterConfig var1) throws ServletException{
      };

    void doFilter(ServletRequest var1, ServletResponse var2, FilterChain var3) throws IOException, ServletException;

    default void destroy(){
      };
}

则我们可以只重写 doFilter 方法。

用过滤器的示例

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     
    req.setCharacterEncoding("UTF-8");
    String name = req.getParameter("1");
    System.out.println(name);
}
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
     
    req.setCharacterEncoding("UTF-8");
    String name = req.getParameter("2");
    System.out.println(name);
}

在上面我们可以看到,我们在两个 servlet 中为了避免乱码问题我们分别都写了 设置字符集 的代码,这样我们有了重复代码,且在实际开发中过于麻烦

则我们可以写一个过滤器将重复代码写在过滤器中,避免重复代码的出现

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
     
    req.setCharacterEncoding("UTF-8");
    chain.doFilter(req,resp);
}

web.xml 中的配置 Filter

<filter>
    <filter-name>CharaFilterfilter-name>
    <filter-class>cf.duanzifan.filter.CharaFilterfilter-class>
filter>
<filter-mapping>
    <filter-name>CharaFilterfilter-name>
    <url-pattern>/login1url-pattern>
    <url-pattern>/login2url-pattern>
filter-mapping>

注意:doFilter 方法中处理完业务逻辑之后,必须加 chain.doFilter(req,resp); 否则请求/响应无法向后传递,一直停留在过滤器中。

Filter 生命周期

当 Tomcat 启动时,通过反射机制调用 Filter 的无参构造函数创建实例化对象,同时调用 init 方法实现初始化,doFilter 方法调用多次,当Tomcat 服务关闭的时候,调用 destory 来销毁 Filter 对象。

注意:创建 Servlet 对象是在第一次访问 Servlet 时(第一次发送请求时),创建 Filter 对象时在启动 Tomcat 时就会创建

  • 无参构造函数:只调用一次,当 Tomcat 启动时调用(Filter 一定要进行配置)
  • doFilter :调用多次,访问 Filter 的业务逻辑都写在 doFilter 中
  • destroy : 只调用一次,Tomcat 关闭时调用

同时配置多个 Filter ,Filter 的调用顺序是由 web.xml 中的配置顺序来决定的。

我们也可以通过注解的方式来配置:

@ WebFilter("/login")

实际开发中 Filter 的使用场景

  • 统一处理中文乱码

    @WebFilter(urlPatterns = {
           "/login1","/login2"})		//同时配置给多个页面
    public class CharaFilter implements Filter {
           
        public void destroy() {
           
        }
    
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
           
            req.setCharacterEncoding("UTF-8");
            chain.doFilter(req,resp);
        }
    
        public void init(FilterConfig config) throws ServletException {
           
    
        }
    
    }
    
  • 屏蔽敏感词

    package cf.duanzifan.filter;
    
    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import java.io.IOException;
    @WebFilter("/word")
    public class WordFilter implements Filter {
           
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
           
    
        }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
           
            servletRequest.setCharacterEncoding("UTF-8");
            servletResponse.setCharacterEncoding("UTF-8");
            String username = servletRequest.getParameter("username");
            String newUsername = username.replaceAll("敏感词", "***");
            servletRequest.setAttribute("username",newUsername);
            filterChain.doFilter(servletRequest,servletResponse);
        }
    
        @Override
        public void destroy() {
           
    
        }
    }
    
    package cf.duanzifan.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("/word")
    public class WordServlet extends HttpServlet {
           
        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
           
            String username =(String) req.getAttribute("username");
            req.getRequestDispatcher("word1.jsp").forward(req,resp);
        }
    }
    
    ${requestScope.username}
    
  • 控制资源的访问权限

    package cf.duanzifan.filter;
    
    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import java.io.IOException;
    
    @WebFilter("/download.jsp")
    public class DownloadFilter implements Filter {
           
    
    
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
           
    
        }
    
        @Override
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
           
            //向上转型,让req、resp 有相应的方法
            HttpServletRequest request = (HttpServletRequest) servletRequest;
            HttpServletResponse response = (HttpServletResponse) servletResponse;
            HttpSession session = request.getSession();
            String name = (String) session.getAttribute("name");
            if(name == null){
           
                //不是登录状态
                response.sendRedirect("/login.jsp");
            }else{
           
                filterChain.doFilter(request,response);
            }
        }
    
        @Override
        public void destroy() {
           
    
        }
    }
    
    response.sendRedirect("/login.jsp");
        }else{
            filterChain.doFilter(request,response);
        }
    }
    
    @Override
    public void destroy() {
    
    }
    

    }

    
    
    
    

过滤器_第1张图片

你可能感兴趣的:(JavaWeb)