发新话题
移动帖子 加入精华 加入置顶 加入收藏 关注此帖

一段我自己使用的通用日志过滤器,支持GZIP压缩



一段我自己使用的通用日志过滤器,支持GZIP压缩

package net.java2000.forum.util;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Set;
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;
import net.java2000.forum.Setting;
import net.java2000.forum.service.SettingService;
import net.java2000.tools.DateTools;

public class CommonFilter implements Filter {
  public void init(FilterConfig filterConfig) throws ServletException {
  }

  public void destroy() {
  }

  private static int delayTime = -1;

  private static Set<String> pageSet = null;

  private static SettingService settingService = (SettingService) Factory.getBean("SettingService");

  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException,
      ServletException {
    HttpServletRequest requestHttp = (HttpServletRequest) request;

    String __USERNAME = (String) requestHttp.getSession().getAttribute("SESSION_LOGIN_USERNAME");
    String ctx = requestHttp.getContextPath();
    if (pageSet == null) {
      synchronized (this) {
        if (pageSet == null) {
          Set<String> o = ((NotTracePageSet) Factory.getBean("NotTracePageSet")).getSet();
          pageSet = new HashSet<String>();
          for (String s : o) {
            pageSet.add(ctx + s);
          }
        }
      }
    }
    if (delayTime < 0) {
      Setting s = settingService.findByKey(Setting.THREAD_DELAY_TIME);
      if (s == null) {
        delayTime = Setting.THREAD_DELAY_TIME_DEFAULT;
      } else {
        delayTime = s.getIntValue(Setting.THREAD_DELAY_TIME_DEFAULT);
      }
    }
    long begin = System.currentTimeMillis();
    String url = requestHttp.getRequestURL().toString();
    String qs = requestHttp.getQueryString();
    String size = "";
    HttpServletResponse resp = (HttpServletResponse) response;
    // 我默认关闭了GZIP,如果需要,吧那个=null去掉即可
    String transferEncoding = null; //(url.indexOf("NOGZIP") == -1) ? null : getGZIPEncoding((HttpServletRequest) request);
    if (transferEncoding == null) {
      try {
        // if (__USERNAME != null) {
        // synchronized (__USERNAME) {
        chain.doFilter(request, response);
        // Thread.sleep(delayTime); // 限制每个用户的速度
        // }
        // } else {
        // chain.doFilter(request, response);
        // }
      } catch (Exception ex) {
        ex.printStackTrace();
      }
    } else {
      ReduceWrapper wrapper = new ReduceWrapper(resp);
      try {
        chain.doFilter(request, wrapper);
      } catch (Exception ex) {
        ex.printStackTrace();
      }
      byte[] gzipData = wrapper.getResponseData();
      if (gzipData.length > 1024) {
        gzipData = gzip(wrapper.getResponseData());
        size = wrapper.getResponseData().length + "=>" + gzipData.length;
        resp.addHeader("Content-Encoding", "gzip");
        resp.setContentLength(gzipData.length);
      }
      ServletOutputStream output = response.getOutputStream();
      output.write(gzipData);
      output.flush();
    }
    String uri = requestHttp.getRequestURI();
    long time = (System.currentTimeMillis() - begin); // - (__USERNAME != null ? delayTime : 0));
    if (!pageSet.contains(uri)) {
      System.out.println("<DATE>" + DateTools.now() + "</DATE><COST>" + time + "</COST><USER>"
          + (__USERNAME == null ? "" : __USERNAME) + "</USER><METHOD>" + requestHttp.getMethod() + "</METHOD><AGE>" + url
          + (qs == null ? "" : ("?" + qs)) + "</PAGE><IP>" + request.getRemoteAddr() + "</IP><SIZE>" + size + "</SIZE>");
    }
  }

  @SuppressWarnings("unused")
  private String getGZIPEncoding(HttpServletRequest request) {
    String acceptEncoding = request.getHeader("Accept-Encoding");
    if (acceptEncoding == null) {
      return null;
    }
    acceptEncoding = acceptEncoding.toLowerCase();
    if (acceptEncoding.indexOf("x-gzip") >= 0) {
      return "x-gzip";
    }
    if (acceptEncoding.indexOf("gzip") >= 0) {
      return "gzip";
    }
    return null;
  }

  private byte[] gzip(byte[] data) {
    ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(10240);
    GZIPOutputStream output = null;
    try {
      output = new GZIPOutputStream(byteOutput);
      output.write(data);
    } catch (IOException ex) {
      ex.printStackTrace();
    } finally {
      if (output != null) {
        try {
          output.close();
        } catch (IOException ex) {
          ex.printStackTrace();
        }
      }
    }
    return byteOutput.toByteArray();
  }
}

class ReduceWrapper extends HttpServletResponseWrapper {
  public static final int OT_NONE = 0, OT_WRITER = 1, OT_STREAM = 2;

  private int outputType = OT_NONE;

  private ServletOutputStream output = null;

  private PrintWriter writer = null;

  private ByteArrayOutputStream buffer = null;

  public ReduceWrapper(HttpServletResponse resp) throws IOException {
    super(resp);
    buffer = new ByteArrayOutputStream();
  }

  @Override
  public PrintWriter getWriter() throws IOException {
    if (outputType == OT_STREAM)
      throw new IllegalStateException();
    else if (outputType == OT_WRITER)
      return writer;
    else {
      outputType = OT_WRITER;
      writer = new PrintWriter(new OutputStreamWriter(buffer, getCharacterEncoding()));
      return writer;
    }
  }

  @Override
  public ServletOutputStream getOutputStream() throws IOException {
    if (outputType == OT_WRITER)
      throw new IllegalStateException();
    else if (outputType == OT_STREAM)
      return output;
    else {
      outputType = OT_STREAM;
      output = new WrappedOutputStream(buffer);
      return output;
    }
  }

  @Override
  public void flushBuffer() throws IOException {
    if (outputType == OT_WRITER)
      writer.flush();
    if (outputType == OT_STREAM)
      output.flush();
  }

  @Override
  public void reset() {
    outputType = OT_NONE;
    buffer.reset();
  }

  public byte[] getResponseData() throws IOException {
    flushBuffer();
    return buffer.toByteArray();
  }

  class WrappedOutputStream extends ServletOutputStream {
    private ByteArrayOutputStream buffer;

    public WrappedOutputStream(ByteArrayOutputStream buffer) {
      this.buffer = buffer;
    }

    @Override
    public void write(int b) throws IOException {
      buffer.write(b);
    }

    public byte[] toByteArray() {
      return buffer.toByteArray();
    }
  }
}
快乐渡过每一天,减肥坚持每一天
编辑 回复 快速回复 TOP

Re:一段我自己使用的通用日志过滤器,支持GZIP压缩

----------------------http://michelecindy.javaeye.com
编辑 回复 快速回复 TOP
发新话题