zoukankan      html  css  js  c++  java
  • 设置常用过滤器-站点黑名单、内容压缩

    设置站点黑名单的过滤器

    功能描述

            不允许从禁用的站点(IP)访问当前应用,也不允许从禁用的站点链接到当前应用。
            为了简单起见,设置禁用站点时,暂不支持使用通配符。只是抛砖引玉了。
            比如:禁止其他的网站引用本站的图片资源,只需在此基础上稍作修改即可。

    使用方法

            在 java web 项目的 web.xml 文件中添加如下代码。

    复制代码
    <!--设置站点黑名单的过滤器配置  开始 -->
    <filter> 
     <filter-name>BannedAccessFilter</filter-name> 
     <filter-class>com.hmw.filter.BannedAccessFilter</filter-class> 
     <init-param> 
         <description>需要禁用的站点,一个站点占用一行</description> 
         <param-name>bannedSites</param-name> 
         <param-value> 
             192.168.1.101 
             192.168.1.102 
             www.csdn.net 
         </param-value> 
     </init-param> 
    </filter> 
      
    <filter-mapping> 
     <filter-name>BannedAccessFilter</filter-name> 
     <url-pattern>/*</url-pattern> 
    </filter-mapping> 
    <!--设置站点黑名单的过滤器配置  结束 --> 
    复制代码

    过滤器源码

    复制代码
    package com.hmw.filter; 
      
    import java.io.IOException; 
    import java.io.PrintWriter; 
    import java.net.MalformedURLException; 
    import java.net.URL; 
    import java.util.HashSet; 
    import java.util.StringTokenizer; 
      
    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 org.apache.commons.lang3.StringUtils; 
    import org.apache.log4j.Logger; 
      
    /** 
     * 设置禁用站点(黑名单)的过滤器 
    */
    public class BannedAccessFilter implements Filter { 
        static final Logger logger = Logger.getLogger(BannedAccessFilter.class); 
          
        private HashSet bannedSiteTable; 
          
        /** 
         * 将配置的禁用站点列表初始化到一个 HashSet 中 
         */
        @Override
        public void init(FilterConfig config) throws ServletException { 
            bannedSiteTable = new HashSet(); 
            String bannedSites = config.getInitParameter("bannedSites"); 
            // Default token set: white space. 
            StringTokenizer tok = new StringTokenizer(bannedSites); 
            while (tok.hasMoreTokens()) { 
                String bannedSite = tok.nextToken(); 
                bannedSiteTable.add(bannedSite); 
                logger.info("Banned " + bannedSite); 
            } 
        } 
          
        /** 
         * 如果请求来自被禁用的站点,或是从被禁用的站点链接过来的,则拒绝访问。 
         */
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException { 
            logger.debug("BannedAccessFilter: Filtering the Request..."); 
              
            HttpServletRequest req = (HttpServletRequest) request; 
            String requestingHost = req.getRemoteHost(); 
            String referringHost = getReferringHost(req.getHeader("Referer")); 
              
            String bannedSite = null; 
            boolean isBanned = false; 
            if (bannedSiteTable.contains(requestingHost)) { 
                bannedSite = requestingHost; 
                isBanned = true; 
            } else if (bannedSiteTable.contains(referringHost)) { 
                bannedSite = referringHost; 
                isBanned = true; 
            } 
              
            if (isBanned) { 
                showWarning(response, bannedSite); 
            } else { 
                chain.doFilter(request, response); 
            } 
              
            logger.debug("BannedAccessFilter: Filtering the Response..."); 
        } 
      
        @Override
        public void destroy() { 
        } 
      
        /** 
         * 根据 URL 链接地址,取得该链接地址所在的站点 
         * @param refererringURLString URL链接地址 
         * @return 该 URL 链接地址所在的站点,如果传入的参数不是一个符合URL规范的字符串,则返回 <CODE>null</CODE> 
         */
        private String getReferringHost(String refererringURLString) { 
            if(StringUtils.isBlank(refererringURLString)) 
                return null; 
              
            try { 
                URL referringURL = new URL(refererringURLString); 
                return referringURL.getHost(); 
            } catch (MalformedURLException mue) { // Malformed 
                return null; 
            } 
        } 
      
        /** 
         * 如果用户是从禁用站点访问的该应用,或是从禁用站点链接过来的,则调用此方法将警告信息展现给用户。 
         * @param response HTTP请求响应对象 
         * @param bannedSite 禁止的站点 
         * @throws ServletException 
         * @throws IOException 
         * @author <A href="mailto:hemw@mochasoft.com.cn">何明旺</A> 
         */
        private void showWarning(ServletResponse response, String bannedSite) throws ServletException, IOException { 
            String htmlCode  = ""; 
            htmlCode += "<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">"; 
            htmlCode += "<html xmlns="http://www.w3.org/1999/xhtml">"; 
            htmlCode += "  <head>"; 
            htmlCode += "      <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />"; 
            htmlCode += "      <title>禁止访问</title>"; 
            htmlCode += "  </head>"; 
            htmlCode += "  <body>"; 
            htmlCode += "      <h1>禁止访问</h1>"; 
            htmlCode += "      <p>对不起,您无法访问该资源,因为您的站点已经被列入我们的黑名单!</p>"; 
            htmlCode += "      <p>您的站点是:<strong>" + bannedSite + "</strong></p>"; 
            htmlCode += "  </body>"; 
            htmlCode += "</html>"; 
      
            response.setContentType("text/html"); 
            PrintWriter out = null; 
            try{ 
                out = response.getWriter(); 
                out.println(htmlCode); 
            }finally{ 
                  if(out != null){ 
                    out.flush(); 
                    out.close(); 
                  } 
            } 
              
            /* 
             * 也可以使用下面的方法直接转发或重定向到指定的警告页面 
             * 转发: 
             *     ((HttpServletRequest)request).getRequestDispatcher("/warn.html").forward(request, response); 
             * 重定向: 
             *     ((HttpServletResponse)response).sendRedirect("webAppContext/warn.html"); 
             */
        } 
    } 
    复制代码

     将响应数据进行压缩处理的过滤器

    功能描述

            如果浏览器支持 gzip 压缩格式的数据,则将响应的数据使用 gzip 压缩后再输出。

    使用方法

            在 java web 项目的 web.xml 文件中添加如下代码。

    复制代码
    <!--压缩过滤器的配置  开始 -->
     <filter> 
     <filter-name>CompressionFilter</filter-name> 
     <filter-class>com.hmw.filter.CompressionFilter</filter-class> 
     </filter> 
       
     <filter-mapping> 
     <filter-name>CompressionFilter</filter-name> 
       <servlet-name>/LongServlet</servlet-name> 
     </filter-mapping> 
    <!--压缩过滤器的配置  结束 --> 
    复制代码

    过滤器源码

    复制代码
    CompressionFilter.java
    ?package com.hmw.filter; 
      
    import java.io.ByteArrayOutputStream; 
    import java.io.IOException; 
    import java.io.OutputStream; 
    import java.io.OutputStreamWriter; 
    import java.util.zip.GZIPOutputStream; 
      
    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 javax.servlet.http.HttpServletResponse; 
      
    /** 
     * 压缩过滤器 <BR> 
     * 如果浏览器支持 gzip 压缩格式的数据,则将响应的数据使用 gzip 压缩后再输出。 
     *  */
    public class CompressionFilter implements Filter { 
      
        @Override
        public void init(FilterConfig config) throws ServletException { 
        } 
      
        /** 
         * 如果浏览器不支持 gzip 压缩,则不做直接放行(不做压缩处理)<BR> 
         * 反之,将HTTP响应头的编码设置为 <CODE>gzip</CODE>,然后将响应数据使用 gzip 进行压缩处理。 
         */
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, 
                FilterChain chain) throws ServletException, IOException { 
            HttpServletRequest req = (HttpServletRequest) request; 
            HttpServletResponse res = (HttpServletResponse) response; 
      
            if (!isGzipSupported(req)) { // Invoke resource normally. 
                chain.doFilter(req, res); 
                return; 
            } 
      
            // 将响应头信息中的内容编码设置为 gzip 
            res.setHeader("Content-Encoding", "gzip"); 
              
            // 调用资源,使用 CharArrayWrapper 包装输出 
            CharArrayWrapper responseWrapper = new CharArrayWrapper(res); 
            chain.doFilter(req, responseWrapper); 
            // 取得存放输出数据的 char 型数组 
            char[] responseChars = responseWrapper.toCharArray(); 
              
            // 将响应数据压缩后存入一个 byte 型的数组,然后输出到 
            ByteArrayOutputStream byteStream = new ByteArrayOutputStream(); 
            GZIPOutputStream zipOut = new GZIPOutputStream(byteStream); 
            OutputStreamWriter tempOut = new OutputStreamWriter(zipOut); 
            // 将原来的响应数据压缩后写入二字节输出流 
            tempOut.write(responseChars); 
            // 关闭输出流 
            tempOut.close(); 
      
            // 更新响应头信息中 Content-Length 的值。 
            res.setContentLength(byteStream.size()); 
            // 将压缩后的数据发送至客户端 
            OutputStream realOut = res.getOutputStream(); 
            byteStream.writeTo(realOut); 
        } 
      
        @Override
        public void destroy() { 
        } 
      
        /** 
         * 检测浏览器是否支持 Gzip 压缩 
         *  
         * @param req HTTP 请求对象 
         * @return 如果浏览器支持 Gzip 压缩,则返回 true,反之,则返回 false 
         */
        private boolean isGzipSupported(HttpServletRequest req) { 
            String browserEncodings = req.getHeader("Accept-Encoding"); 
            return ((browserEncodings != null) && (browserEncodings.indexOf("gzip") != -1)); 
        } 
    } 
    CharArrayWrapper.java
    ?package com.hmw.filter; 
      
    import java.io.CharArrayWriter; 
    import java.io.PrintWriter; 
      
    import javax.servlet.http.HttpServletResponse; 
    import javax.servlet.http.HttpServletResponseWrapper; 
      
    /** 
     * A response wrapper that takes everything the client would normally output and 
     * saves it in one big character array. 
     */
    public class CharArrayWrapper extends HttpServletResponseWrapper { 
        private CharArrayWriter charWriter; 
      
        /** 
         * Initializes wrapper. 
         * <P> 
         * First, this constructor calls the parent constructor. That call is 
         * crucial so that the response is stored and thus setHeader, *setStatus, 
         * addCookie, and so forth work normally. 
         * <P> 
         * Second, this constructor creates a CharArrayWriter that will be used to 
         * accumulate the response. 
         */
        public CharArrayWrapper(HttpServletResponse response) { 
            super(response); 
            charWriter = new CharArrayWriter(); 
        } 
      
        /** 
         * When servlets or JSP pages ask for the Writer, don't give them the real 
         * one. Instead, give them a version that writes into the character array. 
         * The filter needs to send the contents of the array to the client (perhaps 
         * after modifying it). 
         */
        @Override
        public PrintWriter getWriter() { 
            return new PrintWriter(charWriter); 
        } 
      
        /** 
         * Get a String representation of the entire buffer. 
         * <P> 
         * Be sure <B>not</B> to call this method multiple times on the same 
         * wrapper. The API for CharArrayWriter does not guarantee that it 
         * "remembers" the previous value, so the call is likely to make a new 
         * String every time. 
         */
        @Override
        public String toString() { 
            return charWriter.toString(); 
        } 
      
        /** Get the underlying character array. */
        public char[] toCharArray() { 
            return charWriter.toCharArray(); 
        } 
    } 
    复制代码

     替换禁用语(指定关键字)

    功能描述

            将请求响应中所有的禁用关键字替换掉之后再输出。

    使用方法

            在 java web 项目的 web.xml 文件中添加如下代码。

    复制代码
    <!--替换关键字的过滤器配置  开始 -->
     <filter> 
     <filter-name>StopWordsFilter</filter-name> 
     <filter-class>com.hmw.filter.StopWordsFilter</filter-class> 
     <init-param> 
         <description>需要禁用的关键字,一个关键字占一行</description> 
         <param-name>keys</param-name> 
         <param-value> 
           QQ 
           百度 
           七一五 
         </param-value> 
     </init-param> 
     </filter> 
       
     <filter-mapping> 
     <filter-name>StopWordsFilter</filter-name> 
       <servlet-name>*.jsp</servlet-name> 
     </filter-mapping> 
    <!--替换关键字的过滤器  结束 --> 
    复制代码

    过滤器源码

    复制代码
    ReplaceKeyWordFilter.java
    ?package com.hmw.filter; 
      
    import java.io.IOException; 
    import java.io.PrintWriter; 
    import java.util.HashSet; 
    import java.util.Iterator; 
    import java.util.Set; 
    import java.util.StringTokenizer; 
      
    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.HttpServletResponse; 
      
    /** 
     * 替换关键字的滤器 <BR> 
     *  */
    public class StopWordsFilter implements Filter { 
        private Set keyWords = new HashSet(); 
      
        /** 
         * 将需要进行替换的关键字添加到一个定义好的 Set 中 
         */
        @Override
        public void init(FilterConfig config) throws ServletException { 
            String keys =  config.getInitParameter("keys"); 
            StringTokenizer tokenizer = new StringTokenizer(keys); 
            String token = null; 
            while (tokenizer.hasMoreTokens()) { 
                token = tokenizer.nextToken(); 
                if(token != null && token.length() > 0){ 
                    keyWords.add(tokenizer.nextToken()); 
                } 
            } 
        } 
      
        @Override
        public void doFilter(ServletRequest request, ServletResponse response, 
                FilterChain chain) throws ServletException, IOException { 
            CharArrayWrapper responseWrapper = new CharArrayWrapper( 
                    (HttpServletResponse) response); 
            // 调用请求资源(使用自己包装的 responseWrapper) 
            chain.doFilter(request, responseWrapper); 
            // 取得响应字符串 
            String responseString = responseWrapper.toString(); 
            // 将需要替换的关键字用“**”替换掉 
            Iterator iter = keyWords.iterator(); 
            while (iter.hasNext()) { 
                responseString = replace(responseString, iter.next(), "**"); 
            } 
              
            // 修改响应头信息中的 Content-Length 
            response.setContentLength(responseString.length()); 
            PrintWriter out = response.getWriter(); 
            out.write(responseString); 
        } 
      
        @Override
        public void destroy() { 
        } 
      
        /** 
         * 将字符串中的所有的指定子字符串替换掉 
         * @param mainString 需要进行替换的字符串 
         * @param orig 需要被替换的子串 
         * @param replacement 替换后的新串 
         * @return 返回替换后的字符串 
         */
        public static String replace(String mainString, String orig, String replacement) { 
            String result = ""; 
            int oldIndex = 0; 
            int index = 0; 
            int origLength = orig.length(); 
            while ((index = mainString.indexOf(orig, oldIndex)) != -1) { 
                result = result + mainString.substring(oldIndex, index) + replacement; 
                oldIndex = index + origLength; 
            } 
            result = result + mainString.substring(oldIndex); 
            return result; 
        } 
    } 
    CharArrayWrapper.java
    ?package com.hmw.filter; 
      
    import java.io.CharArrayWriter; 
    import java.io.PrintWriter; 
      
    import javax.servlet.http.HttpServletResponse; 
    import javax.servlet.http.HttpServletResponseWrapper; 
      
    /** 
     * A response wrapper that takes everything the client would normally output and 
     * saves it in one big character array. 
     */
    public class CharArrayWrapper extends HttpServletResponseWrapper { 
        private CharArrayWriter charWriter; 
      
        /** 
         * Initializes wrapper. 
         * <P> 
         * First, this constructor calls the parent constructor. That call is 
         * crucial so that the response is stored and thus setHeader, *setStatus, 
         * addCookie, and so forth work normally. 
         * <P> 
         * Second, this constructor creates a CharArrayWriter that will be used to 
         * accumulate the response. 
         */
        public CharArrayWrapper(HttpServletResponse response) { 
            super(response); 
            charWriter = new CharArrayWriter(); 
        } 
      
        /** 
         * When servlets or JSP pages ask for the Writer, don't give them the real 
         * one. Instead, give them a version that writes into the character array. 
         * The filter needs to send the contents of the array to the client (perhaps 
         * after modifying it). 
         */
        @Override
        public PrintWriter getWriter() { 
            return new PrintWriter(charWriter); 
        } 
      
        /** 
         * Get a String representation of the entire buffer. 
         * <P> 
         * Be sure <B>not</B> to call this method multiple times on the same 
         * wrapper. The API for CharArrayWriter does not guarantee that it 
         * "remembers" the previous value, so the call is likely to make a new 
         * String every time. 
         */
        @Override
        public String toString() { 
            return charWriter.toString(); 
        } 
      
        /** Get the underlying character array. */
        public char[] toCharArray() { 
            return charWriter.toCharArray(); 
        } 
    } 
    复制代码
  • 相关阅读:
    Javascript FP-ramdajs
    微信小程序开发
    SPA for HTML5
    One Liners to Impress Your Friends
    Sass (Syntactically Awesome StyleSheets)
    iOS App Icon Template 5.0
    React Native Life Cycle and Communication
    Meteor framework
    RESTful Mongodb
    Server-sent Events
  • 原文地址:https://www.cnblogs.com/shaohz2014/p/3700569.html
Copyright © 2011-2022 走看看