精华内容
下载资源
问答
  • java过滤器Filter

    万次阅读 多人点赞 2019-07-31 19:08:31
    Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序,主要的用途是过滤字符编码、做一些业务逻辑判断如是否有权限访问页面等。其工作原理是,只要你在web.xml文件配置好要拦截的客户端请求,它...

    一、简介

    Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序,主要的用途是过滤字符编码、做一些业务逻辑判断如是否有权限访问页面等。其工作原理是,只要你在web.xml文件配置好要拦截的客户端请求,它都会帮你拦截到请求,此时你就可以对请求或响应 (Request、Response)统一设置编码,简化操作;同时还可进行逻辑判断,如用户是否已经登陆、有没有权限访问该页面等等工作。它是随你的 web应用启动而启动的,只初始化一次,以后就可以拦截相关请求,只有当你的web应用停止或重新部署的时候才销毁,以下通过代码示例来了解它 的使用。

    二、实例

    package test.filter; 
    import ...; 
    /**
     * 介绍过滤器的使用,以设置编码为例
     */
    public class MyFilter implements Filter { 
      private FilterConfig config = null; 
      private boolean isFilter = false;
      
      public void destroy() { 
       System.out.println("MyFilter准备销毁..."); 
      } 
      
      public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain chain) throws IOException, ServletException { 
       // 强制类型转换 
       HttpServletRequest request = (HttpServletRequest)arg0; 
       HttpServletResponse response = (HttpServletResponse)arg1; 
       // 获取web.xm设置的编码集,设置到Request、Response 中   
       request.setCharacterEncoding(config.getInitParameter("charset"));   
       response.setContentType(config.getInitParameter("contentType"));   
       response.setCharacterEncoding(config.getInitParameter("charset"));   
       // 将请求转发到目的地继续执行
       chain.doFilter(request, response);
      } 
      
      public void init(FilterConfig arg0) throws ServletException { 
       this.config = arg0; 
       if(isFilter){
          System.out.println("MyFilter初始化..."); 
       }
      } 
      
      private void setIsFilter(boolean isFilter){
    	this.isFilter = isFilter;
      }
    }

    然后在web. xml中配置该过滤器:

     <filter>
     	<filter-name>MyFilter</filter-name>
     	<filter-class>test.filter.MyFilter</filter-class>
     	<init-param>
     		<param-name>isFilter</param-name>
     		<param-value>true</param-value>
     	</init-param>
     </filter>
     <filter-mapping>
     	<filter-name>MyFilter</filter-name>
     	<url-pattern>/*</url-pattern>
     	<dispatcher>REQUEST</dispatcher> <!-- 没有配置dispatcher就是默认request方式的 -->
     	<dispatcher>FORWARD</dispatcher>
     	<dispatcher>ERROR</dispatcher>
     	<dispatcher>INCLUDE</dispatcher>
     </filt

    三、详细介绍

    在doFilter方法中通常都做些什么呢,下面列举一下:

    1、通过控制对chain.doFilter的方法的调用,来决定是否需要访问目标资源。

    比如,可以在用户权限验证等等。判断用户是否有访问某些资源的权限,有权限放行,没权限不执行chain.doFilter方法。
    2、在调用chain.doFilter方法之前,做些处理来达到某些目的。
    比如,解决中文乱码的问题等等。可以在doFilter方法前,执行设置请求编码与响应的编码。甚至可以对request接口进行封装装饰来处理get请求方式的中文乱码问题(重写相应的request.getParameter方法)。
    3、在调用chain.doFilter方法之后,做些处理来达到某些目的。
    比如对整个web网站进行压缩。在调用chain.doFilter方法之前用类A对response对象进行封装装饰,重写getOutputStream和重写getWriter方法。在类A内部中,将输出内容缓存进ByteArrayOutputStream流中,然后在chain.doFilter方法执行后,获取类A中ByteArrayOutputStream流缓存数据,用GZIPOutputStream流进行压缩下。

    Filter不仅可以通过url-pattern来指定拦截哪些url匹配的资源。而且还可以通过servlet-name来指定拦截哪个指定的servlet(专门为某个servlet服务了,servlet-name对应Servlet的相关配置)。

    filter-mapping标签中dispatcher指定过滤器所拦截的资源被Servlet 容器调用的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默认REQUEST。用户可以设置多个<dispatcher> 子元素用来指定 Filter 对资源的多种调用方式进行拦截。

    REQUEST:

    当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问或ERROR情况时,那么该过滤器就不会被调用。

    INCLUDE:

    如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。

    FORWARD:

    如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。

    ERROR:

    如若在A.jsp页面page指令中指定了error属性=examError.jsp,那么A.jsp中若出现了异常,会跳转到examError.jsp中处理。而在跳转到examError.jsp时,若过滤器配置了ERROR的dispather那么则会拦截,否则不会拦截。

    四、高级配置(允许代理注入spring bean)

    web.xml中配置过滤器DelegatingFilterProxy:

     

    <filter>
        <filter-name>permission</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
        <init-param>
            <param-name>targetFilterLifecycle</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
     <filter-mapping>
        <filter-name>permission</filter-name>
        <url-pattern>*.htm</url-pattern>
    </filter-mapping>

    在spring bean配置中加入:

    <bean id="permission" class="你的bean"></bean>

    bean的id必须和filter-name一样。如果想不一样,可以这样配置:

    <filter>
        <filter-name>permission</filter-name>
        <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
         <init-param>
            <param-name>targetFilterLifecycle</param-name>
            <param-value>true</param-value>
        </init-param>
        <init-param>
            <param-name>targetBeanName</param-name>
            <param-value>test</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>permission</filter-name>
        <url-pattern>*.htm</url-pattern>
    </filter-mapping>

    在spring bean配置中加入:

    <bean id="test" class="你的bean"></bean>

    以上你的spring bean必须实现Filter接口。

    那这样子做是为了什么呢?

    答:这样做就可以将DelegatingFilterProxy所代理的filter作为spring的bean,受到spring的管理,也就是通过Spring容器来管理filter的生命周期,还有就是如果filter中需要一些Spring容器的实例,可以通过spring直接注入,另外读取一些配置文件这些便利的操作都可以通过Spring来配置实现。

    其中如果设置"targetFilterLifecycle"为True,则Filter.init()和Filter.destroy()有效;若为false,则这两个方法失效。

    如果大家有用到shiro(一个强大且易用的Java安全框架,执行身份验证、授权、密码学和会话管理等)的话,通常就会用到这个DelegatingFilterProxy了!

     

    展开全文
  • Java Web之过滤器(Filter)

    万次阅读 多人点赞 2018-07-31 16:58:40
    过滤器(Filter) 过滤器实际上就是对web资源进行拦截,做一些处理后再交给servlet。 通常都是用来拦截request进行处理的,也可以对返回的response进行拦截处理 大概流程图如下 应用场景 自动登录 统一设置...

    过滤器(Filter)


    过滤器实际上就是对web资源进行拦截,做一些处理后再交给下一个过滤器或servlet处理
    通常都是用来拦截request进行处理的,也可以对返回的response进行拦截处理

    大概流程图如下

    这里写图片描述

    应用场景
    自动登录
    统一设置编码格式
    访问权限控制
    敏感字符过滤等


    创建Filter

    在Servlet中我们一般都会对request和response中的字符集编码进行配置,如果Servlet过多字符集编码发生变化时修改起码会很麻烦,这些通用的字符集编码配置等工作我们可以放到Filter中来实现。
    下面我们来创建一个处理字符集编码的Filter。

    右键包名—>new ---->Filter

    这里写图片描述

    输入过滤器名称,跟创建Servlet一样,这里我们直接使用 @WebFilter 注解,不再去web,xml中进行配置了。

    这里写图片描述

    创建完成后默认代码,可以看到,CharsetFilter实现了Filter接口,实现了3个方法。3个方法的作用已经在注释中写清楚了。

    package filter;
    
    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import java.io.IOException;
    
    @WebFilter(filterName = "CharsetFilter")
    public class CharsetFilter implements Filter {
        public void destroy() {
            /*销毁时调用*/
        }
    
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
            /*过滤方法 主要是对request和response进行一些处理,然后交给下一个过滤器或Servlet处理*/
           
            chain.doFilter(req, resp);//交给下一个过滤器或servlet处理
        }
    
        public void init(FilterConfig config) throws ServletException {
    
            /*初始化方法  接收一个FilterConfig类型的参数 该参数是对Filter的一些配置*/
    
        }
    
    }
    
    

    配置Filter

    可配置的属性有这些

    这里写图片描述

    常用配置项
    urlPatterns
    配置要拦截的资源

    1. 以指定资源匹配。例如"/index.jsp"
    2. 以目录匹配。例如"/servlet/*"
    3. 以后缀名匹配,例如"*.jsp"
    4. 通配符,拦截所有web资源。"/*"

    initParams
    配置初始化参数,跟Servlet配置一样

    例如

    initParams = {
            @WebInitParam(name = "key",value = "value")
    }
    

    dispatcherTypes
    配置拦截的类型,可配置多个。默认为DispatcherType.REQUEST
    例如

    dispatcherTypes = {DispatcherType.ASYNC,DispatcherType.ERROR}
    

    其中DispatcherType是个枚举类型,有下面几个值

    	FORWARD,//转发的
        INCLUDE,//包含在页面的
        REQUEST,//请求的
        ASYNC,//异步的
        ERROR;//出错的
    

    下面我们来对CharsetFilter 代码进行一下修改

    package filter;
    
    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import javax.servlet.annotation.WebInitParam;
    import java.io.IOException;
    
    @WebFilter(filterName = "CharsetFilter",
            urlPatterns = "/*",/*通配符(*)表示对所有的web资源进行拦截*/
            initParams = {
                    @WebInitParam(name = "charset", value = "utf-8")/*这里可以放一些初始化的参数*/
            })
    public class CharsetFilter implements Filter {
        private String filterName;
        private String charset;
    
        public void destroy() {
            /*销毁时调用*/
    
            System.out.println(filterName + "销毁");
        }
    
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
            /*过滤方法 主要是对request和response进行一些处理,然后交给下一个过滤器或Servlet处理*/
    		System.out.println(filterName + "doFilter()");
            req.setCharacterEncoding(charset);
            resp.setCharacterEncoding(charset);
            chain.doFilter(req, resp);
        }
    
        public void init(FilterConfig config) throws ServletException {
    
            /*初始化方法  接收一个FilterConfig类型的参数 该参数是对Filter的一些配置*/
    
            filterName = config.getFilterName();
            charset = config.getInitParameter("charset");
    
            System.out.println("过滤器名称:" + filterName);
            System.out.println("字符集编码:" + charset);
    
        }
    
    }
    
    

    这样一个简单的字符集编码处理的过滤器就完成了
    我们看看执行打印的结果
    这里写图片描述

    需要注意的是
    过滤器是在服务器启动时就会创建的,只会创建一个实例,常驻内存,也就是说服务器一启动就会执行Filter的init(FilterConfig config)方法.
    当Filter被移除或服务器正常关闭时,会执行destroy方法


    多个Filter的执行顺序

    在我们的请求到达Servle之间是可以经过多个Filter的,一般来说,建议Filter之间不要有关联,各自处理各自的逻辑即可。这样,我们也无需关心执行顺序问题。
    如果一定要确保执行顺序,就要对配置进行修改了,执行顺序如下

    1. 在web.xml中,filter执行顺序跟<filter-mapping>的顺序有关,先声明的先执行
    2. 使用注解配置的话,filter的执行顺序跟名称的字母顺序有关,例如AFilter会比BFilter先执行
    3. 如果既有在web.xml中声明的Filter,也有通过注解配置的Filter,那么会优先执行web.xml中配置的Filter

    我们写个小例子看一下

    新建3个Filter,加上之前的CharsetFilter一共四个

    这里写图片描述

    其中CharsetFilterABFilter是通过注解声明的

    CharsetFilter注解配置

    
    @WebFilter(filterName = "CharsetFilter",
            urlPatterns = "/*",/*通配符(*)表示对所有的web资源进行拦截*/
            initParams = {
                    @WebInitParam(name = "charset", value = "utf-8")/*这里可以放一些初始化的参数*/
            })
    

    ABFilter

    @WebFilter(filterName = "ABFilter",urlPatterns = "/*")
    

    AFilterBFilter是在web.xml配置的。
    执行顺序跟<filter>的顺序无关
    <filter-mapping>的顺序才决定执行顺序

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
             version="4.0">
        <filter>
            <filter-name>AFilter</filter-name>
            <filter-class>filter.AFilter</filter-class>
        </filter>
        <filter>
            <filter-name>BFilter</filter-name>
            <filter-class>filter.BFilter</filter-class>
        </filter>
    
        <!--这里BFilter在AFilter之前-->
        <filter-mapping>
            <filter-name>BFilter</filter-name>
            <url-pattern>/filter.jsp</url-pattern>
        </filter-mapping>
    
        <filter-mapping>
            <filter-name>AFilter</filter-name>
            <url-pattern>/filter.jsp</url-pattern>
        </filter-mapping>
    
       
    </web-app>
    

    每个Filter添加了打印语句,如下
    以ABFilter为例

    package filter;
    
    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import java.io.IOException;
    
    @WebFilter(filterName = "ABFilter",urlPatterns = "/*")
    public class ABFilter implements Filter {
        private String filterName;
    
        public void destroy() {
        }
    
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
            System.out.println(filterName + "  doFilter()");
            chain.doFilter(req, resp);
        }
    
        public void init(FilterConfig config) throws ServletException {
            filterName= config.getFilterName();
            System.out.println("过滤器名称:" + filterName +" init");
        }
    
    }
    
    

    下面我们来访问filter.jsp看看打印结果

    这里写图片描述

    可以看到,执行结果符合预期。
    BFilter和AFilter是在web.xml中声明的,且BFilter的<filter-mapping>在前,故BFilter在AFilter之前执行。
    ABFilter和CharsetFilter是通过注解声明的,故他俩在BFilter和AFilter之后执行,但是ABFilter的名称以A开头,故在CharsetFilter之前执行

    这里写图片描述


    访问权限控制小例子

    下面我们写一个访问控制权限控制的小例子。
    我们在浏览一些网站经常有这个情况,没有登录时是不允许我们访其主页的,只有登录过后才能访问。
    下面我们就用Filter简单实现一下。

    需求分析

    1. 登录时将登录的账号密码保存到cookie中,下次访问时携带账号和密码,过滤器中进行校验
    2. 用户没有登录直接访问主页时,要跳转到登录页面
    3. 登录过滤器不对登录页面进行过滤

    我们先来看一下项目结构

    这里写图片描述

    这里主要看一下LoginFilter的代码

    我们在LoginFilter中对非登录页面的其他jsp都会进行过滤,判断cookie中是否携带了account和pwd。
    如果有这两个数据表示之前登录过,那么对数据进行校验,正确的话就进行下一个操作。
    否则的话,跳转到登录界面

    package filter;
    
    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    
    @WebFilter(filterName = "LoginFilter", urlPatterns = "*.jsp", dispatcherTypes = {})
    public class LoginFilter implements Filter {
        public void destroy() {
        }
    
        public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
    
    
            System.out.println("LoginFilter doFilter");
    
            HttpServletRequest request = (HttpServletRequest) req;
            HttpServletResponse response = (HttpServletResponse) resp;
    
            String url = request.getRequestURI();
    
            System.out.println("请求的url:" + url);
            /*登录页面不需要过滤*/
    
            int idx = url.lastIndexOf("/");
            String endWith = url.substring(idx + 1);
    
    
            if (!endWith.equals("login.jsp")) {
                /*不是登录页面  进行拦截处理*/
    
                System.out.println("不是登录页面,进行拦截处理");
    
                if (!isLogin(request)) {
                    System.out.println("没有登录过或者账号密码错误,跳转到登录界面");
                    response.sendRedirect("login.jsp");
                } else {
                    System.out.println("已经登录,进行下一步");
                    chain.doFilter(req, resp);
                }
    
            } else {
    
                System.out.println("是登录页面,不进行拦截处理");
                chain.doFilter(req, resp);
            }
    
    
        }
    
    
        private boolean isLogin(HttpServletRequest request) {
    
            Cookie[] cookies = request.getCookies();
    
            String account = "";
            String pwd = "";
    
            if (cookies != null && cookies.length > 0) {
                for (Cookie cookie : cookies) {
                    if (cookie.getName().equals("account")) {
                        account = cookie.getValue();
                    } else if (cookie.getName().equals("pwd")) {
                        pwd = cookie.getValue();
                    }
                }
            }
    
            if (account.equals("") || pwd.equals("")) {
                return false;
    
            } else if (account.equals("yzq") && pwd.equals("123")) {
                return true;
            }
    
    
            return false;
        }
    
        public void init(FilterConfig config) throws ServletException {
            System.out.println("LoginFilter  init");
        }
    
    }
    
    

    执行效果

    这里写图片描述

    可以看到,我们在没有登录的情况下直接去访问index.jsp页面时会自动跳转到登录页面,在登录成功后,再次直接访问index页面则可以访问。

    下面是demo

    访问控制demo

    下一篇我们来看看

    JavaWeb之监听器Listener


    从Java线程到kotlin协程 系列文章,感兴趣可以了解下 :
    https://blog.csdn.net/yuzhiqiang_1993/category_11098206.html


    如果你觉得本文对你有帮助,麻烦动动手指顶一下,可以帮助到更多的开发者,如果文中有什么错误的地方,还望指正,转载请注明转自喻志强的博客 ,谢谢!

    展开全文
  • 拦截器(Interceptor)和过滤器(Filter)的执行顺序和区别

    一、引言

    本来想记录一下关于用户登陆和登陆之后的权限管理、菜单管理的问题,想到解决这个问题用到Interceptor,但想到了Interceptor,就想到了Filter,于是就想说一下它们的执行顺序和区别。关于Interceptor解决权限和菜单管理的问题,在放在下一篇写吧,就酱紫。

    二、区别

    1、过滤器(Filter)

    首先说一下Filter的使用地方,我们在配置web.xml时,总会配置下面一段设置字符编码,不然会导致乱码问题:

    <filter>
        <filter-name>encoding</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <servlet-name>/*</servlet-name>
    </filter-mapping>
    

    配置这个地方的目的,是让所有的请求都需要进行字符编码的设置,下面来介绍一下Filter。

    (1)过滤器(Filter):它依赖于servlet容器。它可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的,是用来做一些过滤操作,获取我们想要获取的数据,比如:在Javaweb中,对传入的request、response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者Controller进行业务逻辑操作。通常用的场景是:在过滤器中修改字符编码(CharacterEncodingFilter)、在过滤器中修改HttpServletRequest的一些参数(XSSFilter(自定义过滤器)),如:过滤低俗文字、危险字符等。

    2、拦截器(Interceptor)

    拦截器的配置一般在SpringMVC的配置文件中,使用Interceptors标签,具体配置如下:

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**" />
            <bean class="com.scorpios.atcrowdfunding.web.LoginInterceptor"></bean>
        </mvc:interceptor>
        <mvc:interceptor>
            <mvc:mapping path="/**" />
            <bean class="com.scorpios.atcrowdfunding.web.AuthInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>
    

    (2)拦截器(Interceptor):它依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架。在实现上,基于Java的反射机制,属于面向切面编程(AOP)的一种运用,就是在service或者一个方法前,调用一个方法,或者在方法后,调用一个方法,比如动态代理就是拦截器的简单实现,在调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在调用方法后打印出字符串,甚至在抛出异常的时候做业务逻辑的操作。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。拦截器可以对静态资源的请求进行拦截处理。

    三、代码


    下面在一个项目中我们使用既有多个过滤器,又有多个拦截器,并观察它们的执行顺序:
    (1)第一个过滤器:

    public class TestFilter1 implements Filter {  
      
    		@Override
      	    protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {  
            //在DispatcherServlet之前执行  
    		System.out.println("############TestFilter1 doFilterInternal executed############");  
            filterChain.doFilter(request, response);  
            //在视图页面返回给客户端之前执行,但是执行顺序在Interceptor之后  
            System.out.println("############TestFilter1 doFilter after############");  
        }  
    }  
    

    (2)第二个过滤器:

    public class TestFilter2 implements Filter {  
     
    	@Override
        protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {  
    	    //在DispatcherServlet之前执行  
            System.out.println("############TestFilter2 doFilterInternal executed############");  
            filterChain.doFilter(request, response);  
            //在视图页面返回给客户端之前执行,但是执行顺序在Interceptor之后 
            System.out.println("############TestFilter2 doFilter after############");  
        }  
    }  
    

    (3)在web.xml中注册这两个过滤器:

    <!-- 自定义过滤器:testFilter1 -->   
    <filter>  
        <filter-name>testFilter1</filter-name>  
        <filter-class>com.scorpios.filter.TestFilter1</filter-class>  
    </filter>  
    <filter-mapping>  
        <filter-name>testFilter1</filter-name>  
        <url-pattern>/*</url-pattern>  
    </filter-mapping>  
    
    <!-- 自定义过滤器:testFilter2 -->   
    <filter>  
        <filter-name>testFilter2</filter-name>  
        <filter-class>com.scorpios.filter.TestFilter2</filter-class>  
    </filter>  
    <filter-mapping>  
        <filter-name>testFilter2</filter-name>  
        <url-pattern>/*</url-pattern>  
    </filter-mapping>  
    

    再定义两个拦截器:
    (4)第一个拦截器:

    public class BaseInterceptor implements HandlerInterceptor{  
         
        /** 
         * 在DispatcherServlet之前执行 
         * */  
        public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {  
            System.out.println("************BaseInterceptor preHandle executed**********");  
            return true;  
        }  
     
        /** 
         * 在controller执行之后的DispatcherServlet之后执行 
         * */  
        public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception {  
            System.out.println("************BaseInterceptor postHandle executed**********");  
        }  
         
        /** 
         * 在页面渲染完成返回给客户端之前执行 
         * */  
        public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)  
                throws Exception {  
            System.out.println("************BaseInterceptor afterCompletion executed**********");  
        }  
    }  
    

    (5)第二个拦截器:

    public class TestInterceptor implements HandlerInterceptor {  
     
        public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {  
            System.out.println("************TestInterceptor preHandle executed**********");  
            return true;  
        }  
     
        public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception {  
            System.out.println("************TestInterceptor postHandle executed**********");  
        }  
     
        public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception {  
            System.out.println("************TestInterceptor afterCompletion executed**********");  
        }  
    }  
    

    (6)、在SpringMVC的配置文件中,加上拦截器的配置:

    <!-- 拦截器 -->  
    <mvc:interceptors>  
        <!-- 对所有请求都拦截,公共拦截器可以有多个 -->  
        <bean name="baseInterceptor" class="com.scorpios.interceptor.BaseInterceptor" />  
    
        <mvc:interceptor> 
            <!-- 对/test.jsp进行拦截 -->       
            <mvc:mapping path="/test.jsp"/>  
            <!-- 特定请求的拦截器只能有一个 -->  
            <bean class="com.scorpios.interceptor.TestInterceptor" />  
        </mvc:interceptor>  
    </mvc:interceptors>  
    

    (7)、定义一个Controller控制器:

    package com.scorpios.controller;  
    import org.springframework.stereotype.Controller;  
    import org.springframework.web.bind.annotation.RequestMapping;  
    import org.springframework.web.servlet.ModelAndView;  
      
    @Controller  
    public class TestController {  
        @RequestMapping("/test")  
        public ModelAndView handleRequest(){  
            System.out.println("---------TestController executed--------");  
            return new ModelAndView("test");  
        }  
    }  
    

    (8)、测试结果:
    启动测试项目,地址如下:http://www.localhost:8080/demo,可以看到控制台中输出如下:
    这里写图片描述
    这就说明了过滤器的运行是依赖于servlet容器,跟springmvc等框架并没有关系。并且,多个过滤器的执行顺序跟xml文件中定义的先后关系有关。

    接着清空控制台,并访问:http://www.localhost:8080/test,再次看控制台的输出:
    这里写图片描述
    从这个控制台打印输出,就可以很清晰地看到有多个拦截器和过滤器存在时的整个执行顺序了。当然,对于多个拦截器它们之间的执行顺序跟在SpringMVC的配置文件中定义的先后顺序有关。

    四、总结


    对于上述过滤器和拦截器的测试,可以得到如下结论:

    • Filter需要在web.xml中配置,依赖于Servlet

    • Interceptor需要在SpringMVC中配置,依赖于框架

    • Filter的执行顺序在Interceptor之前,具体的流程见下图
      在这里插入图片描述

    • 两者的本质区别:拦截器(Interceptor)是基于Java的反射机制,而过滤器(Filter)是基于函数回调。从灵活性上说拦截器功能更强大些,Filter能做的事情,都能做,而且可以在请求前,请求后执行,比较灵活。Filter主要是针对URL地址做一个编码的事情、过滤掉没用的参数、安全校验(比较泛的,比如登录不登录之类),太细的话,还是建议用interceptor。不过还是根据不同情况选择合适的。

    展开全文
  • Android实现ListView的A-Z字母排序和过滤搜索功能,完整源码,小伙伴需要的来CSDN下载吧!项目详情http://blog.csdn.net/xiaanming/article/details/12684155
  • 文章目录布隆过滤器 - Redis 布隆过滤器,Guava 布隆过滤器 BloomFilter1、布隆过滤器的起源,用途2、布隆过滤器的概念3、布隆过滤器的优缺点1、优点2、缺点4、应用场景5、布隆过滤器的工作原理6、布隆过滤器的设计 ...

    布隆过滤器 - Redis 布隆过滤器,Guava 布隆过滤器 BloomFilter


    1、布隆过滤器的起源,用途

    布隆过滤器(Bloom Filter)是1970年由布隆提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在一个集合中。它的优点是空间效率和查询时间都比一般的算法要好的多,缺点是有一定的误识别率和删除困难。

    2、布隆过滤器的概念

    如果想要判断一个元素是不是在一个集合里,一般想到的是将所有元素保存起来,然后通过比较确定。链表,树等等数据结构都是这种思路. 但是随着集合中元素的增加,我们需要的存储空间越来越大,检索速度也越来越慢(O(n),O(logn))。不过世界上还有一种叫作散列表(又叫哈希表,Hash table)的数据结构。它可以通过一个Hash函数将一个元素映射成一个位阵列(Bit array)中的一个点。这样一来,我们只要看看这个点是不是1就可以知道集合中有没有它了。这就是布隆过滤器的基本思想。

    Hash面临的问题就是冲突。假设Hash函数是良好的,如果我们的位阵列长度为m个点,那么如果我们想将冲突率降低到例如 1%, 这个散列表就只能容纳m / 100个元素。显然这就不叫空间效率了(Space-efficient)了。解决方法也简单,就是使用多个Hash,如果它们有一个说元素不在集合中,那肯定就不在。如果它们都说在,虽然也有一定可能性它们在说谎,不过直觉上判断这种事情的概率是比较低的。

    3、布隆过滤器的优缺点

    1、优点

    相比于其它的数据结构,布隆过滤器在空间和时间方面都有巨大的优势。布隆过滤器存储空间和插入/查询时间都是常数。另外, Hash函数相互之间没有关系,方便由硬件并行实现。布隆过滤器不需要存储元素本身,在某些对保密要求非常严格的场合有优势。

    布隆过滤器可以表示全集,其它任何数据结构都不能。

    2、缺点

    但是布隆过滤器的缺点和优点一样明显。误算率是其中之一。随着存入的元素数量增加,误算率随之增加。常见的补救办法是建立一个小的白名单,存储那些可能被误判的元素。但是如果元素数量太少,则使用散列表足矣。

    另外,一般情况下不能从布隆过滤器中删除元素。我们很容易想到把位列阵变成整数数组,每插入一个元素相应的计数器加1, 这样删除元素时将计数器减掉就可以了。然而要保证安全的删除元素并非如此简单。首先我们必须保证删除的元素的确在布隆过滤器里面. 这一点单凭这个过滤器是无法保证的。另外计数器回绕也会造成问题。

    在降低误算率方面,有不少工作,使得出现了很多布隆过滤器的变种。

    4、应用场景

    • 网页URL 去重
    • 垃圾邮件识别
    • 黑名单
    • 查询加速【比如基于KV结构的数据】
    • 集合元素重复的判断
    • 缓存穿透

    5、布隆过滤器的工作原理

    布隆过滤器本身是一个很长的二进制向量,既然是二进制的向量,那么显而易见的,存放的不是0,就是1。

    新建一个16位的布隆过滤器,如图
    在这里插入图片描述

    有一个对象,我们通过

    • 方式一计算他的hash值,得到hash = 2
    • 方式二计算他的hash值,得到hash = 9
    • 方式三计算他的hash值,得到hash = 5

    通过三个方法计算得到三个数值,我们把这三个数值对应的布隆过滤器向量值改为1,表明该位置有值。

    第二个对象,加入得到值1 6 3,就把1 6 3 改为1

    对于布隆过滤器本身来说,并没有存储任何数据,只是计算该数据的位置,然后存储向量值

    那么,如果需要判断某个数据是否存在于布隆过滤器,就只需要判断计算出来的所有向量值是否都为1即可


    但是:

    当存储的数据向量不断增多,就可能会出现,2 9 5 向量值都为1,但是实际上没有这个数据的情况,这样就导致了,布隆过滤器只能判断某个数据一定不存在,但是不能保证某个数据一定存在。

    另外,因为一个向量位置可能被多个对象映射,所以,布隆过滤器无法删除数据

    6、布隆过滤器的设计

    布隆过滤器思路比较简单,但是对于布隆过滤器的随机映射函数设计,需要计算几次,向量长度设置为多少比较合适,这个才是需要认真讨论的。

    如果向量长度太短,会导致误判率直线上升。
    如果向量太长,会浪费大量内存。
    如果计算次数过多,会占用计算资源,且很容易很快就把过滤器填满。

    展开全文
  • Filter过滤

    万次阅读 2020-12-29 13:52:12
    Filter:过滤器 ,用来过滤网站的数据; 处理中文乱码 登录验证…. (比如用来过滤网上骂人的话,我***我自己 0-0) Filter开发步骤: 导包 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接...
  • 网站敏感词过滤的实现(附敏感词库)

    万次阅读 多人点赞 2017-07-10 17:50:05
    现在基本上所有的网站都需要设置敏感词过滤,似乎已经成了一个网站的标配,如果你的网站没有,或者你没有做相应的处理,那么小心相关部门请你喝茶哦。 最近在调研Java web网站的敏感词过滤的实现,网上找了相关资料...
  • wireshark显示过滤器和捕获过滤

    万次阅读 2018-11-14 20:52:57
    关于wireshark 过滤器的使用,包括wireshark显示过滤器和wireshark捕获过滤器。
  • 文章目录布隆过滤器 - Redis 布隆过滤器,Guava 布隆过滤器 BloomFilter - 代码实践1、通过guava 实现的布隆过滤器2、通过 redisson 实现的布隆过滤器3、通过Jedis 实现的布隆过滤器 布隆过滤器 - Redis 布隆过滤器...
  • Wireshark捕获过滤器和显示过滤

    千次阅读 2019-12-17 21:19:26
    wireshark中非常实用的捕获过滤器以及显示过滤器的使用技巧
  • 过滤过滤特定的url 默认情况下,过滤器不支持排除特定的URL模式,每当您为过滤器定义URL模式时,任何与该模式匹配的请求都将由过滤器无例外处理。 从过滤器中排除URL的最简单方法是将过滤器映射到非常特定的...
  • wireshark过滤规则

    万次阅读 2021-08-12 14:09:39
    wireshark是一款抓包软件,常用来分析网络底层协议,寻找网络安全问题,平时用的最多的是过滤功能,wireshark的过滤分功能有两种,抓包过滤器和显示过滤器 抓包过滤器的过滤规则分为四个部分:放行,类型,协议和逻辑...
  • 16.引言篇——自定义过滤器及标签

    万次阅读 多人点赞 2021-08-27 22:41:06
    引言——在前面讲述了如何使用Django内置的过滤器,这在我们进行某些项目开发时很是方便。但是,内置的过滤器毕竟有限(当内置的满足不了我们的需求该怎么办?),但是规则是死的,人是活的。这就引出了接下来要讲的...
  • Vue过滤器和自定义过滤

    千次阅读 2017-07-25 19:19:09
    1、过滤器的用法,用 ‘|' 分割表达式和过滤器。 Vue.js 允许你自定义过滤器,可被用作一些常见的文本格式化。过滤器可以用在两个地方:mustache 插值和 v-bind 表达式。过滤器应该被添加在 JavaScript 表达式的...
  • Filter过滤器(超详细)

    万次阅读 多人点赞 2021-01-17 16:03:49
    什么是过滤器 Filter 过滤器它是 JavaWeb 的三大组件之一。 三大组件分别是:Servlet 程序、Listener 监听器、Filter 过滤器 Filter 过滤器它是 JavaEE 的规范。也就是接口 Filter 过滤器它的作用是:拦截请求,...
  • 搜索过滤

    千次阅读 2020-02-18 12:25:27
    了解过滤功能的基本思路 实现分类和品牌展示 了解规格参数展示 实现过滤条件筛选 实现已选过滤项回显 实现取消选择过滤项 1.过滤功能分析 首先看下页面要实现的效果: 整个过滤部分有3块: 顶部的导航,已经选择...
  • chrome Network 过滤和高级过滤

    万次阅读 多人点赞 2019-05-28 18:10:05
    为什么用过滤? 在我们对一个不熟悉的系统进行开发的时候,我们往往需要通过页面去查看当前页面都调用了后台的那些请求,或者去查找页面中所有的POST请求或者GET请求,这些在一个项目很复杂的时候变得尤其重要,但是...
  • java stream过滤_Java Stream过滤

    千次阅读 2020-07-14 20:24:52
    java stream过滤Java Stream filter can be very helpful when you want to do some processing only on some elements of the Stream based on certain condition. 当您希望仅基于特定条件对Stream的某些元素进行...
  • Struts过滤过滤某些字符

    千次阅读 2014-09-24 15:50:23
    (1)天朝的规矩做项目的时候可能需要过滤某些特定的字符,在更多的用途是安全的考虑,下边就是一个过滤字符的简单案例; (2)过滤器代码如下: package com.lc.filter; import java.io.IOException; ...
  • Wireshark使用教程(界面说明、捕获过滤器表达式、显示过滤器表达式) Wireshark常用过滤使用方法 过滤 打开主页面能看到很多报文,但是从这么多报文中筛选我们需要的某个类型的报文,就需要用到表达式功能,比如...
  • 拦截过滤器模式

    千次阅读 2019-09-25 20:01:21
    拦截过滤器模式(Intercepting Filter Pattern)用于对应用程序的请求或响应做一些预处理/后处理。定义过滤器,并在把请求传给实际目标应用程序之前应用在请求上。过滤器可以做认证/授权/记录日志,或者跟踪请求,...
  • 小秋今天去面试了,面试官问了一个与敏感词过滤算法相关的问题,然而小秋对敏感词过滤算法一点也没听说过。于是,有了下下事情的发生… 面试官开怼 面试官:玩过王者荣耀吧?了解过敏感词过滤吗?,例如在游戏里,...
  • URL过滤

    千次阅读 2018-11-18 16:11:57
    一、url过滤简介 针对企业对员工上网行为的控制管理,可以采用URL过滤技术。如企业不允许研发员工在上班时间访问娱乐网站,在下班时间则允许;或者企业不允许市场人员访问研发内部网站等等。这些基于不同的用户组、...
  • 双线性过滤和三线过滤

    千次阅读 2019-01-25 16:50:13
    双线性过滤(Bilinear_filtering)是进行缩放显示的时候进行纹理平滑的一种纹理过滤方法。 在大多数情况下,纹理在屏幕上显示的时候都不会同保存的纹理一模一样,没有任何失真。正因为这样,所以一些像素要使用纹素...
  • 我想实现一个功能就是,过滤一个url然后配置文件过滤截取到这个路径直接跳转到指定的URL中。不用去写一个类去处理的那种。直接在配置文件处理。是过滤的路径就跳转。。请问有没有这样实现的办法。求大神科普。在线急...
  • 《thor过滤器 thor过滤规则合集资源 500+》资源整理并且分享,亲测有限 抖音规则、音乐规则、视频规则,400个规则打包等等

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,535,843
精华内容 614,337
关键字:

过滤