GZIP:response压缩

本文介绍了一个使用GZIP对HTTP响应进行压缩的方法,包括通过包装Response对象和使用ByteArrayOutputStream来压缩数据,并在完成后通知浏览器正文已采用gzip编码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里写图片描述

设置编码问题

response压缩

public class GzipFilter implements Filter {

    public void init(FilterConfig filterConfig) throws ServletException {

    }

    public void doFilter(ServletRequest req, ServletResponse resp,
            FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request;
        HttpServletResponse response;
        try{
            request = (HttpServletRequest)req;
            response = (HttpServletResponse)resp;
        }catch(Exception e){
            throw new RuntimeException("non-http request");
        }

        //对 response进行包装,为了能获取向浏览器写的数据
        MyHttpServletResponse myresponse = new MyHttpServletResponse(response);

        chain.doFilter(request, myresponse);

        //压缩代码应放到放行后
        byte b[] = myresponse.getBytes();//如何拿到原始的数据字节序列
        System.out.println("压缩前大小:"+b.length);

        ByteArrayOutputStream out = new ByteArrayOutputStream();//内存数组流:缓存输出流
        GZIPOutputStream gout = new GZIPOutputStream(out);
        gout.write(b);
        gout.close();//   压缩后的数据到ByteArrayOutputStream中了


        b = out.toByteArray();//取出压缩后的数据
        System.out.println("压缩后大小:"+b.length);

        //通知浏览器正文的压缩格式
        response.setHeader("Content-Encoding", "gzip");     

        response.getOutputStream().write(b);
    }

    public void destroy() {

    }

}



class MyHttpServletResponse extends HttpServletResponseWrapper{
    private HttpServletResponse response;
    private ByteArrayOutputStream baos = new ByteArrayOutputStream();//输出的数据
    private PrintWriter pw;


    public MyHttpServletResponse(HttpServletResponse response){
        super(response);
        this.response = response;
    }


    //字节流.覆盖该方法的目的,截获原始的数据:当外部调用getOutputStream()时,能获取输出流的内容数据
    @Override
    public ServletOutputStream getOutputStream() throws IOException {
        return new MyServletOutputStream(baos);
    }

    //字符流输出  当外部调用getWriter()时,能获取输出流的内容数据
    @Override
    public PrintWriter getWriter() throws IOException {
        pw = new PrintWriter(new OutputStreamWriter(baos, response.getCharacterEncoding()));
        return pw;
    }

    /**
     * 刷新存放缓存的字节流输出的数据,得到写入的数据
     * @return
     */
    public byte[] getBytes(){
        try {
            if(pw!=null){
                pw.close();
            }               
            baos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return baos.toByteArray();
    }
}


/**
 * 包装字节流
 * @author zhangjianbin
 *
 */
class MyServletOutputStream extends ServletOutputStream{
    private ByteArrayOutputStream baos;

    public MyServletOutputStream(ByteArrayOutputStream baos){
        this.baos = baos;
    }

    //将外部的数据写入 ByteArrayOutputStream 存放缓存的字节流输出的数据
    @Override
    public void write(int b) throws IOException {
        baos.write(b);
    }

}

public class ServletDemo1 extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        String data = "<h1>中中</h1>";
        //response 是包装后的
        ServletOutputStream sos = response.getOutputStream();

        //调用了包装后的对象,这里是写入了自定义的内存缓存字节数组中去了
        sos.write(data.getBytes("UTF-8"));


//      byte b[] = data.getBytes();
//      System.out.println("压缩前大小:"+b.length);
//      ByteArrayOutputStream out = new ByteArrayOutputStream();//内存数组流:缓存输出流
//      GZIPOutputStream gout = new GZIPOutputStream(out);
//      gout.write(b);
//      gout.close();//   压缩后的数据到ByteArrayOutputStream中了
//      
//      
//      b = out.toByteArray();//取出压缩后的数据
//      System.out.println("压缩后大小:"+b.length);
//      
//      //通知浏览器正文的压缩格式
//      response.setHeader("Content-Encoding", "gzip");


//      response.getOutputStream().write(b);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值