filter_filtering - CSDN
filter 订阅
Filter 技术是servlet 2.3 新增加的功能。servlet2.3是sun公司于2000年10月发布的,它的开发者包括许多个人和公司团体,充分体现了sun公司所倡导的代码开放性原则。在众多参与者的共同努力下,servlet2.3比以往功能都强大了许多,而且性能也有了大幅提高。 展开全文
Filter 技术是servlet 2.3 新增加的功能。servlet2.3是sun公司于2000年10月发布的,它的开发者包括许多个人和公司团体,充分体现了sun公司所倡导的代码开放性原则。在众多参与者的共同努力下,servlet2.3比以往功能都强大了许多,而且性能也有了大幅提高。
信息
外文名
Filter
发    布
2000年10月
体    现
代码开放性原则
作    用
改变request和修改response
出    自
sun公司
中文名
过滤器
所    属
servlet 2.3
Filter特点功能
它新增加的功能包括:1. 应用程序生命周期事件控制;2. 新的国际化;3. 澄清了类的装载规则;4. 新的错误及安全属性;5. 不赞成使用HttpUtils 类;6. 各种有用的方法;7. 阐明并扩展了几个servlet DTD;8. filter功能.
收起全文
精华内容
参与话题
  • Filter的简单介绍及用法

    千次阅读 2018-07-31 20:59:44
    Filter简介: Filter被称之为过滤器,它的基本功能是对servlet容器调用servlet的过程进行过滤,从而在servlet进行响应处理前后做一些操作。 它主要用于对用户请求进行预处理,也可以对HttpServletResponse 进行后...

    Filter简介:
    Filter被称之为过滤器,它的基本功能是对servlet容器调用servlet的过程进行过滤,从而在servlet进行响应处理前后做一些操作。
    它主要用于对用户请求进行预处理,也可以对HttpServletResponse 进行后处理。

    Filter过滤器实现的是javax.servlet.Filter接口的类,而在javax.servlet.Filter中定义了以下三个方法:

    - init(FilterConfig fConfig)
    init()方法用来初始化过滤器,可以在init()方法中获取Filter中的初始化参数。

    String username = filterConfig.getInitParameter("username");

    - doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    doFilter()方法完成过滤操作。当请求发过来的时候,过滤器将执行doFilter方法。
    在HttpServletRequest 执行doFilter()之前,根据需要检查 HttpServletRequest ,同时也可以修改HttpServletRequest 请求头和数据。
    在HttpServletResponse 执行doFilter()之后,根据需要检查 HttpServletResponse ,同时也可以修改HttpServletResponse响应头和数据。

            //设置编码格式
            response.setContentType("text/html;charset=utf-8");
            response.setCharacterEncoding("utf-8");
            //添加name属性
            request.setAttribute("name", "tom");
            System.out.println("denlguFiletr处理 之前");
            //过滤器
            chain.doFilter(request, response);
            response.getWriter().println("<br>");
            response.getWriter().println("经过filter的处理了");
            System.out.println("denlguFiletr处理 之后 ");

    - destroy()
    Filter对象创建后会驻留在内存,当web应用移除或服务器停止时调用destroy()方法进行销毁。在Web容器卸载 Filter 对象之前被调用。destroy()方法在Filter的生命周期中仅执行一次。通过destroy()方法,可以释放过滤器占用的资源。

    xml文件中配置Filter过滤器:

    <filter>
        <filter-name>SessionFilter</filter-name>
        <filter-class>com.login.SessionFilter</filter-class>
        <init-param>
            <param-name>name</param-name>
            <param-value>aaa</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>SessionFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    Filter过滤器执行顺序:
    web服务器根据Filter在web.xml文件中的注册顺序,决定先调用哪个Filter,当第一个Filter的doFilter方法被调用时,web服务器会创建一个代表Filter链的FilterChain对象传递给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2个filter,如果没有,则调用目标资源。

    展开全文
  • JavaWeb三大组件之Filter学习详解

    千次阅读 2018-01-28 20:54:05
    JavaWeb三大组件之Filter学习详解 Filter基本上可以说存在所有的JavaWeb项目中,比如最基本的一个请求参数的编码CharacterEncodingFilter,大家一般都会配置下,那么filter是干嘛的呢? 本篇将主要集中在fitler...

    JavaWeb三大组件之Filter学习详解

    Filter基本上可以说存在所有的JavaWeb项目中,比如最基本的一个请求参数的编码CharacterEncodingFilter,大家一般都会配置下,那么filter是干嘛的呢?

    本篇将主要集中在fitler的以下几个知识点:

    • 干嘛的
    • 怎么用
    • 多个Filter执行的先后顺序
    • 注意事项

    I. 基本知识

    Filter称之为过滤器,是用来做一些拦截的任务, 在Servlet接受请求之前,做一些事情,如果不满足限定,可以拒绝进入Servlet

    arch

    从上面的图,可以看出一个Filter的工作流程:

    一个http请求过来之后

    • 首先进入filter,执行相关业务逻辑
    • 若判定通行,则进入Servlet逻辑,Servlet执行完毕之后,又返回Filter,最后在返回给请求方
    • 判定失败,直接返回,不需要将请求发给Servlet

    通过上面的流程,可以推算使用场景:

    • 在filter层,来获取用户的身份
    • 可以考虑在filter层做一些常规的校验(如参数校验,referer校验等)
    • 可以在filter层做稳定性相关的工作(如全链路打点,可以在filter层分配一个traceId;也可以在这一层做限流等)

    1. 基本使用姿势

    要使用一个Filter,一半需要两步,实现Filter接口的自定义类,web.xml中对filter的定义

    public interface Filter {
        public void init(FilterConfig filterConfig) throws ServletException;
    
    
        public void doFilter(ServletRequest request, ServletResponse response,
                             FilterChain chain)
                throws IOException, ServletException;
    
    
        public void destroy();
    }

    主要就三个方法,从命名来看,

    • 也比较清晰,在创建Filter对象的时候,调用 init 方法
    • 销毁Filter对象的时候,调用 destroy 方法
    • 当请求过来之后,调用 doFilter,也就是主要的业务逻辑所在了

    详细case后面再说

    接下来就是xml的配置了,和Servlet类似,每自定义一个,都需要在xml中加上一个配置(挺繁琐的操作的)

    <!-- 解决乱码的问题 -->
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <async-supported>true</async-supported>
        <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>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    配置也比较简单了,一个 一个 前者定义具体的Filter,后者表示这个Filter拦截的URL (看起来和Servlet的配置规则没什么两样)


    II. 实例

    我们的实例,就拿大名鼎鼎的CharacterEncodingFilter来说明,顺带膜拜下Spring的大神的优秀源码

    public class CharacterEncodingFilter extends OncePerRequestFilter {
    
        private String encoding;
    
        private boolean forceEncoding = false;
    
        public CharacterEncodingFilter() {
        }
    
        public CharacterEncodingFilter(String encoding) {
            this(encoding, false);
        }
    
        public CharacterEncodingFilter(String encoding, boolean forceEncoding) {
            Assert.hasLength(encoding, "Encoding must not be empty");
            this.encoding = encoding;
            this.forceEncoding = forceEncoding;
        }
    
        public void setEncoding(String encoding) {
            this.encoding = encoding;
        }
    
        public void setForceEncoding(boolean forceEncoding) {
            this.forceEncoding = forceEncoding;
        }
    
        @Override
        protected void doFilterInternal(
                HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
                throws ServletException, IOException {
    
            if (this.encoding != null && (this.forceEncoding || request.getCharacterEncoding() == null)) {
                request.setCharacterEncoding(this.encoding);
                if (this.forceEncoding) {
                    response.setCharacterEncoding(this.encoding);
                }
            }
            filterChain.doFilter(request, response);
            System.out.printl("servelt 执行完成,又返回filter");
        }
    }

    上面的实现比较简单,主要将视线集中在 doFilterInternal 方法内部,如果要设置编码参数,则直接修改 HttpServletRequest, HttpServletResponse 两个参数,操作完成之后,执行下面这一行

    filterChain.doFilter(request, response);

    注意

    • 上面这一行执行,表示Filter层已经通过了,请求可以转发给下一个Filter或者直接传给Servlet
    • 而下一个Filter, Servlet执行完成之后,还会继续往下走,就是上面的那一行输出,也会被调用(那一行是我加的,源码中没有)

    所以,如果你不希望继续往下走,那么就简单了,不执行上面的那一行即可

    疑问

    问题一:看了上面的源码,一个很明显的问题就是,参数怎么设置的?

    仔细看上面的源码,发现自定义Filter是继承 org.springframework.web.filter.OncePerRequestFilter 而不是直接实现的 Filter 接口,而且方法内也没有显示的实现 init()方法,所有很容易猜到是父类中实现了参数的初始化过程

    具体的实现逻辑是在 org.springframework.web.filter.GenericFilterBean#init 中,同样是Spring实现的,主要代码捞出来

    public final void init(FilterConfig filterConfig) throws ServletException {
            Assert.notNull(filterConfig, "FilterConfig must not be null");
            if (logger.isDebugEnabled()) {
                logger.debug("Initializing filter '" + filterConfig.getFilterName() + "'");
            }
    
            this.filterConfig = filterConfig;
    
            // Set bean properties from init parameters.
            try {
                PropertyValues pvs = new FilterConfigPropertyValues(filterConfig, this.requiredProperties);
                BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
                ResourceLoader resourceLoader = new ServletContextResourceLoader(filterConfig.getServletContext());
                bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, this.environment));
                initBeanWrapper(bw);
                bw.setPropertyValues(pvs, true);
            }
            catch (BeansException ex) {
                String msg = "Failed to set bean properties on filter '" +
                    filterConfig.getFilterName() + "': " + ex.getMessage();
                logger.error(msg, ex);
                throw new NestedServletException(msg, ex);
            }
    
            // Let subclasses do whatever initialization they like.
            initFilterBean();
    
            if (logger.isDebugEnabled()) {
                logger.debug("Filter '" + filterConfig.getFilterName() + "' configured successfully");
            }
    }

    看上面一大串的代码,到底干了嘛? 简单来讲,就是获取xml中配置的参数,然后填充到Filter对象中(对Srping而言,CharacterEncodingFilter就是一个bean),这个具体的逻辑和本篇关系不大,就直接跳过了

    问题二:在Filter层中可以获取参数么

    从doFilter的方法签名中看,既然有Request参数,那么应该是可以获取到请求参数的,那么实际验证一下

    先实现一个最最最简单的Filter

    public class TestFilter implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {
        }
    
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    
            System.out.println("in filter");
            System.out.println("args: " + JSON.toJSONString(request.getParameterMap()));
            chain.doFilter(request, response);
            System.out.println("out filter");
        }
    
        @Override
        public void destroy() {
        }
    }

    开始测试

    curl -d 'name=Hello&password=world' http://127.0.0.1:8088/123

    输出如下

    in filter
    args: {"name":["Hello"],"password":["world"]}
    out filter

    注意

    在Filter中获取参数时,最好不要直接使用获取请求流的方式,如果获取请求流,那么Servlet就获取不到请求参数了

    问题三:多个filter的顺序怎么定

    前面学习Servlet的时候,也有这个问题,一个URL被多个Servlet命中了,那么先后顺序是怎样的呢?

    • 精确匹配 > 最长匹配 > 其他模糊匹配 > 没有匹配的则是404

    那么Filter呢,他们的区别还是比较明显的,很多Filter都是拦截所有的请求,即很多Filter的命中规则都是一样的,那么怎么办?

    • 先执行带有url-pattern标签的filter,再执行带有servlet-name标签的filter
    • 如果同为url-pattern或servlet-name,则会按照在web.xml中的声明顺序执行

    测试case如下,我们定义三个Filter:

    • TestFilter: 匹配所有路径
    • ATestFilter: 匹配所有路径
    • ServletFilter: 匹配 mvc-servlet
    // ATestFilter
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("in ATestFilter");
        chain.doFilter(request, response);
    }
    
    
    // TestFilter
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("in TestFilter");
        chain.doFilter(request, response);
    }
    
    // ServletFilter
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        System.out.println("in ServletFilter");
        chain.doFilter(request, response);
    }

    对应的xml配置如下

    <filter>
        <filter-name>servletFilter</filter-name>
        <filter-class>com.test.ServletFilter</filter-class>
        <async-supported>true</async-supported>
    </filter>
    <filter-mapping>
        <filter-name>servletFilter</filter-name>
        <servlet-name>mvc-dispatcher</servlet-name>
    </filter-mapping>
    
    <filter>
        <filter-name>testFilter</filter-name>
        <filter-class>com.test.TestFilter</filter-class>
        <async-supported>true</async-supported>
    </filter>
    <filter-mapping>
        <filter-name>testFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
    
    <filter>
        <filter-name>atestFilter</filter-name>
        <filter-class>com.test.ATestFilter</filter-class>
        <async-supported>true</async-supported>
    </filter>
    <filter-mapping>
        <filter-name>atestFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    输出结果

    in TestFilter
    in ATestFilter
    in ServletFilter

    III. 小结

    Filter 通常用于JavaWeb的过滤使用,通过doFilter方法中执行 chain.doFilter(request, response);,进入下一个Filter或者Servlet执行逻辑,当执行完成之后,依然会回到Filter这一层,继续走下去

    针对上面的逻辑,Filter的常见应用场景有:

    • 用户信息获取,身份校验
    • 安全校验(referer校验失败,直接拒绝)
    • 稳定性相关(限流,监控埋点,全链路日志埋点)

    Filter的执行顺序:

    • url-mapping 的优先执行,其次是 servlet-mapping
    • 同一个匹配方式(如都是url-mapping)中,根据在xml中定义的先后顺序来确定

    Filter的注意事项:

    • 正常业务,请记得一定执行 chain.doFilter(request, response), 最后把它放在finnal块中,防止你在Filter中的代码抛异常导致进入不到后续的逻辑
    • 在Filter中不要直接获取请求数据流(请求流被读取完之后,Servlet就get不到了!)

    IV. 其他

    声明

    尽信书则不如,已上内容,纯属一家之言,因本人能力一般,见解不全,如有问题,欢迎批评指正

    扫描关注,java分享

    QrCode

    展开全文
  • Filter(过滤器)

    千次阅读 2018-09-03 19:44:20
    1.什么是Filter Filter也称之为过滤器,可以对web服务器管理的所有web资源:例如Jsp、Servlet、html文件等进行拦截,从而实现一些特殊的功能。 Filter的用途 1. 解决中文乱码问题 2. 权限访问控制 3. 过滤...

    1.什么是Filter

    Filter也称之为过滤器,可以对web服务器管理的所有web资源:例如Jsp、Servlet、html文件等进行拦截,从而实现一些特殊的功能。

    Filter的用途
    1. 解决中文乱码问题
    2. 权限访问控制
    3. 过滤敏感词汇
    4. 压缩响应信息


    2.编写过滤器

    实现过滤器需要两个步骤:

    1. 编写Java类实现Filter接口
    2. 在web.xml文件中注册Filter,并设置它需要拦截的资源。
    package com.mbc.filter;
    
    import java.io.IOException;
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    
    public class MyFilter implements Filter {
        /**
         * init()属于Filter的生命周期方法。当web应用程序启动时,web服务器将创建Filter的实例对象,
         * 调用init方法,完成对象的初始化功能,从而能对用户的请求进行拦截。Filter对象只会创建一次,因此
         * init方法也只会执行一次。init方法的参数:FilterConfig对象,封装了当前filter的配置信息,由服务器
         * 根据web.xml中的相应的配置信息来生成。
         */
        public void init(FilterConfig fConfig) throws ServletException {
            System.out.println("过滤器初始化了。。。");
        }
    
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            //对request和response进行一些预处理
            request.setCharacterEncoding("UTF-8");
            response.setContentType("text/html; charset=UTF-8");
            System.out.println("我是目标资源执行之前运行的代码...");
            chain.doFilter(request, response);//让目标资源执行,放行
            System.out.println("我是目标资源执行之后,响应回给客户端时经过过滤器运行的代码...");
        }
    
        /**
         * destroy()属于Filter的生命周期方法。在服务器关闭之前执行,仅执行一次,
         * 用于释放过滤器使用的资源
         */
        public void destroy() {
            System.out.println("过滤器销毁了。。。");
        }
    }
    

    在web. xml中配置Filter

    <filter>
        <filter-name>MyFilter</filter-name>
        <filter-class>com.mbc.filter.MyFilter</filter-class>
    </filter>
    
    <filter-mapping>
        <filter-name>MyFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    Filter是如何实现拦截的

    当我们编写好Filter并配置好Filter要对哪些web资源拦截后,当用户需要访问配置有Filter的web资源时,web服务器每次在调用web资源的service方法之前会调用Filter的doFilter方法。该方法中可以决定是否过滤掉用户的请求。web服务器调用Filter的doFilter方法时,会传递一个FilterChain的对象进来,它也提供了一个doFilter方法,开发人员根据需求决定是否调用此方法(chain.doFilter(request, response);)。若调用,web服务器通过调用web资源的service方法,用户就可以访问到请求的资源,否则就访问不了。

    image

    Filter中doFilter()的代码执行如下

    1. 调用目标资源前,让一段代码执行
    2. 是否调用目标资源(即是否有FilterChain对象的doFilter方法)
    3. 调用目标资源后,响应回给客户端时经过Filter时执行的代码

    即若用户对web资源的访问通过Filter的过滤后,服务器对用户的访问进行响应时还需要执行chain.doFilter(request, response)下的代码。

    如图所示:图片来自javaweb学习总结(四十二)——Filter(过滤器)学习


    3.Filter的部署

    Filter分为两个步骤

    1. 注册Filter
    2. 映射Filter

    1. 注册Filter

    <filter>
              <description>过滤器的描述</description>
              <filter-name>MyFilter</filter-name>
              <filter-class>com.mbc.filter.MyFilter</filter-class>
              <!--配置FilterDemo02过滤器的初始化参数-->
              <init-param>
                  <description>配置过滤器的初始化参数</description>
                  <param-name>name</param-name>
                  <param-value>mbc</param-value>
              </init-param>
              <init-param>
                  <description>配置初始化参数</description>
                  <param-name>age</param-name>
                  <param-value>18</param-value>
              </init-param>
    </filter>

    说明:
    - <description>:用于添加描述信息,可以不配置
    - <filter-name>:用于指定Filterd的名称
    - <filter-class>:用于指定过滤器的完整类名
    - <init-param>:用于为过滤器指定初始化参数,可以有多个。它的子元素<param-name>指定参数的名字,<parm-value>指定参数的值。此元素可以不配置。通过FilterConfig对象访问初始化参数,类似Servlet的ServletConfig。

    2. 映射Filter

    <filter-mapping>
        <filter-name>MyFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    说明:
    - <filter-mapping>:元素用于设置一个Filter所负责拦截的资源。一个Filter拦截的资源可通过两种方式来指定:Servlet名称和资源访问的请求路径

    • <filter-name>:子元素用于设置filter的注册名称。该值必须是在元素中声明过的过滤器的名字

    • <url-pattern>:设置filter所拦截的请求路径

    • <servlet-name>:指定过滤器所拦截的Servlet名称。

    • <dispatcher>:指定过滤器所拦截的资源被Servlet容器调用的方式,可以是

      • REQUEST:只要是请求过来,都拦截,默认就是REQUEST

      • FORWARD: 只要是转发都拦截

      • ERROR: 页面出错发生跳转时拦截

      • INCLUDE:包含页面的时候就拦截

    可以设置多个子元素用来指定Filter对资源的多种调用方式进行拦截


    4.多个Filter的执行顺序

    如果有多个过滤器,那么他们会按照注册的映射顺序执行,即根据web.xml中元素的配置顺序。只要有一个过滤器不放行,那么后面排队的过滤器不会收到请求。


    5.Filter应用实例

    解决中文乱码问题

    这里使用装饰者模式,对GET请求进行装饰。包括以下文件:

    1. index.html:发送get、post请求的界面
    2. EncodingFilter:过滤器,对所有的请求进行编码处理
    3. IndexServlet:Servlet,测试是否能得到正确的数据
    4. EncodingRequestImpro:装饰类,对get请求的getParameterMap()、getParameterValues()、getParameter()进行装饰(编码处理)

    1.index.html

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>Insert title here</title>
    </head>
    <body>
        <a href="IndexServlet?name=张三&hobby=游泳">通过get提交中文数据</a>
        <form method="post" action="IndexServlet">
            <input name="name" value="张三">
            <input name="hobby" value="游泳">
            <input type="submit" value="提交">
        </form>
    </body>
    </html>

    2.EncodingFilter

    package com.mbc.filter;
    
    import java.io.IOException;
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletRequest;
    
    import com.mbc.servlet.EncodingRequest;
    import com.mbc.servlet.EncodingRequestImpro;
    
    public class EncodingFilter implements Filter {
    
    
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    
            if(req.getMethod().equals("GET")) {
                HttpServletRequest req = (HttpServletRequest) request;    
                //对请求进行装饰
                EncodingRequestImpro encodingRequest = new EncodingRequestImpro(req);
                //装饰完后放行
                chain.doFilter(encodingRequest, response);
            }else if(req.getMethod().equals("POST")) {
                request.setCharacterEncoding("UTF-8");
                chain.doFilter(request, response);
            }
    
        }
    
        public void init(FilterConfig fConfig) throws ServletException {
        }
    
        public void destroy() {
        }
    }

    EncodingFilter部署

    <filter>
        <display-name>EncodingFilter</display-name>
        <filter-name>EncodingFilter</filter-name>
        <filter-class>com.mbc.filter.EncodingFilter</filter-class>
    </filter>
    
    <filter-mapping>
        <filter-name>EncodingFilter</filter-name>
        <url-pattern>/*</url-pattern><!--对所有请求都拦截-->
        <dispatcher>REQUEST</dispatcher>
     </filter-mapping>

    3.EncodingRequestImpro

    package com.mbc.servlet;
    
    import java.io.UnsupportedEncodingException;
    import java.util.Map;
    import java.util.Set;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    
    public class EncodingRequestImpro extends HttpServletRequestWrapper {
        private HttpServletRequest request = null;
        private boolean flag = false;   //用于标记map是否被编码过了
    
        public EncodingRequestImpro(HttpServletRequest request) {
            super(request);
            this.request = request;
        }
    
        @Override
        public Map<String, String[]> getParameterMap() {
            Map<String, String[]> map = request.getParameterMap();
            if(map != null && flag == false) {
                flag = true;
                Set<String> keySet = map.keySet();
                for (String key : keySet) {
                    String[] values = map.get(key);
                    for(int i = 0; i < values.length; i++) {//对作用域中map中的值重新编码
                        try {
                            values[i] = new String(values[i].getBytes("ISO-8859-1"), "UTF-8");
                        } catch (UnsupportedEncodingException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
            return map;
        }
    
        @Override
        public String[] getParameterValues(String name) {
            Map<String, String[]> map = this.getParameterMap();//调用正确编码的map
            if(map != null) {
                return map.get(name);
            }
            return null;
        }
    
        @Override
        public String getParameter(String name) {
            String[] values = this.getParameterValues(name);
            if(values != null) {
                return values[0];
            }
            return null;
        }
    }
    
    1. IndexServlet
    package com.mbc.servlet;
    
    import java.io.IOException;
    import java.util.Map;
    
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    public class IndexServlet extends HttpServlet {
        protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            String name = request.getParameter("name");
            String hobby = request.getParameter("hobby");
            String[] values = request.getParameterValues("name");
            Map<String, String[]> map = request.getParameterMap();
    
            System.out.println("--------------");//检查getParameterValues()得到的是否是乱码
            for (String string : values) {
                System.out.println("values = " + string);
            }
    
            System.out.println("--------------");//检查getParameterMap()得到的是否是乱码
            for(Map.Entry<String, String[]> entry : map.entrySet()) {
                System.out.println(entry.getKey() + " = " + entry.getValue()[0]);
            }
    
            System.out.println("-----------------");//检查getParameter得到的是否是乱码
            System.out.println("name = "+name + "hobby = " + hobby);
    
        }
    
        protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request, response);
        }
    
    }
    

    参考:

    javaweb学习总结(四十二)——Filter(过滤器)学习

    JavaWeb三大组件之过滤器(Filter)

    使用过滤器(Filter)解决请求参数中文乱码问题(复杂方式)

    展开全文
  • 强烈推荐30个原生JavaScript的demo,包括canvas时钟特效、自定义视频播放器、搜索栏快速匹配、fetch访问资源、...但是和map不同的是, filter把传入的函数依次作用于每个元素,然后根据返回值是 true 还是fals...

    强烈推荐30个原生JavaScript的demo,包括canvas时钟特效、自定义视频播放器、搜索栏快速匹配、fetch访问资源、console调试技巧等,先fork后学习,详见点击打开链接,欢迎点赞~~~谢谢,共同进步学习!

    前言

    和map类似,Array的filter也接收一个函数。但是和map不同的是, filter把传入的函数依次作用于每个元素,然后根据返回值是 true 还是false决定保留还是丢弃该元素。

    实例介绍

    例如,在一个Array中,删掉偶数,只保留奇数,可以这么写:

    ?

    1

    2

    3

    4

    5

    var arr = [1, 2, 4, 5, 6, 9, 10, 15];

    var r = arr.filter(function (x) {

     return x % 2 !== 0;

    });

    r; // [1, 5, 9, 15]

    把一个Array中的空字符串删掉,可以这么写:

    ?

    1

    2

    3

    4

    5

    var arr = ['A', '', 'B', null, undefined, 'C', ' '];

    var r = arr.filter(function (s) {

     return s && s.trim(); // 注:IE9(不包含IE9)以下的版本没有trim()方法

    });

    arr; // ['A', 'B', 'C']

    可见用 filter 这个高阶函数,关键在于正确实现一个“筛选”函数。

    回调函数

    filter 接收的回调函数,其实可以有多个参数。通常我们仅使用第一个参数,表示Array的某个元素。回调函数还可以接收另外两个参数,表示元素的位置和数组本身:

    ?

    1

    2

    3

    4

    5

    6

    7

    var arr = ['A', 'B', 'C'];

    var r = arr.filter(function (element, index, self) {

     console.log(element); // 依次打印'A', 'B', 'C'

     console.log(index); // 依次打印0, 1, 2

     console.log(self); // self就是变量arr

     return true;

    });

    利用 filter ,可以巧妙地去除Array的重复元素:

    ?

    1

    2

    3

    4

    5

    6

    7

    8

    var r,

     arr = ['apple', 'strawberry', 'banana', 'pear', 'apple', 'orange', 'orange', 'strawberry'];

     

    r = arr.filter(function (element, index, self) {

     return self.indexOf(element) === index;

    });

     

    console.log(r.toString());

    去除重复元素依靠的是 indexOf 总是返回第一个元素的位置,后续的重复元素位置与 indexOf 返回的位置不相等,因此被 filter 滤掉了。

     

    定义和用法

    filter() 方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素。

    注意: filter() 不会对空数组进行检测。

    注意: filter() 不会改变原始数组。

    语法

    array.filter(function(currentValue,index,arr), thisValue).filter(function(currentValue,index,arr), thisValue)

    参数说明

    参数 描述
    function(currentValue, index,arr) 必须。函数,数组中的每个元素都会执行这个函数
    函数参数:
    参数 描述
    currentValue 必须。当前元素的值
    index 可选。当前元素的索引值
    arr 可选。当前元素属于的数组对象
    thisValue 可选。对象作为该执行回调时使用,传递给函数,用作 "this" 的值。
    如果省略了 thisValue ,"this" 的值为 "undefined"

    技术细节

    返回值: 返回数组,包含了符合条件的所有元素。如果没有符合条件的元素则返回空数组。

     

    展开全文
  • python中filter()高阶函数

    千次阅读 2020-04-17 21:49:26
    # filter()函数是python内置的另一个有用的高阶函数 # filter()函数接收一个函数f和一个list, # 这个函数f的作用是对每个元素进行判断,返回True或False # filter()根据判断结果自动过滤掉不符合条件的元素 # 返回由...
  • Filter 和 Listener 学习

    2020-04-01 15:03:54
    文章目录一、学习目录二、扩展目录 一、学习目录 二、扩展目录
  • Filter&Listener介绍

    2020-01-01 16:34:03
    #### 1.1 Filter【++++】 - 概念【+++】 - 拦截请求,做一些通用的操作,是否放行 - 通用操作:登录验证,字符集编码设置,敏感字符过滤 - 优点:提高代码的通用性 - 快速入门【+++++】 - 编写一个类实现...
  • Filter概述 Filter的作用 Filter的应用 Filter的开发和使用 Filter的细节 Filter概述 过滤器:一个拥有过滤/拦截功能的东西,过滤掉一些不想要的,不和谐的东西. 生活中的过滤器:香烟过滤嘴,滤纸,净水器,空气净化器,...
  • Filter过滤器 1. 什么是filter filter本质上也是一个类,这个类需要实现java提供的filter规范,在方法中书写过滤的条件。filter是对客户端访问资源的过滤,符合条件放行,不符合条件不放行。 2. filter的执行流程 ...
  • 文章目录Filter:过滤器Listener:监听器 Filter:过滤器 1. 概念: * 生活中的过滤器:净水器,空气净化器,土匪、 * web中的过滤器:当访问服务器的资源时,过滤器可以将请求拦截下来,完成一些特殊的功能。 * ...
  • Java Web之过滤器(Filter

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

    千次阅读 2014-03-17 00:25:32
    Filter概念(Filter的作用) Filter :过滤器从名字可以看出来,他就是过滤我们的请求他和serlvet很相似,在serlvet处理之前我们可以用filter来进行处理,同理在servlet处理完后,我们也可以处理响应。 这样我们就...
  • CSS3中强大的filter(滤镜)属性

    千次阅读 2018-08-19 23:25:35
    filter(滤镜)属性,是CSS3中非常有意思的一个属性,可惜IE不支持(当然IE有它专属的滤镜方式)。无所谓,反正IE已经日薄西山。当然,强迫症的同学还是可以在网上找到与CSS3 filter对应的IE滤镜方式,不过这篇文章就...
  • MATLAB 中 filter 函数的使

    万次阅读 2019-08-06 11:30:21
    一维数字滤波滤波器filter 使用 filter 1-D digital filter expand all in page Syntax y = filter(b,a,X) [y,zf] = filter(b,a,X) [y,zf] = filter(b,a,X,zi) y = filter(b,a...
  • spark scala中对RDD过滤的写法
  • val df = sc.parallelize(Seq(("a", 1), ("a", 2), ("b", 2), ("b", 3), ("c", 1))).toDF("id", "num") ...df.filter($"num"===2) df.filter($"num">2) df.filter($"num" 或者 df.fi
  • Reference: https://www.mkyong.com/java8/java-8-streams-filter-examples/ ... In Java 8, using stream.filter() to filter a List, and collect() to convert a stream. */ import java.util.*; import j
  • layui layForm lay-filter的作用

    万次阅读 2018-06-02 10:40:38
    layui框架独有的元素选择形式。
  • @WebFilter(urlPatterns = "/*") @Order(value = 1) public class TestFilter implements Filter { private static final Set ALLOWED_PATHS = Collections.unmodifiableSet(new HashSet( Arrays
  • Vue 报错 Failed to resolve filter

    万次阅读 2017-11-18 18:59:11
    原因: filter 顺序问题: 先定义过滤器, 再新建 vue 实例 原代码: 更改后代码
1 2 3 4 5 ... 20
收藏数 1,058,393
精华内容 423,357
关键字:

filter