web开发之过滤器

过滤器

过滤器可以看作是一个对service资源的中控,客户端在请求已配置过滤器的资源时首先要通过filter的审视/处理,然后才能够请求到对应的service资源,service在响应时,同样的要经过filter才能响应给客户端

概述

Filter,是作用目标资源的请求进行过滤的一套技术规范

  • Filter接口定义了过滤器的开发规范,所有的过滤器都要实现该接口
  • Filter的工作位置是项目中所有目标资源之前,容器再创建HttpServletRequest和HttpServletResponse对象后,会先调用Filter的doFilter方法
  • Filter的doFilter方法可以控制请求是否继续,如果放行,则请求继续,如果拒绝,则请求到此为止,由过滤器本身做出响应
  • Filter不仅可以对请求做出过滤,也可以再目标资源做出响应之前,对响应再次进行处理
  • Filter是GOF中责任链模式的经典案例
  • Filter的常用应用包括但不限于:登录权限检查,解决网站乱码,过滤敏感字符,日志记录,性能分析
  • Filter

以打印日志为例实现过滤器

/**
 * 1.实现Filter接口
 * 2.重写过滤方法
 * 3.配置过滤器
 *      web.xml
 *      注解
 */

@WebServlet("/servleta")
public class LogginFilter implements Filter{

    //指定日期格式
    private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

/*
    过滤请求的和响应的方法
        1.请求到达目标资源之前,先经过该方法
        2.该方法有能力控制请求是否继续向后到达目标资源,可以再该方法内直接向客户端做响应处理
        3.请求到达目标资源后,响应之前,还会经过该方法
 */
    @Override
    public void doFilter(ServletRequest servletRequest,ServletResponse servletResponse,FilterChain filterChain) throws Exception{
        /*
         1.请求到达目标资源之前的功能代码
                判断是否登录
                校验权限是否满足
         2.放行代码
         3.响应之前HttpServletResponse转换为响应报文之前的功能代码
         */

        //参数父转子
        HttpServletRequest request = (HttpServletRequest)servletRequest
        HttpServletResponse response = (HttpServletResponse)servletResponse

        //请求到达目标资源之前 打印日志
        String requestURI = request.getRequestURI();//获取URI
        String dateTime = dateFormat.format(new Date());//获取当前系统时间
        String beforeLogging = requestURI +"在"+dateTime+"被访问了"
        System.out.println(beforeLoggin);
        
        //获取请求达到目标之前系统时间
        long t1 = System.currentTimeMillis();
        //放行代码
        filterChain.doFilter(req,res);
        //获取请求达到目标之后,响应之前时间
        long t2 = System.currentTimeMillis();


        //响应之前的功能代码
        String afterLoggin = requestURI + "资源在"+dateTime+"的请求耗时"+(t2-t1)+"毫秒";
         System.out.println(afterLoggin);
    }

}

<filter>
    <filter-name>logginFilter</filter-name>
    <filter-class>com.aili.LogginFilter</filter-class>
</filter>
<!--配置过滤器的过滤资源规则,路径-->
<filter-mapping>
    <filter-name>loggingFilter</filter-name>
    <!--
        url-pattern     根据请求的资源路径,对指定的请求进行过滤
        /*              过滤全部资源
        /a/*            过滤以a开头的资源
        *.html          过滤以html为后缀的资源
        /servlet1       对servlet1请求进行过滤
        servlet-name    根据请求的servlet的别名,对指定的servlet资源进行过滤

        一个filter-mapping中可以同时存在多个url-pattern和servlet-name
    -->
    <url-pattern>/*</url-pattern>
    <!--也可以使用servlet别名来配置-->
    <servlet-name>servleta</servlet-name>

</filter-mapping>

过滤器的生命周期

  • 初始化阶段(Initialization):
    当容器启动或者第一次请求到达过滤器时,会调用过滤器的 init() 方法进行初始化。
    init() 方法只会在过滤器被创建时调用一次,用于进行一些初始化工作,比如读取配置文件等。
  • 请求处理阶段(Request Processing):
    每当有请求到达过滤器时,容器会调用过滤器的 doFilter() 方法来处理请求。
    doFilter() 方法会在请求到达 Servlet 之前被调用,可以在这里对请求进行处理,比如修改请求参数、验证用户身份等。
  • 销毁阶段(Destruction):
    当容器关闭或者过滤器需要被移除时,会调用过滤器的 destroy() 方法进行清理工作。
    destroy() 方法只会在过滤器被销毁时调用一次,用于释放资源,比如关闭数据库连接等。

过滤器的生命周期由容器管理,过滤器的生命周期与 Servlet 的生命周期有些类似,过滤器类是通过容器来实例化和管理的

过滤器链

一个web项目中,可以同时定义多个过滤器,多个过滤器对同一个资源进行过滤工作时,工作位置有先有后,整体形成一个工作链,称之为过滤器链

  • 过滤器链中的过滤器的顺序由filter-mapping顺序决定
  • 每个过滤器过滤的范围不同,针对同一个资源来说,过滤器链中的过滤器个数可能是不同的
  • 如果某个Filter是使用ServletName进行匹配规则的设置,那么这个Filter执行的优先级要更低

Java Web过滤器链的一般工作流程:

客户端发送请求到服务器。
请求首先被第一个过滤器拦截。
第一个过滤器可以对请求进行处理,然后决定是否将请求传递给下一个过滤器。
如果第一个过滤器决定将请求传递下一个过滤器,则请求会继续经过下一个过滤器。
这个过程会一直持续,直到请求到达目标资源(Servlet或JSP)。
目标资源处理完请求后,响应会按相反的顺序经过过滤器链返回给客户端。

过滤器链的顺序由在web.xml文件中配置的<filter-mapping>元素的顺序决定。

实例

public class Filter1 implements Filter {
    public void init(FilterConfig config) throws ServletException {
        // Initialization code
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        // Pre-processing code

        // Pass the request along the filter chain
        chain.doFilter(request, response);

        // Post-processing code
    }

    public void destroy() {
        // Cleanup code
    }
}

public class Filter2 implements Filter {
    // Similar structure as Filter1
}

// In web.xml
<filter>
    <filter-name>Filter1</filter-name>
    <filter-class>com.example.Filter1</filter-class>
</filter>
<filter>
    <filter-name>Filter2</filter-name>
    <filter-class>com.example.Filter2</filter-class>
</filter>
<filter-mapping>
    <filter-name>Filter1</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>Filter2</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

过滤器注解

//定义了一个拦截所有路径,并且定义了一个名为paramName,值为paramValue的初始化参数
//在过滤器初始化时,可以通过FilterConfig对象获取这个初始化参数的值
//如果需要指定过滤器链的执行顺序,可以使用@WebFilter注解的filterName属性来控制过滤器的执行顺序。过滤器链的执行顺序是根据过滤器的名称(filterName)的字母顺序来确定的,按照字母顺序先后执行。
//也可以利用过滤器类名来确定过滤器执行顺序
@WebFilter(
    filterName="loggingFilter",
    urlPatterns = { "/*" }, 
    initParams = {@WebInitParam(name = "paramName", value = "paramValue") }
    servletNames = {"servletBName"}
    )

public class MyFilter implements Filter {

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 初始化操作
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // 过滤逻辑
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
        // 销毁操作
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值