java gzip filter_Filter过滤器(gzip) 全站 压缩

package com.itheima.filter;

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 FilterConfig config;

@Override

public void init(FilterConfig filterConfig) throws ServletException {

this.config = filterConfig;

}

@Override

public void doFilter(ServletRequest req, ServletResponse resp,

FilterChain chain) throws IOException, ServletException {

HttpServletRequest request = (HttpServletRequest) req;

HttpServletResponse response = (HttpServletResponse) resp;

String encoding = config.getInitParameter("encoding");

request.setCharacterEncoding(encoding);

response.setContentType("text/html;charset="+encoding);

//

//response.setCharacterEncoding("")

// HttpServletRequestWrapper ---对request 进行 包装的包装类 ---- 解决全站的 请求数据的乱码

//HttpServletResponseWrapper ----对response 进行 包装的 包装类 ---- 解决全站的 响应的数据的 压缩

MyHttpServletResponseWrapper myresponse = new MyHttpServletResponseWrapper(response);

//放行

chain.doFilter(request, myresponse); // --- 目标 资源会得到 执行

System.out.println("之后 ...");

// 将 写到 myresponse 里的数据 进行 压缩 , 然后 输出到 浏览器 去

//这里 报错的 原因是 因为

// 没有 原始的数据(压缩前的数据), 那么 如果 能够 将原始的 压缩前的数据 拿到

// 所有的问题就 都解决了...

//byte[] b = data.getBytes();

byte[] b = myresponse.getOldData();

System.out.println("压缩前: " + b.length);

//底层流

ByteArrayOutputStream baos = new ByteArrayOutputStream();

//采用gzip压缩

//这里 压缩的时候, 需要的是一个 输出流, 这里的输出流是一个底层流

GZIPOutputStream gout= new GZIPOutputStream(baos);

gout.write(b);

gout.close(); //确保 数据可以写到 底层流 baos中去

//这里 要注意: 由于 数据是写到 底层流 baos中去的, gout 默认的是有 缓冲区的 .

b = baos.toByteArray();

System.out.println("压缩后 : " +b.length);

//告诉浏览器 需要 解压缩 数据-- 通过 http的响应头 实现

response.setHeader("content-encoding", "gzip");

response.setContentLength(b.length); //数据的长度

response.getOutputStream().write(b);

}

@Override

public void destroy() {

}

}

class MyHttpServletResponseWrapper extends HttpServletResponseWrapper{

private HttpServletResponse response;

public MyHttpServletResponseWrapper(HttpServletResponse response) {

super(response);

this.response= response;

}

ByteArrayOutputStream bout = new ByteArrayOutputStream();

//通过 这个方法 可以 拿到 原始的 数据

public byte[] getOldData(){

if(pw!=null){

pw.close();

}

return bout.toByteArray();

}

PrintWriter pw = null;

@Override

public PrintWriter getWriter() throws IOException {

//字符输出流, 有缓冲区 ,

if(pw==null){

//字符输出流 ----- bout (字节流)

pw = new PrintWriter(new OutputStreamWriter(bout, response.getCharacterEncoding()));

}

return pw;

}

@Override

public ServletOutputStream getOutputStream() throws IOException {

//在 调用这个 方法的时候, 数据 写到 一个 俺们自己 定义的输出流去, 那么这样 数据就进入了 自己 定义的输出流中去 了 .

return new MyServletOutputStream(bout);

}

}

class MyServletOutputStream extends ServletOutputStream{

private OutputStream out;

public MyServletOutputStream(OutputStream out){

this.out = out;

}

//最终 是 调用到 这个 方法里 了 .

//所有的数据 都进入 到了 out 中去 了,而这里 out 又 是 MyHttpServletResponseWrapper 里的 bout 了, 所以 所有的数据 都 在 bout 中了

@Override

public void write(int b) throws IOException {

out.write(b);

}

// 这里 没有 一个 接受 字节 数组的write 方法

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值