`

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

    博客分类:
  • java
阅读更多

功能描述

        如果浏览器支持 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实现

    每个过滤器都是一个独立的类,负责对输入数据进行某种特定的处理,并将处理后的结果传递给下一个过滤器。这个过程就像是数据通过一根管道,依次经过各个过滤阶段。这种模式允许我们将复杂的任务分解为多个简单的部分...

    过滤器拦截并处理request请求

    总结一下,Servlet Filter是Java Web开发中的强大工具,可以用来拦截和处理HTTP请求,实现诸如数据过滤、安全控制等多种功能。通过合理配置和编程,过滤器可以帮助我们构建更健壮、安全的Web应用程序。

    Socket通信,封包处理, Filter过滤器处理

    在"0121SupperSocket"这个文件中,可能包含了关于高级Socket通信、封包处理技巧以及如何结合Filter进行网络数据过滤的示例代码或教程。通过学习和实践这些内容,开发者可以更好地理解和掌握网络编程的核心技术,提升...

    【ASP.NET编程知识】.Net Core HttpClient处理响应压缩详细.docx

    本文将深入探讨HttpClient如何处理响应压缩以及如何在不同场景下使用。 一、HttpClient处理响应压缩的使用方式 在.NET Core中,HttpClient通过HttpClientHandler来处理响应的解压缩。以下是一个简单的示例: ```...

    过滤器链的一个小Demo

    在Java Web开发中,过滤器(Filter)是用于处理HTTP请求和响应的一种机制,它可以对请求进行预处理,也可以对响应进行后处理。过滤器链(Filter Chain)则是多个过滤器按照特定顺序组织起来,共同处理同一个请求或...

    java RAS非对称公私密钥加密+AES公私密钥加密+过滤器入口出口统一处理

    在处理加密时,可以利用过滤器在请求到达目标资源之前加密数据,在响应返回客户端之前解密数据,从而确保数据的安全传输。 **示例代码(demo)** 这个压缩包中的"demo"可能包含了完整的Java代码示例,展示了如何在...

    Servlet过滤器的简单使用源码+文档

    - `web.xml`配置文件:定义了过滤器的映射规则,指明哪些请求路径需要被过滤器处理。 - 自定义过滤器类:实现了`Filter`接口,包含上述的三个方法。 - 登录界面的Servlet或JSP文件:用户输入用户名和密码后,发送...

    过滤器在Java Web开发中的应用研究.pdf

    - 数据压缩:过滤器可以对响应数据进行压缩,优化传输效率。 通过这些应用实例,我们可以看到使用过滤器可以减少开发工作量,提高项目的可维护性,具有很高的实用价值。 总结来说,过滤器在Java Web开发中扮演着...

    网络编程 过滤器链例子

    - 数据转换:`GzipFilter`对响应进行GZIP压缩,减少网络传输的数据量,提高性能。 总之,过滤器链是Java Web开发中的重要工具,它提供了一种灵活的方式来增强应用程序的功能,而无需修改目标资源的代码。通过理解...

    过滤器的使用过滤器的使用

    在Java Web开发中,过滤器(Filter)是一个非常重要的组件,它允许我们在数据处理的各个环节进行拦截、修改或增强处理。本篇文章将深入探讨Java中的过滤器使用技术,旨在帮助开发者理解和掌握这一核心技术。 首先,...

    过滤器笔记整理

    6. **后处理**:过滤器对响应进行后处理,如压缩响应体、添加额外信息等。 7. **响应发送**:处理后的响应发送给客户端。 #### 八、编码过滤器实例 假设我们需要解决中文乱码问题,可以创建一个编码过滤器: 1. *...

    web过滤器 c#

    例如,你可以使用结果过滤器来改变HTTP响应头,或者在响应发送到客户端之前对其进行压缩。 在提供的压缩包文件"WebMIS.GoldFilterOpenSource"中,很可能是包含了一个开源的Web过滤器实现。这样的库通常会提供自定义...

    过滤器Filter的全面解析

    过滤器提供了一种机制,可以对HTTP请求和响应进行拦截、处理,甚至修改,从而实现诸如数据校验、权限控制、字符编码转换等多种功能。本文将全面解析过滤器的概念、原理及其实现方式。 过滤器是Java Servlet规范的一...

    Java Web过滤器详解

    过滤器可以对响应的内容进行压缩。例如,在Web应用程序中,我们可以使用过滤器来压缩响应的内容,以提高系统的性能。 在Java Web开发中,我们可以使用Servlet Filter来实现过滤器的功能。Servlet Filter是一个实现...

    过滤器和监听器的使用与区别

    3. **使用场景**:过滤器常用于数据过滤、安全控制、性能优化等,如登录验证、GZIP压缩等。监听器常用于初始化资源、管理会话、统计信息收集等,如初始化全局变量、记录日志等。 4. **配置方式**:两者都需要在web....

    过滤器实验

    同样,响应也会按照过滤器链的逆序返回,每个过滤器都有机会对响应进行处理。 二、过滤器接口 过滤器API主要由以下三个接口组成: 1. `Filter`:这是过滤器的核心接口,定义了初始化、过滤和销毁方法,分别是`init...

    拦截器过滤器.rar

    它们是在请求被控制器处理之前和之后执行的一系列方法,允许你在请求生命周期的特定点进行干预。拦截器可以用于登录验证、日志记录、性能监控等多种任务。在Spring MVC中,你可以定义一个实现了`HandlerInterceptor`...

    过滤器与过滤器

    在Java Web开发中,过滤器(Filter)和拦截器(Interceptor)是两种常见的处理请求和响应的机制。它们主要用于在请求被实际处理之前或之后执行某些预定义的任务,如认证、授权、数据转换、日志记录等。在这个基于...

    过滤器介绍及代码

    通过使用过滤器技术,开发者能够实现一系列高级功能,如URL级别的权限控制、敏感词过滤、响应信息压缩等。 在Servlet API中,提供了一个名为`Filter`的接口,任何实现了该接口的Java类都可以被视为过滤器。当Web...

Global site tag (gtag.js) - Google Analytics