8.过滤器Filter

2023-04-11 13:06:26

1.1 现有问题

在以往的Servlet中,有没有冗余的代码,多个Servlet都要进行编写。

1.2 概念

过滤器(Filter)是处于客户端与服务器目标资源之间的一道过滤技术。

过滤器

 

1.3 过滤器作用

  • 执行地位在Servlet之前,客户端发送请求时,会先经过Filter,再到达目标Servlet中;响应时,会根据执行流程再次反向执行Filter

  • 可以解决多个Servlet共性代码的冗余问题(例如:乱码处理、登录验证)

1.4 编写过滤器

Servlet API中提供了一个Filter接口,开发人员编写一个Java类实现了这个接口即可,这个Java类称之为过滤器(Filter)

1.4.1 实现过程

  • 编写Java类实现Filter接口

  • 在doFilter方法中编写拦截逻辑

  • 设置拦截路径

 
@WebFilter("/myservlet1")//过滤路径
public class MyFilter1 implements Filter {

    //初始化过滤器
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("过滤器初始化了........init...  "+filterConfig);
    }

    //执行过滤
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("过滤前........doFilter ");
        //放行
        chain.doFilter(request, response);

        System.out.println("过滤后.......doFilter");

    }

    //销毁
    @Override
    public void destroy() {
        System.out.println("销毁了.....destroy");
    }
}

1.5 过滤器配置

1.5.1 注解配置

在自定义的Filter类上使用注解@WebFilter(value=“/过滤目标资源”)

1.5.2 xml配置

<!--过滤器的xml配置  -->
  <filter>
  <!--名称-->
    <filter-name>sf</filter-name>
    <!--过滤器类全称-->
    <filter-class>com.qf.web.filter.SecondFilter</filter-class>
  </filter>
 <!--映射路径配置-->
  <filter-mapping>
     <!--名称-->
    <filter-name>sf</filter-name>
     <!--过滤的url匹配规则和Servlet类似-->
    <url-pattern>/*</url-pattern>
  </filter-mapping>

1.5.3 过滤器路径

过滤器的过滤路径通常有三种形式:

精确过滤匹配 ,比如/index.jsp   /myservlet1

后缀过滤匹配,比如*.jsp、*.html、*.jpg

通配符过滤匹配/*,表示拦截所有。注意过滤器不能使用/匹配。  (常用)
    /aaa/bbb/* 允许

1.6 过滤器链和优先级

1.6.1 过滤器链

客户端对服务器请求之后,服务器调用Servlet之前会执行一组过滤器(多个过滤器),那么这组过滤器就称为一条过滤器链。

每个过滤器实现某个特定的功能,当第一个Filter的doFilter方法被调用时,Web服务器会创建一个代表Filter链的FilterChain对象传递给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则Web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2个filter,如果没有,则调用目标资源。

过滤器链

 

1.6.2 过滤器优先级

在一个Web应用中,可以开发编写多个Filter,这些Filter组合起来称之为一个Filter链。 优先级:

  • 如果为注解的话,是按照类全名称的字符串顺序决定作用顺序

  • 如果web.xml,按照 filter-mapping注册顺序,从上往下

  • web.xml配置高于注解方式

  • 如果注解和web.xml同时配置,会创建多个过滤器对象,造成过滤多次。

1.7 过滤器典型应用

1.7.1 过滤器解决编码

@WebFilter(value = "/*")
public class EncodingFilter 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.setContentType("text/html;charset=utf-8");

        filterChain.doFilter(servletRequest,servletResponse);
    }

    @Override
    public void destroy() {

    }
}

1.7.2 权限验证

ShowAllAdminController


@WebServlet(value = "/showallcontroller")
public class ShowAllAdminController extends HttpServlet {
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        //通过HttpSession完成权限控制
//        HttpSession session = req.getSession();
//        Manager mgr  =(Manager)session.getAttribute("mgr");
//        if(mgr !=null){
            //只负责调用业务逻辑功能
            AdminService adminService = new AdminServiceImpl();

            List<Admin> adminList = adminService.showAllAdmin();

            //request作用域存储数据
            req.setAttribute("admins",adminList);
            //通过转发 跳转到显示结果servlet
            req.getRequestDispatcher("/showalljsp").forward(req,resp);
//        }else{
//            resp.sendRedirect("/WebProject_war_exploded/loginMgr.html");
//        }

    }

}
 

CheckFilter

@WebFilter(value = "/showallcontroller")
public class CheckFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        //权限验证   验证管理员是否登录!
        //向下转型  拆箱
        HttpServletRequest request = (HttpServletRequest)servletRequest;
        HttpServletResponse response = (HttpServletResponse)servletResponse;
        HttpSession session =request.getSession();
        Manager mgr = (Manager) session.getAttribute("mgr");
        if(mgr!=null){//登录过!
            filterChain.doFilter(request,response);
        }else{
            response.sendRedirect(request.getContextPath()+"/loginMgr.html");
        }

    }

    @Override
    public void destroy() {

    }
}
  • 作者:llxxqq5
  • 原文链接:https://blog.csdn.net/m0_58574228/article/details/121841210
    更新时间:2023-04-11 13:06:26