filter拦截(Response输出压缩)此案例基础知识面广

本文详细介绍了如何通过GzipFilter实现HTTP响应的压缩,包括在配置文件中设置filter映射,自定义GzipFilter类实现Filter接口,以及处理getOutputStream()和getWriter()两种响应输出方式。示例代码展示了如何进行数据压缩和设置响应头信息,确保正确处理字符编码和防止乱码问题。
摘要由CSDN通过智能技术生成
Response两种输出方式:1.getOutputStream().writer();2.getWriter().writer();但不能同时存在
1.配置文件
<filter>
    <filter-name>GzipFilter</filter-name>
    <filter-class>cn.itcast.web.filter.GzipFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>GzipFilter</filter-name>
    <url-pattern>*.jsp</url-pattern><!-- 注意一般不要做全栈压缩,只压缩html,jsp,js -->
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
</filter-mapping>
<filter-mapping>
    <filter-name>GzipFilter</filter-name>
    <url-pattern>*.html</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>GzipFilter</filter-name>
    <url-pattern>*.js</url-pattern>
</filter-mapping>
2.定义 GzipFilter类并 implements Filter
 public class GzipFilter implements Filter {
@Override
    public void doFilter(ServletRequest req, ServletResponse resp,FilterChain chain) throws IOException, ServletException {
        HttpServletRequest request=(HttpServletRequest) req;
        HttpServletResponse response=(HttpServletResponse) resp;
           MyResponse myresponse=new MyResponse(response);
        chain.doFilter(request, myresponse);     //response.getWriter response.getOutputStream
             //取出缓冲数据压缩后输出
             byte out[]=myresponse.getBuffer();
            System.out.println("压缩前:"+out.length);
             byte gzipout[]=gzip(out);
            System.out.println("压缩后:"+gzipout.length);
            //设置头信息,以压缩方式打开  
            response.setHeader("content-encoding", "gzip");
            response.setHeader("content-length", gzipout.length+"");
 
             response. getOutputStream(). write(gzipout);     //分别对应下面橙色A/B/C
    }
public byte[]  gzip(byte b[]) throws IOException{     //压缩
     ByteArrayOutputStream bout=new ByteArrayOutputStream();
     GZIPOutputStream gout=new GZIPOutputStream(bout);
gout.write(b);
gout.close();
return bout.toByteArray();
}
 
class MyResponse extends HttpServletResponseWrapper{     //A处对应上面response
    private ByteArrayOutputStream bout=new ByteArrayOutputStream();     //定义缓冲区 数组字节流
        private PrintWriter pw;
        private HttpServletResponse response;
    public MyResponse(HttpServletResponse response) {
        super(response);
        this.response=response;
    }
//response输出数据方式一:response.getOutputStream().write("xxxx");
@Override
public  ServletOutputStream  getOutputStream() throws IOException {    // B 处对应上面getOutputStream
    return new MyServletOutputStream(bout);  //response.getOutputStream.write(); 因 ServletOutputStream是abstract类,不能直接 new
    }

//response输出数据方式二:response.getWriter().write("xxxx");
@Override
public  PrintWriter  getWriter() throws IOException{
     // pw=new PrintWriter(bout); //字符流向字节流写数据,会查编码,默认GB2312,所以要注意乱码问题
     pw=new PrintWriter(new OutputStreamWriter(bout,response.getCharacterEncoding()));     //用于解决PrintWriter().writer()的乱码问题
    return pw;      //MyResponse.getWriter.write("xxx");
}
//将缓冲区中的数据返回
public byte[]  getBuffer(){
    if(pw!=null){    
    pw.close();     //保证数据会写入缓冲区,当用PrintWrier输出时,此判断有效
    }
        return bout.toByteArray();  
    }
}

class MyServletOutputStream extends ServletOutputStream{    / / B 处对应上面getOutputStream
    private ByteArrayOutputStream bout;
     public MyServletOutputStream(ByteArrayOutputStream bout){
           this.bout=bout;
   }
@Override
         public void  write(int b) throws IOException {   //覆写write方法// c 处对应上面write
             bout.write(b);
    }
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub

}

@Override
public void destroy() {
// TODO Auto-generated method stub

}

}

3.Servlet代码编写
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

String data="中国";
//response.getOutputStream().write( data.getBytes("UTF-8")); //一定要指编码,用于解决getOutputStream().write输出乱码
response.getWriter().write(data); //getWriter().writer输出的乱码问题在拦截代码中处理。
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值