GZIP compressed resource file

When we browse a website, we will find that the transmission speed of static files takes up a large part of the time, especially when the network speed is extremely slow, js and css file compression schemes appear. As far as I know, the current The compression is mainly divided into two categories:
the first category, remove the spaces and comments in the js and css files, and shorten the long variable function names. For example, our common files that end with min.js are the compressed files. .
The second type is the GZIP compression I want to talk about. The principle is: compress the js and css files through gzip on the server side, send the compressed package to the front end, and the browser parses it. At present, most mainstream browsers and application servers all support GZIP technology and can be used after configuration.
Although the configuration can be used, there are also inconveniences in my personal feeling.
First, if the application server is changed, it needs to be reconfigured.
Second, it is compressed every time it needs to be used. Although the cache can be configured, it still puts pressure on the server.
Therefore, GZIP compression technology is implemented in the code to achieve cross-platform, one-time compression and multiple use.
Let's just talk about my ideas directly from the application server. First configure the interceptor to intercept all requests at the end of js and css files:

<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>

 Down the interceptor code:

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();
	}

}

 The main idea is to judge whether there is a compressed file, if not, start a thread to create a compressed file, and if the file is compressed, use the compressed file, and do not do any operation if it is not compressed.

Down the thread code:

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 ();
		}

	}

}

 The thread calls a method that produces a GZIP file.

The code to generate the GZIP file found on the Internet:

public abstract class GZipUtils {

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

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

		// compress
		compress(bais, baos);

		byte[] output = baos.toByteArray();

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

		bais.close();

		return output;
	}

	/**
	 * File compression
	 *
	 * @param file
	 * @throws Exception
	 */
	public static void compress(File file) throws Exception {
		compress(file, true);
	}

	/**
	 * File compression
	 *
	 * @param file
	 * @param delete
	 * Whether to delete the original file
	 * @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();
		}
	}

	/**
	 * data compression
	 *
	 * @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();
	}

	/**
	 * File compression
	 *
	 * @param path
	 * @throws Exception
	 */
	public static void compress(String path) throws Exception {
		compress(path, true);
	}

	/**
	 * File compression
	 *
	 * @param path
	 * @param delete
	 * Whether to delete the original file
	 * @throws Exception
	 */
	public static void compress(String path, boolean delete) throws Exception {
		File file = new File(path);
		compress(file, delete);
	}

	/**
	 * Data decompression
	 *
	 * @param data
	 * @return
	 * @throws Exception
	 */
	public static byte[] decompress(byte[] data) throws Exception {
		ByteArrayInputStream bais = new ByteArrayInputStream(data);
		ByteArrayOutputStream baos = new ByteArrayOutputStream();

		// unzip

		decompress(bais, baos);

		data = baos.toByteArray();

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

		bais.close();

		return data;
	}

	/**
	 * File decompression
	 *
	 * @param file
	 * @throws Exception
	 */
	public static void decompress(File file) throws Exception {
		decompress(file, true);
	}

	/**
	 * File decompression
	 *
	 * @param file
	 * @param delete
	 * Whether to delete the original file
	 * @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();
		}
	}

	/**
	 * Data decompression
	 *
	 * @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();
	}

	/**
	 * File decompression
	 *
	 * @param path
	 * @throws Exception
	 */
	public static void decompress(String path) throws Exception {
		decompress(path, true);
	}

	/**
	 * File decompression
	 *
	 * @param path
	 * @param delete
	 * Whether to delete the original file
	 * @throws Exception
	 */
	public static void decompress(String path, boolean delete) throws Exception {
		File file = new File(path);
		decompress(file, delete);
	}

}

 

In this way, after we start the container, when someone accesses a static file for the first time, we create a compressed file in the same directory, and access our static file directly when accessing it again later. When we view the response header information of the resource in the browser, if there is Content-Encoding:gzip字段表明配置成功。

Of course, we can use both compression methods, the compression effect is better, first remove spaces, comments, modify variables, and then use gzip compression.

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326641320&siteId=291194637
Recommended