JAVA-FILTER使用


概述

java过滤器是Servlet技术中最实用的技术,Web开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。

可以实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等高级功能。

主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理。使用Filter的完整流程:Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。

JAVA 如何使用filter

1.实现filter接口,重写dofilter()方法.

注意事项:在JAVA的servlet不允许直接对request中的parameter直接进行修改,需要使用AMHttpServletRequestWrapper来实现对request中的parameter的修改.

    import java.io.IOException;
    import java.util.Map;

    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;

    /**
    * @Description:    
    * @author: jackromer
    * @version: 1.0, Dec 14, 2018
    */


    public class SpecialCharactersFilter implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {//使用filterConfig初始化filter

        }

        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            HttpServletRequest http_req = (HttpServletRequest)request;
          //在JAVA的servlet不允许直接对request中的parameter直接进行修改,需要使用AMHttpServletRequestWrapper来实现对request中的parameter的修改.
          AMHttpServletRequestWrapper amHttpServletRequestWrapper = new AMHttpServletRequestWrapper(http_req, http_req.getParameterMap());
          Map<String,String[]> map = amHttpServletRequestWrapper.getParameterMap();
            if(map.containsKey("XXX")) {
                String searchKey = map.get("XXX")[0];
                  if (searchKey.contains("%")) {
                String newSearchKey = searchKey.replaceAll("%", "\\\\%");//处理%特殊字符,对其转义用于查询数据
                String newArr []  =  {newSearchKey};
                amHttpServletRequestWrapper.setParameter("XXX", newArr);//重设参数值
                  }
             }

          chain.doFilter(amHttpServletRequestWrapper, response);
        }

        /**
         * @see javax.servlet.Filter#destroy()
         */
        @Override
        public void destroy() {

        }

    }

2. AMHttpServletRequestWrapper的实现

    import java.util.Enumeration;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Vector;

    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;

    /**
     * @Description:
     * @author: zhouqiang
     * @version: 1.0, Dec 14, 2018
     */

    public class AMHttpServletRequestWrapper extends HttpServletRequestWrapper {

        Map<String, String[]> params = null;

        @SuppressWarnings({ "unchecked", "rawtypes" })
        public AMHttpServletRequestWrapper(HttpServletRequest request, Map inParam) {
            super(request);
            params = new HashMap(inParam);
        }

        public void setParameter(String key, String value) {
            params.put(key, new String[] { value });
        }

        public void setParameter(String key, String[] values) {
            params.put(key, values);
        }

        @Override
        public String getParameter(String name) {
            Object v = params.get(name);
            if (v == null) {
                return null;
            } else if (v instanceof String[]) {
                String[] strArr = (String[]) v;
                if (strArr.length > 0) {
                    return strArr[0];
                } else {
                    return null;
                }
            } else {
                return v.toString();
            }
        }


        @Override
        public Map<String, String[]> getParameterMap() {
            return params;
        }

        @SuppressWarnings({ "unchecked", "rawtypes" })
        @Override
        public Enumeration<String> getParameterNames() {
            Vector l = new Vector(params.keySet());
            return l.elements();
        }

        @Override
        public String[] getParameterValues(String name) {
            return params.get(name);
        }

    }

3.初始化filterConfig

    import org.springframework.boot.web.servlet.FilterRegistrationBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
    /**
    * @Description:    
    * @author: zhouqiang
    * @version: 1.0, Dec 14, 2018
    */

    @Configuration
    public class FilterConfig extends WebMvcConfigurerAdapter {

        /**
         * 初始化过滤器
         *
         * @return
         * @Bean 注解必加,否则过滤器失效
         */
        @Bean
        public FilterRegistrationBean indexFilterRegistration() {
            FilterRegistrationBean registration = new FilterRegistrationBean(new SpecialCharactersFilter());
            registration.addUrlPatterns("/*");
            /**
             * 再有一个过滤器的话,可以设置成 registration.setOrder(Integer.MAX_VALUE - 1)
             * spring boot 会按照order值的大小,从小到大的顺序来依次过滤
             */
            registration.setOrder(Integer.MAX_VALUE);
            return registration;
        }
    }

