response增强案例—压缩响应=学习笔记

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了response增强案例—压缩响应=学习笔记相关的知识,希望对你有一定的参考价值。

应用HttpServletResponseWrapper对象,压缩响应正文内容。思路:
通过filter向目标页面传递一个自定义的response对象。
在自定义的response对象中,重写getOutputStream方法和getWriter方法,使目标资源调用此方法输出页面内容时,获得的是我们自定义的ServletOutputStream对象。
在我们自定义的ServletOuputStream对象中,重写write方法,使写出的数据写出到一个buffer中。
当页面完成输出后,在filter中就可得到页面写出的数据,从而我们可以调用GzipOuputStream对数据进行压缩后再写出给浏览器,以此完成响应正文件压缩功能

ShowServlet

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ShowServlet extends HttpServlet {
    public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {
        PrintWriter pw = response.getWriter();
        pw.write("美国美国美国美国美国美国美国美国美国美国美国美国美国美国美国<br/>");
        pw.write("中国中国中国中国中国中国中国中国中国中国中国中国中国中国中国<br/>");
        pw.write("法国法国法国法国法国法国法国法国法国法国法国法国法国法国法国<br/>");
        //ServletOutputStream sout = response.getOutputStream();
        //sout.write(data.getBytes("UTF-8"));
        //MyServletOutputStream mySout = myResponse.getOutputStream();
        //sout.write("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA".getBytes());
        //mySout.write("AAAAAA".getBytes[]);
    }
}

GzipFilter


import java.io.ByteArrayOutputStream;
import java.io.IOException;
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;

import cn.itcast.web.decorator.MyResponse;

public class GzipFilter implements Filter {
    public void destroy() {
    }
    public void doFilter(ServletRequest req, ServletResponse res,FilterChain chain) throws IOException, ServletException {

        HttpServletRequest request = (HttpServletRequest) req;
        HttpServletResponse response = (HttpServletResponse) res;

        MyResponse myResponse = new MyResponse(response);

        chain.doFilter(request,myResponse);

        //取得缓存中的内容
        byte[] data = myResponse.getBuffer();
        System.out.println("压缩前:" + data.length);

        //进行压缩
        ByteArrayOutputStream bout = new ByteArrayOutputStream();
        GZIPOutputStream gout = new GZIPOutputStream(bout);
        gout.write(data);
        gout.flush();
        gout.close();
        data = bout.toByteArray();
        System.out.println("压缩后:" + data.length);

        //通知浏览器接收是的一个压缩型数据库和长度
        response.setHeader("content-encoding","gzip");
        response.setHeader("content-length",data.length+"");

        //以字节方式真正输出到浏览器
        response.getOutputStream().write(data);

        //无限压缩,无出口,类似环无限循环
        //myResponse.getOutputStream().write(data);
    }
    public void init(FilterConfig filterConfig) throws ServletException {
    }
}

MyResponse


import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

//对response对象的装饰/包装
public class MyResponse extends HttpServletResponseWrapper{
    private HttpServletResponse response;
    //缓存
    private ByteArrayOutputStream bout = new ByteArrayOutputStream();
    private PrintWriter pw;
    public MyResponse(HttpServletResponse response) {
        super(response);
        this.response = response;
    }
    //重写父类方法,目的是将字节输出到缓存中去[字节]
    public ServletOutputStream getOutputStream() throws IOException {
        return new MyServletOutputStream(bout);
    }
    //重写父类方法,目的是将字符输出到缓存中去[字符]
    public PrintWriter getWriter() throws IOException {
        pw = new PrintWriter(new OutputStreamWriter(bout,"UTF-8"));
        return pw;
    }
    //取得缓存中的数据
    public byte[] getBuffer(){
        if(pw!=null){
            pw.flush();
        }
        return bout.toByteArray();
    }
}
//带有缓存功能ServletOutputStream
class MyServletOutputStream extends ServletOutputStream{
    private ByteArrayOutputStream bout;
    public MyServletOutputStream(ByteArrayOutputStream bout) {
        this.bout = bout;
    }
    public void write(int b) throws IOException {
    }
    public void write(byte[] bytes) throws IOException {
        //将字节数组的内容写入缓存
        bout.write(bytes);
        //确保所有字节数组内容进入缓存
        bout.flush();
    }
}

以上是关于response增强案例—压缩响应=学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

重温Servlet学习笔记--response对象

Javaweb学习笔记8(Response对象)

Bootstrap 学习笔记1

压缩服务栈的响应

[javaweb]Java过滤器与包装设计模式的实用案例.

20160322 javaweb 学习笔记--response 重定向