代碼來之哪里,不記得了
Paste_Image.png
GzipFilter
public class GzipFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("過濾器被執(zhí)行了");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
//1.對response進行改進
MyResponse resp = new MyResponse((HttpServletResponse) response);
//2.放行,讓后臺做response做輸出操作
chain.doFilter(request, resp);
//3.從我們定義的“字節(jié)數(shù)組輸出流”中取出數(shù)據(jù)進行壓縮
ByteArrayOutputStream baout = resp.getBaout();
byte bs[] = baout.toByteArray();// 源字節(jié)數(shù)據(jù)
System.out.println("壓縮前大小:" + bs.length);
ByteArrayOutputStream zipBaout = new ByteArrayOutputStream();
GZIPOutputStream gout = new GZIPOutputStream(zipBaout);
gout.write(bs);// 把數(shù)據(jù)壓縮到baout中
gout.close();
bs = zipBaout.toByteArray();//得到壓縮后的字節(jié)
System.out.println("壓縮后大小:" + bs.length);
//4.再用原生的reponse輸出壓縮后的內(nèi)容
HttpServletResponse httpResp = (HttpServletResponse) response;
// 輸出之前告訴客戶端:我們的數(shù)據(jù)是gzip格式,然后輸出
httpResp.setHeader("Content-Encoding", "gzip");
httpResp.setContentLength(bs.length);
OutputStream out = httpResp.getOutputStream();
out.write(bs);
}
@Override
public void destroy() {
}
}
class MyResponse extends HttpServletResponseWrapper { //HttpServletResponse實現(xiàn)類
private PrintWriter pw;
private ByteArrayOutputStream baout = new ByteArrayOutputStream();
/*
* 字節(jié)數(shù)組輸了流(帶緩存功能):所有發(fā)送到輸出流的數(shù)據(jù)保存在該字節(jié)數(shù)組緩沖區(qū)中,可以轉(zhuǎn)成字節(jié)數(shù)組
* 在此的作用:為了將response輸出的內(nèi)容先存到字節(jié)數(shù)組緩沖區(qū)中,以便后續(xù)的壓縮處理*/
public MyResponse(HttpServletResponse response) {
super(response);
}
//重新實現(xiàn)response的該方法
public ServletOutputStream getOutputStream() throws IOException {
return new MyOutputStream(baout);
}
public ByteArrayOutputStream getBaout() {
if(pw!=null){
pw.flush();
//這里很重要,如果不flush或close,不把字符流刷出去,baout中是不會有數(shù)據(jù)的.
}
return baout;
}
//重新實現(xiàn)response的該方法
public PrintWriter getWriter() throws IOException {
//字節(jié)流轉(zhuǎn)字符流
pw = new PrintWriter(new OutputStreamWriter(baout, "utf-8"),true);
return pw;
}
}
/**
* 自定義ServletOutputStream子類
* 目的:保證response獲取到的outputStream是我們定義的“字節(jié)數(shù)組輸入流”
* ,且調(diào)用write方法時,是往“字節(jié)數(shù)組輸入流”的緩存區(qū)中寫入*/
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);//把指定內(nèi)容寫入到 字節(jié)數(shù)組輸入流
}
}
測試servlet
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// String str = "go go go let's go";
// //1\獲取字節(jié)數(shù)組
// byte[] bytes = str.getBytes() ;
//
// System.out.println("壓縮前的長度:" + bytes.length);
// //2\
// ByteArrayOutputStream baos = new ByteArrayOutputStream() ;
// GZIPOutputStream gzip = new GZIPOutputStream(baos) ;
//
// gzip.write(bytes) ;
// gzip.close() ;
// //3\
// bytes = baos.toByteArray() ;
// System.out.println("壓縮后的長度:" + bytes.length);
response.setContentType("text/html;charset=utf-8");
String str = "And I memorize each word我記住的每個字眼";
OutputStream out = response.getOutputStream();
out.write(str.getBytes("utf-8"));
//response.getWriter().write(str);
}