4. 使用web.xml 配置过滤器

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="3.0" 
        xmlns="http://java.sun.com/xml/ns/javaee" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
        http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
      <display-name></display-name>    
      <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
      </welcome-file-list>
      <!--配置过滤器-->
      <filter>
          <filter-name>SpecialCharactersFilter</filter-name>
          <filter-class>com.xxx.xxx.SpecialCharactersFilter</filter-class>
      </filter>
      <!--映射过滤器-->
      <filter-mapping>
          <filter-name>SpecialCharactersFilter</filter-name>
          <!--“/*”表示拦截所有的请求 -->
          <url-pattern>/*</url-pattern>
      </filter-mapping>
    </web-app>

Filter链

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

web服务器根据Filter在web.xml文件中的注册顺序,决定先调用哪个Filter,当第一个Filter的doFilter方法被调用时,web服务器会创建一个代表Filter链的FilterChain对象传递给该方法。

在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2个filter,如果没有,则调用目标资源。

Filter 链的使用

1.再定义一个filter

    import java.io.IOException;
    import java.util.Map;

    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;

    /**
    * @Description:    
    * @author: jackromer
    * @version: 1.0, Dec 14, 2018
    */

    public class SpecialCharactersFilter2 implements Filter {
        @Override
        public void init(FilterConfig filterConfig) throws ServletException {//使用filterConfig初始化filter

        }

        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            HttpServletRequest http_req = (HttpServletRequest)request;
          //do something...
          chain.doFilter(amHttpServletRequestWrapper, response);
        }

        /**
         * @see javax.servlet.Filter#destroy()
         */
        @Override
        public void destroy() {

        }
    }

2.配置web.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
    <display-name>FilterTest</display-name>

    <filter>
        <filter-name>SpecialCharactersFilter</filter-name>
        <filter-class>com.xxx.xxx.SpecialCharactersFilter</filter-class>
        <init-param>
            <param-name>xxx</param-name>
            <param-value>xxx-value</param-value>
        </init-param>
    </filter>

    <filter>
        <filter-name>SpecialCharactersFilter2</filter-name>
        <filter-class>com.xxx.xxx.SpecialCharactersFilter2</filter-class>
        <init-param>
            <param-name>yyy</param-name>
            <param-value>yyy-value</param-value>
        </init-param>
    </filter>

    <!-- 故意将filter-mapping倒过来写,观察顺序是和哪个标签一致 -->
    <!-- filter在filter chain中的执行顺序是按照 filter-mapping中的配置顺序来执行的 -->

    <filter-mapping>
        <filter-name>com.xxx.xxx.SpecialCharactersFilter2</filter-name>
        <!-- 只过滤根目录下go.html -->
        <url-pattern>/go.html</url-pattern>
    </filter-mapping>

    <filter-mapping>
        <filter-name>com.xxx.xxx.SpecialCharactersFilter</filter-name>
        <!-- 过滤根目录下所有资源(实验中只放了go.html) -->
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <welcome-file-list>
        <welcome-file>go.html</welcome-file>
    </welcome-file-list>
    </web-app>

总结

JAVA 的filter可以非常简单的实现web服务器的过滤功能, 包括页面,参数,请求路径等等.



   Reprint policy


《JAVA-FILTER使用》 by jackromer is licensed under a Creative Commons Attribution 4.0 International License
 Previous
Linux自动打包脚本 Linux自动打包脚本
概述 本文主要介绍如何使用一些linux脚本 linux启动项目脚本 启动脚本名startup.bash #!/bin/bash start_monitor() { nohup java -cp KafkaOffsetMon
2019-08-27
Next 
JAVA-LISTENER使用 JAVA-LISTENER使用
概述 敬请期待… 有序列表 文本1 文本2 文本3 引用图片 引用链接引用图片 一盏灯, 一片昏黄; 一简书, 一杯淡茶。 守着那一份淡定, 品读属于自己的寂寞。 保持淡定, 才能欣赏到最美丽的风景! 保持淡定, 人生从此不再寂寞
2019-08-27
  目录