您的位置:首页 > Web前端 > JavaScript

J2EE的压缩输出流的过滤器实现(来自于Head first Servlets and jsp)

2011-01-29 11:51 375 查看
可以应用到html,但不适用于png,和mpeg因为它们已经被压缩过了

Accept-Encoding=gzip,deflate

响应中:Vary=Accept-Encoding

         Content-Encoding=gzip


package com.example.web:
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.zip.GZIPOutputStream;
public class CompressionFilter implements Filter {
private ServletContext ctx;
private FilterConfig cfg;
//覆写此方法只是为了生成日志
public void init(FilterConfig cfg) throws ServletException {
this.cfg = cfg;
ctx = cfg.getServletContext();
ctx.log(cfg.getFilterName() + “ initialized.”);
}
public void doFilter(ServletRequest req,
ServletResponse resp,
FilterChain fc)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;

//根据浏览器是否支持来确定
String valid_encodings = request.getHeader(“Accept-Encoding”);
if ( valid_encodings.indexOf(“gzip”) > -1 ) {

CompressionResponseWrapper wrappedResp
= new CompressionResponseWrapper(response);
wrappedResp.setHeader(“Content-Encoding”, “gzip”);

fc.doFilter(request, wrappedResp);
//参见GZIPOutputStream的api
GZIPOutputStream gzos = wrappedResp.getGZIPOutputStream();
gzos.finish();

ctx.log(cfg.getFilterName() + “: finished the request.”);
} else {
ctx.log(cfg.getFilterName() + “: no encoding performed.”);
fc.doFilter(request, response);
}
}
public void destroy() {
// nulling out my instance variables
cfg = null;
ctx = null;
}
}

package com.example.web;
// Servlet imports
import javax.servlet.http.*;
import javax.servlet.*;
// I/O imports
import java.io.*;
import java.util.zip.GZIPOutputStream;
class CompressionResponseWrapper extends HttpServletResponseWrapper {
private GZIPServletOutputStream servletGzipOS = null;
private PrintWriter pw = null;
CompressionResponseWrapper(HttpServletResponse resp) {
super(resp);
}
//由于使用压缩,此方法不需使用
public void setContentLength(int len) { }

public GZIPOutputStream getGZIPOutputStream() {
return this.servletGzipOS.internalGzipOS;
}
//标识是使用OutputStream还是PrintWriter
private Object streamUsed = null;
public ServletOutputStream getOutputStream() throws IOException {
//确定要么是用getWriter要么是用getOutputStream不能两个一起用

if ((streamUsed != null) && (streamUsed != pw)) {
throw new IllegalStateException();
}

if ( servletGzipOS == null ) {
servletGzipOS
= new GZIPServletOutputStream(getResponse()
.getOutputStream());
streamUsed = servletGzipOS;
}
return servletGzipOS;
}
public PrintWriter getWriter() throws IOException {

//确定要么是用getWriter要么是用getOutputStream不能两个一起用
if ( (streamUsed != null) && (streamUsed != servletGzipOS)) {
throw new IllegalStateException();
}

if ( pw == null ) {

servletGzipOS
= new GZIPServletOutputStream(getResponse()
.getOutputStream());
//注意这里要根据编码格式,应该是在自己的servlet,JSP中确定
// response.setContentType("text/html;charset=gb2312");

//response.setCharacterEncoding("GBK");
//<%@ page contentType="text/html; charset=utf-8" %>

OutputStreamWriter osw = new OutputStreamWriter(servletGzipOS,
getResponse().getCharacterEncoding());

pw = new PrintWriter(osw);
streamUsed = pw;
}
return pw;
}
}

class GZIPServletOutputStream extends ServletOutputStream {
//包访问权限用于CompressionResponseWrapper来调用
GZIPOutputStream internalGzipOS;
/** Decorator constructor */
GZIPServletOutputStream(ServletOutputStream sos) throws IOException {
this.internalGzipOS = new GZIPOutputStream(sos);
}
// This method implements the compression decoration by delegating
//the write() call to the GZIP compression stream, which is wrapping
//the original ServletOutputStream, (which in turn is ultimately
//wrapping the TCP network output stream to the client).
public void write(int param) throws java.io.IOException {
internalGzipOS.write(param);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: