??????? 如果浏览器支持 gzip 压缩格式的数据,则将响应的数据使用 gzip 压缩后再输出。
??????? 在 java web 项目的 web.xml 文件中添加如下代码。
monospace !important; font-size: 12px !important; font-style: normal !important; font-weight: normal !important; vertical-align: baseline !important; float: none !important; white-space: pre-wrap;" class="xml comments"><!--压缩过滤器的配置? 开始 -->
?
<
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
>
<!--压缩过滤器的配置? 结束 -->
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
));
????
}
}
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();
????
}
}
?