使用filter實現網站的gzip壓縮
使用filter實現網站的gzip壓縮
gzip可以提高網站的訪問速度,所以還是有必要開啟的,這裡說說如何用filter實現
直接上程式碼
package com.educate.web.filter;
import com.educate.web.interceptor.LoginInterceptor;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.zip.GZIPOutputStream;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
public class GzipFilter implements Filter {
private static final Logger LOGGER = LoggerFactory.getLogger(GzipFilter.class);
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
if (isGZipEncoding(request)) {
//需要過濾的副檔名:.htm,.html,.jsp,.js,.ajax,.css,.ftl,.txt, 一般這些已經足夠了,不建議壓縮圖片(具體百度)
String gzipPattern = ",.htm,.html,.jsp,.js,.ajax,.css,.ftl,.txt,";
String uri = request.getRequestURI();
//得到資源的字尾
String ext = FilenameUtils.getExtension(uri);
if (StringUtils.indexOf(gzipPattern, ",." + ext + ",") != -1) {
MyResponse resp = new MyResponse(response);
chain.doFilter(request, resp);// 放行--讓後臺去寫
// 從增強版的resp的baout中(存放的是源位元組資料),把資料取出來進行壓縮,
// 然後再壓縮後的資料用原生的response輸出到客戶端
ByteArrayOutputStream baout = resp.getBaout();
byte bs[] = baout.toByteArray();// 源位元組資料
//太小的不壓縮
if (bs.length > 512) {
LOGGER.debug("過濾的資源路徑:" + uri);
LOGGER.debug("壓縮前大小:" + bs.length);
ByteArrayOutputStream baout2 = new ByteArrayOutputStream();
GZIPOutputStream gout = new GZIPOutputStream(baout2);
gout.write(bs);// 把資料壓縮到baout中
gout.close();
bs = baout2.toByteArray();
LOGGER.debug("壓縮後大小:" + bs.length);
// 輸出之前告訴客戶端:我們的資料是gzip格式,然後輸出
response.setHeader("Content-Encoding", "gzip");
response.setContentLength(bs.length);
}
ServletOutputStream output = response.getOutputStream();
output.write(bs);
output.flush();
} else {
chain.doFilter(request, response);
}
return;
} else {
chain.doFilter(request, response);
}
}
/**
* 判斷瀏覽器是否支援GZIP
*
* @param request
* @return
*/
private boolean isGZipEncoding(HttpServletRequest request) {
boolean flag = false;
String encoding = request.getHeader("Accept-Encoding");
if (encoding.indexOf("gzip") != -1) {
flag = true;
}
return flag;
}
@Override
public void destroy() {
}
}
class MyResponse extends HttpServletResponseWrapper {
private ByteArrayOutputStream baout = new ByteArrayOutputStream();
public MyResponse(HttpServletResponse response) {
super(response);
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
return new MyOutputStream(baout);
}
public ByteArrayOutputStream getBaout() {
if (pw != null) {
pw.flush();
//這裡很重要,如果不flush或close,不把字元流刷出去,baout中是不會有資料的.
}
return baout;
}
private PrintWriter pw;
@Override
public PrintWriter getWriter() throws IOException {
pw = new PrintWriter(new OutputStreamWriter(baout, "utf-8"), true);
return pw;
}
}
class MyOutputStream extends ServletOutputStream {
private ByteArrayOutputStream baout = null;
public MyOutputStream(ByteArrayOutputStream baout) {
this.baout = baout;
}
@Override
public void write(int b) throws IOException {
baout.write(b);
}
}
最後在web.xml中配置一下
<!-- gzip壓縮 減少網路流量,加快響應速度 -->
<filter>
<filter-name>gzip</filter-name>
<filter-class>com.educate.web.filter.GzipFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>gzip</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
相關文章
- Apache開啟gzip壓縮提高網站速度Apache網站
- 關gzip壓縮,我有新發現
- 前端效能優化gzip初探(補充gzip壓縮使用演算法brotli壓縮的相關介紹)前端優化演算法
- Apache 開啟gzip壓縮Apache
- nginx指定埠開啟gzip壓縮Nginx
- Vue開啟gzip壓縮檔案Vue
- Apache開啟GZIP壓縮功能方法Apache
- vue-cli3.0配置GZIP壓縮Vue
- 高效能 gzip 壓縮工具 pgzip
- Python實現壓縮和解壓縮Python
- 如何透過ZBlogPHP啟用Gzip壓縮?PHP
- 探索HTTP傳輸中gzip壓縮的祕密HTTP
- 解析ws訂閱返回的GZIP 壓縮資料
- 將 Vue.js 專案部署至靜態網站託管,並開啟 Gzip 壓縮Vue.js網站
- nginx快取配置及開啟gzip壓縮Nginx快取
- 簡單聊聊 GZIP 的壓縮原理與日常應用
- 壓縮Word,一鍵實現Word文件壓縮
- 伺服器端如何開啟GZIP壓縮功能伺服器
- VuePress 部落格優化之開啟 Gzip 壓縮Vue優化
- Nginx網路壓縮 CSS壓縮 圖片壓縮 JSON壓縮NginxCSSJSON
- vue-cli 啟動gzip壓縮,及後臺配置Vue
- 修復損壞的gzip壓縮檔案之原理篇
- canvas實現的前端壓縮裁剪工具Canvas前端
- JNI實現圖片壓縮
- linux 高效壓縮工具之xz的壓縮解壓使用Linux
- Vue使用cube-ui的upload元件實現圖片壓縮VueUI元件
- Nginx開啟gzip壓縮大幅提高頁面載入速度Nginx
- c語言,批次處理檔案,進行gzip壓縮C語言
- 哈夫曼實現檔案壓縮解壓縮(c語言)C語言
- 用ASP實現線上壓縮與解壓縮功能程式碼
- 圖片純前端JS壓縮的實現前端JS
- MySQL實現MYISAM表批次壓縮的方法MySql
- 利用 canvas 實現圖片壓縮Canvas
- Java實現壓縮資料夾Java
- 從 Gzip 壓縮 SVG 說起 — 論如何減小資原始檔的大小SVG
- 【親媽教學】配置Gzip壓縮,含前後端步驟後端
- C++ MiniZip實現目錄壓縮與解壓C++
- java實現字元壓縮演算法Java字元演算法
- 前端的圖片壓縮image-compressor(可在圖片上傳前實現圖片壓縮)前端