`
l821398100
  • 浏览: 16312 次
社区版块
存档分类
最新评论
阅读更多

在我们浏览一个网站时,我们会发现,静态文件加载时传输速度占了很大一部分时间,尤其是在网速超慢的情况下,js、css文件压缩方案就出现了,据个人所知目前的压缩主要分为两类:
第一类,去掉js、css文件中的空格、注释,并且把长的变量函数名变短,比如我们常见的已min.js结尾的文件就是这样压缩后的文件。
第二类,就是我要说的GZIP压缩了,其原理是:在服务器端把js、css文件通过gzip压缩,把压缩包传到前端,浏览器解析。目前基本上主流的浏览器和应用服务器都支持GZIP技术,配置即可使用。
虽然配置即可使用,但是个人感觉也有不便之处。
其一,换了应用服务器,需要重新配置.
其二,每次需要用时才压缩,虽然可配置缓存,但这依然对服务器是个压力。
所以就在代码中实现GZIP压缩技术,实现跨平台、一次压缩多次使用,不以来如应用服务器
下来直接就说我的思路吧。首先配置拦截器,拦截所有js、css文件结尾的请求:

 <filter>  
	 <filter-name>gzip</filter-name>  
	 <filter-class>xx.xx.GzipFilter</filter-class>  
</filter>  
	  
<filter-mapping>  
	 <filter-name>gzip</filter-name>  
	 <url-pattern>*.js</url-pattern>  
</filter-mapping>
<filter-mapping>  
	 <filter-name>gzip</filter-name>  
	 <url-pattern>*.css</url-pattern>  
</filter-mapping>

 下来拦截器代码:

public class GzipFilter implements Filter {

	private ServletContext ctx;
	private Logger logger = Logger.getLogger(GzipFilter.class.getName());
	private String contextPath;
	private String realPath;

	@Override
	public void destroy() {

	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
		HttpServletRequest req = (HttpServletRequest) request;
		HttpServletResponse res = (HttpServletResponse) response;
		String uri = req.getRequestURI();
		String accept = req.getHeader("Accept-Encoding");
		contextPath = ctx.getContextPath();
		realPath = ctx.getRealPath("/");
		uri = uri.substring(contextPath.length());
		InputStream in = ctx.getResourceAsStream(uri + GZipUtils.EXT);
		if (in == null) {
			GzipThread gzipThread = new GzipThread(realPath + uri);
			gzipThread.run();
		}
		if (accept != null && accept.contains("gzip") && (in = ctx.getResourceAsStream(uri + GZipUtils.EXT)) != null) {
			logger.info("start getting gzip file " + uri);
			ByteArrayOutputStream bout = new ByteArrayOutputStream();
			byte[] b = new byte[1024 * 8];
			int read = 0;
			while ((read = in.read(b)) >= 0) {
				bout.write(b, 0, read);
			}
			in.close();

			res.setHeader("Content-Encoding", "gzip");
			if (uri.contains(".js")) {
				res.setContentType("application/javascript;charset=UTF-8");
			}
			if (uri.contains(".css")) {
				res.setContentType("text/css;charset=UTF-8");
			}
			res.setContentLength(bout.size());

			ServletOutputStream out = res.getOutputStream();
			out.write(bout.toByteArray());
			out.flush();
			logger.info("finish getting gzip file " + uri);
			return;
		} else {
			chain.doFilter(request, response);
		}
	}

	@Override
	public void init(FilterConfig config) throws ServletException {
		ctx = config.getServletContext();
	}

}

 主要思路是判断是否存在压缩后的文件,如果不存在则开启一个线程去创建压缩文件,下来如果文件压缩好了则用压缩后文件,没压缩好直接不做操作。

下来线程代码:

public class GzipThread implements Runnable {

	File file = null;

	public GzipThread(String filePath) {
		this.file = new File(filePath);
	}

	@Override
	public void run() {
		try {
			GZipUtils.compress(file, false);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}

 线程中调用一个产生GZIP文件的方法。

从网上找来的产生GZIP文件的代码:

public abstract class GZipUtils {

	public static final int BUFFER = 1024;
	public static final String EXT = ".gz";

	/**
	 * 数据压缩
	 * 
	 * @param data
	 * @return
	 * @throws Exception
	 */
	public static byte[] compress(byte[] data) throws Exception {
		ByteArrayInputStream bais = new ByteArrayInputStream(data);
		ByteArrayOutputStream baos = new ByteArrayOutputStream();

		// 压缩
		compress(bais, baos);

		byte[] output = baos.toByteArray();

		baos.flush();
		baos.close();

		bais.close();

		return output;
	}

	/**
	 * 文件压缩
	 * 
	 * @param file
	 * @throws Exception
	 */
	public static void compress(File file) throws Exception {
		compress(file, true);
	}

	/**
	 * 文件压缩
	 * 
	 * @param file
	 * @param delete
	 *            是否删除原始文件
	 * @throws Exception
	 */
	public static void compress(File file, boolean delete) throws Exception {
		FileInputStream fis = new FileInputStream(file);
		FileOutputStream fos = new FileOutputStream(file.getPath() + EXT);

		compress(fis, fos);

		fis.close();
		fos.flush();
		fos.close();

		if (delete) {
			file.delete();
		}
	}

	/**
	 * 数据压缩
	 * 
	 * @param is
	 * @param os
	 * @throws Exception
	 */
	public static void compress(InputStream is, OutputStream os) throws Exception {

		GZIPOutputStream gos = new GZIPOutputStream(os);

		int count;
		byte data[] = new byte[BUFFER];
		while ((count = is.read(data, 0, BUFFER)) != -1) {
			gos.write(data, 0, count);
		}

		gos.finish();

		gos.flush();
		gos.close();
	}

	/**
	 * 文件压缩
	 * 
	 * @param path
	 * @throws Exception
	 */
	public static void compress(String path) throws Exception {
		compress(path, true);
	}

	/**
	 * 文件压缩
	 * 
	 * @param path
	 * @param delete
	 *            是否删除原始文件
	 * @throws Exception
	 */
	public static void compress(String path, boolean delete) throws Exception {
		File file = new File(path);
		compress(file, delete);
	}

	/**
	 * 数据解压缩
	 * 
	 * @param data
	 * @return
	 * @throws Exception
	 */
	public static byte[] decompress(byte[] data) throws Exception {
		ByteArrayInputStream bais = new ByteArrayInputStream(data);
		ByteArrayOutputStream baos = new ByteArrayOutputStream();

		// 解压缩

		decompress(bais, baos);

		data = baos.toByteArray();

		baos.flush();
		baos.close();

		bais.close();

		return data;
	}

	/**
	 * 文件解压缩
	 * 
	 * @param file
	 * @throws Exception
	 */
	public static void decompress(File file) throws Exception {
		decompress(file, true);
	}

	/**
	 * 文件解压缩
	 * 
	 * @param file
	 * @param delete
	 *            是否删除原始文件
	 * @throws Exception
	 */
	public static void decompress(File file, boolean delete) throws Exception {
		FileInputStream fis = new FileInputStream(file);
		FileOutputStream fos = new FileOutputStream(file.getPath().replace(EXT, ""));
		decompress(fis, fos);
		fis.close();
		fos.flush();
		fos.close();

		if (delete) {
			file.delete();
		}
	}

	/**
	 * 数据解压缩
	 * 
	 * @param is
	 * @param os
	 * @throws Exception
	 */
	public static void decompress(InputStream is, OutputStream os) throws Exception {

		GZIPInputStream gis = new GZIPInputStream(is);

		int count;
		byte data[] = new byte[BUFFER];
		while ((count = gis.read(data, 0, BUFFER)) != -1) {
			os.write(data, 0, count);
		}

		gis.close();
	}

	/**
	 * 文件解压缩
	 * 
	 * @param path
	 * @throws Exception
	 */
	public static void decompress(String path) throws Exception {
		decompress(path, true);
	}

	/**
	 * 文件解压缩
	 * 
	 * @param path
	 * @param delete
	 *            是否删除原始文件
	 * @throws Exception
	 */
	public static void decompress(String path, boolean delete) throws Exception {
		File file = new File(path);
		decompress(file, delete);
	}

}

 

这样,我们在启动容器后,当有人第一次访问某个静态文件时,我们就在同目录下创建一个压缩文件,以后再次访问时就直接访问我们的静态文件了。当我们在浏览器查看资源的响应头信息时,如果有Content-Encoding:gzip字段表明配置成功。

当然,我们可以把两种压缩方法都使用起来,压缩效果更佳,先去空格、注释,修改变量,然后再用gzip压缩。

 

分享到:
评论

相关推荐

    gzip压缩js,csss文件

    总结来说,通过gzip压缩js和css文件,可以有效减小文件大小,提高网页加载速度。在Windows环境下,可以利用CMD和gzip命令进行文件压缩,而在服务器端,需要配置相应的设置以支持gzip压缩。理解并掌握这一技巧,对于...

    gzip.rar_C gzip源码_c语言gzip_gzip压缩_gzip解压_poetryfem

    本文将深入探讨gzip的原理、C语言实现细节以及如何进行gzip压缩和解压缩。 首先,gzip基于著名的DEFLATE算法,该算法结合了LZ77(一种字典压缩方法)和霍夫曼编码(一种变长编码技术)。在C语言中实现gzip,我们...

    C语言编写的GZIP压缩算法(含工程文件,附带测试程序)

    总的来说,C语言编写的GZIP压缩算法是一个很好的学习资源,它涵盖了数据压缩的基本原理、C语言编程技巧以及软件工程实践。无论是对个人技能的提升还是对项目开发的理解,这个项目都将为你提供宝贵的经验。

    关于Gzip压缩js文件提高网站运行速度

    如果客户端支持Gzip,它会在请求头中包含`Accept-Encoding: gzip`字段,服务器接收到这个请求后,会将资源(如JavaScript文件)用Gzip压缩后再返回给客户端。 **提高网站运行速度** 1. **减小文件大小**:Gzip能将...

    Gzip压缩软件(gz文件压缩)

    此外,许多版本控制系统如Git也支持对提交的文件进行gzip压缩,以减小存储占用。 总的来说,gzip压缩软件是IT行业中一个基础但不可或缺的工具,它在数据压缩、存储优化和网络传输等方面发挥着重要作用。无论是个人...

    22、MapReduce使用Gzip压缩、Snappy压缩和Lzo压缩算法写文件和读取相应的文件

    以下是一个简单的示例,展示如何从Text文件写入到Gzip压缩的Text文件: ```java conf.set("mapreduce.output.fileoutputformat.compress", "true"); conf.set("mapreduce.output.fileoutputformat.compress.codec",...

    Vue CLI3 开启gzip压缩文件的方式

    webpack在打包时可以借助 compression webpack plugin 实现gzip压缩,首先需要安装该插件: npm i -D compression-webpack-plugin 在vue cli3.0 生成的项目里,可在 vue.config.js 中按照如下方式进行配置: 压缩...

    Java用GZIP压缩解压文件.rar

    本主题将深入探讨如何使用Java实现GZIP压缩和解压缩文件。 首先,让我们了解Java中的GZIPOutputStream和GZIPInputStream类,它们是处理GZIP压缩和解压缩的核心工具。`java.util.zip.GZIPOutputStream`用于将数据...

    Gzip文件压缩 实例

    在开发环境中,像Webpack这样的构建工具也支持Gzip压缩,以优化前端资源的大小。 7. **性能与限制** 虽然Gzip能够有效减少文件大小,但压缩和解压缩过程需要计算资源。对于实时性要求高的应用,可能需要权衡压缩...

    文件GZip压缩AES加密反向解密解压缩代码和jar

    本资源包“文件GZip压缩AES加密反向解密解压缩代码和jar”提供了完整的Java实现,使得开发者能够方便地对文件进行GZip压缩、AES加密,以及后续的解密和解压缩操作。下面将详细解释这些技术及其应用。 首先,GZip...

    java源码资源Java用GZIP压缩解压文件

    java源码资源Java用GZIP压缩解压文件提取方式是百度网盘分享地址

    基于java的用GZIP压缩解压文件.zip

    总之,这个压缩包文件包含了使用Java进行GZIP压缩和解压缩的基本示例,是学习和理解Java文件压缩技术的好资源。通过学习和实践这些示例,开发者可以掌握如何在实际项目中高效地处理GZIP压缩文件。

    如何压缩多个文件\文件夹(GZipStream and C#)

    `GZipStream`是这个命名空间中的一个关键类,它实现了GZIP压缩算法,可以用于处理数据流的压缩和解压缩。本篇文章将详细介绍如何利用`GZipStream`和C#进行文件或文件夹的压缩操作。 一、GZipStream介绍 GZipStream...

    IIS启用GZIP压缩js、css无效的原因及解决方法.docx

    总的来说,启用IIS的GZIP压缩对于优化网站性能至关重要,特别是对于js和css这类影响用户体验的资源。正确配置IIS的GZIP压缩设置,可以显著减少页面加载时间,提升用户访问体验。对于开发者来说,理解并掌握这一技巧...

    Java用GZIP压缩解压文件.7z

    在Java编程语言中,GZIP是一种常用的文件压缩格式,它基于DEFLATE算法,可以用于压缩和解压缩数据。在处理大文件或者网络传输时,使用GZIP进行压缩可以显著减少数据量,提高效率。本篇文章将深入探讨如何在Java中...

    gzip 压缩 三种方法

    - **缓存策略**:开启gzip压缩后,应考虑对静态资源设置合适的缓存策略,以减少不必要的压缩计算。 - **文件大小阈值**:对于非常小的文件,压缩可能并不能带来显著的优化,甚至可能因额外的压缩和解压过程而降低...

    WebLogic的GZip压缩

    WebLogic的GZip压缩是一种优化技术,用于减少通过网络传输的数据量,特别是在Web应用程序中,可以显著提升网页加载速度和服务器性能。GZip压缩利用了HTTP协议中的Content-Encoding头,服务器在发送响应到客户端...

    Java用GZIP压缩解压文件.zip

    GZIP压缩效果通常比不压缩好,但压缩和解压缩操作会消耗更多的CPU资源。在性能敏感的应用中,需要权衡压缩带来的空间节省与CPU消耗。 7. **GZIP在HTTP中的应用** 在Web开发中,GZIP常用于HTTP传输的压缩,以减少...

    gzip批量压缩js为gzjs文件

    总之,批量使用Gzip压缩JavaScript文件可以有效地减小文件体积,提高网站加载速度,同时通过编写批处理脚本,可以自动化这个过程,节省时间和资源。理解这个过程和相关工具的使用,对优化Web应用性能和提升用户体验...

    Gzip压缩技术以及压缩算法

    总的来说,Gzip压缩技术利用LZ77算法寻找和替换重复数据,然后通过Huffman编码进一步压缩结果,有效地减小了文件大小,提升了网络传输效率,特别是在HTTP通信中,它已成为优化网页加载速度的标准工具。理解Gzip的...

Global site tag (gtag.js) - Google Analytics