首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 网站开发 > Web前端 >

施用gzip优化web应用(filter实现) (转)

2012-08-28 
使用gzip优化web应用(filter实现) (转)相关知识:  gzip是http协议中使用的一种加密算法,客户端向web服务器

使用gzip优化web应用(filter实现) (转)

相关知识:

  gzip是http协议中使用的一种加密算法,客户端向web服务器端发出了请求后,通常情况下服务器端会将页面文件和其他资源,返回到客户端,客户端加载后渲染呈现,这种情况文件一般都比较大,如果开启Gzip ,那么服务器端响应后,会将页面,JS,CSS等文本文件或者其他文件通过高压缩算法将其压缩,然后传输到客户端,由客户端的浏览器负责解压缩与呈现。通常能节省40%以上的流量(一般都有60%左右),一些PHP,JSP文件也能够进行压缩。

实????? 现:  

Tomcat 开启Gzip :

1.找到Tomcat 目录下的conf下的server.xml,并找到如下信息

Connector port="8080" maxHttpHeaderSize="8192" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" redirectPort="8443" acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true"

将它改成如下的形式(其实在上面代码的下面已经有了,将他们打开而已。):

<!-- Define a non-SSL HTTP/1.1 Connector on port 8080 --> <Connector port="8080" maxHttpHeaderSize="8192" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" redirectPort="8443" acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true" compression="on" compressionMinSize="2048" noCompressionUserAgents="gozilla, traviata" compressableMimeType="text/html,text/xml" >

这样,就能够对html和xml进行压缩了,如果要压缩css 和 js,那么需要将

compressableMimeType=”text/html,text/xml”加入css和js:

<Connector port="8080" ......... compressableMimeType="text/html,text/xml,text/css,text/javascript" >

你甚至可以压缩图片:

compressableMimeType=”text/html,text/xml”加入css和js:

<Connector port="8080" ......... compressableMimeType="text/html,text/xml,text/css,text/javascript,image/gif,image/jpg" >

开启后重启Tomcat ,通过浏览器查看headers信息就能看到是否开启(firebug中有),如果开启了,那么transfer-encoding就会是Gzip,否则就是chunked。

?

在代码级别完成web应用的gzip压缩的开启:

?

1.Wrapper? 用来包装HttpServletResponse 对象?

Java代码
public class Wrapper 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 Wrapper(HttpServletResponse resp) throws IOException { super(resp); buffer = new ByteArrayOutputStream(); } 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; } } 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; } } public void flushBuffer() throws IOException { if(outputType==OT_WRITER) writer.flush(); if(outputType==OT_STREAM) output.flush(); } 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; } public void write(int b) throws IOException { buffer.write(b); } public byte[] toByteArray() { return buffer.toByteArray(); } }}

package com.shop.gzip;

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;

public class Wrapper 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 Wrapper(HttpServletResponse resp) throws IOException {
??? ??? super(resp);
??? ??? buffer = new ByteArrayOutputStream();
??? }

??? 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;
??? ??? }
??? }

??? 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;
??? ??? }
??? }

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

??? 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;
??? ??? }

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

??? ??? public byte[] toByteArray() {
??? ??? ??? return buffer.toByteArray();
??? ??? }
??? }
}

?

?

2.过滤器

?

Java代码
public class GZipFilter implements Filter{ public void destroy() {  // TODO Auto-generated method stub   } public void doFilter(ServletRequest request, ServletResponse response,   FilterChain chain) throws IOException, ServletException    {   System.out.println("进入过滤器");   HttpServletResponse resp = (HttpServletResponse)response;   Wrapper wrapper = new Wrapper(resp);   chain.doFilter(request, wrapper);   byte[] gzipData = gzip(wrapper.getResponseData());   resp.addHeader("Content-Encoding", "gzip");   resp.setContentLength(gzipData.length);   ServletOutputStream output = response.getOutputStream();   output.write(gzipData);   output.flush();   } public void init(FilterConfig arg0) throws ServletException {  // TODO Auto-generated method stub   } private byte[] gzip(byte[] data) {  ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(10240);  GZIPOutputStream output = null;  try {  output = new GZIPOutputStream(byteOutput);  output.write(data);  }  catch (IOException e) {}  finally {  try {  output.close();  }  catch (IOException e) {}  }  return byteOutput.toByteArray();  } }

?

?package com.shop.gzip;

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.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class GZipFilter implements Filter {

?? ?public void destroy() {
?? ?}
?? ?? /**
?? ??? * 判断浏览器是否支持GZIP
?? ??? * @param request
?? ??? * @return
?? ??? */
?? ?? private static boolean isGZipEncoding(HttpServletRequest request){
?? ???? boolean flag=false;
?? ???? String encoding=request.getHeader("Accept-Encoding");
?? ???? if(encoding.indexOf("gzip")!=-1){
?? ?????? flag=true;
?? ???? }
?? ???? return flag;
?? ?? }
?? ? ?
?? ?public void doFilter(ServletRequest request, ServletResponse response,
?? ??? ??? ?FilterChain chain) throws IOException, ServletException {
?? ??? ?HttpServletResponse resp = (HttpServletResponse) response;
?? ???? HttpServletRequest req=(HttpServletRequest)request;
?? ???? if(isGZipEncoding(req)){
?? ??? ??? ?Wrapper wrapper = new Wrapper(resp);
?? ??? ??? ?chain.doFilter(request, wrapper);
?? ??? ??? ?byte[] gzipData = gzip(wrapper.getResponseData());
?? ??? ??? ?resp.addHeader("Content-Encoding", "gzip");
?? ??? ??? ?resp.setContentLength(gzipData.length);
?? ??? ??? ?ServletOutputStream output = response.getOutputStream();
?? ??? ??? ?output.write(gzipData);
?? ??? ??? ?output.flush();
?? ???? } else {
?? ???????? chain.doFilter(request, response);
?? ???? }?? ??? ?

?? ?}

?? ?public void init(FilterConfig arg0) throws ServletException {

?? ?}

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

}

3.在web.xml中配置 GZipFilter,当我们访问应用中以.do结尾的资源的使用,服务器端就开启http gzip压缩,将压缩后的信息通过http 协议传递给浏览器.??

??

Xml代码

<filter>??

  <filter-name>ecsideExport</filter-name>??

  <filter-class>com.web.servlet.GZipFilter</filter-class>??

?</filter>??

<filter-mapping>??

?????????????<filter-name>ecsideExport</filter-name>??

????????????<url-pattern>*.do</url-pattern>??

</filter-mapping>???

热点排行