Java 图片资源 缓存 压缩 服务(EHCache、Thumbnails)

研发 01/10 阅读 38 views次 人气 0
摘要:

客户端大量的图片展示较为慢,为让客户端快速展示,因此把必要图片按照对应的尺寸压缩放到缓存中,再次访问时提升展示效率,不必要压缩的暂不处理,这里为案例代码。

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.what21</groupId>
	<artifactId>ResourceService2.0</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>ResourceService2.0 Maven Webapp</name>
	<url>http://maven.apache.org</url>
	
	<dependencies>
		<dependency>
			<groupId>net.sf.ehcache</groupId>
			<artifactId>ehcache</artifactId>
			<version>2.10.6</version>
		</dependency>
		<dependency>
			<groupId>net.coobird</groupId>
			<artifactId>thumbnailator</artifactId>
			<version>0.4.8</version>
		</dependency>
	</dependencies>
	
	<build>
		<finalName>ResourceService2.0</finalName>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<version>3.1</version>
				<configuration>
					<source>1.8</source>
					<target>1.8</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>


ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
 
<ehcache>
     
    <!-- 设置缓存文件创建路径 -->
    <diskStore path="java.io.tmpdir"/>
     
    <!--
        maxEntriesLocalHeap : 堆内存中最大缓存对象数,0没有限制;
        eternal: true,对象是永久有效,timeout将被忽略;
        timeToIdleSeconds: 缓存过期前的闲置时间;
        timeToLiveSeconds: 缓存过期前的生存时间,创建时间到失效时间的间隔为存活时间;
                        注:timeToIdleSeconds和timeToLiveSeconds: 当eternal为false时,这个属性才有效,0为不限制;
        maxEntriesLocalDisk: 磁盘中的最大对象数,默认为0不限制;
        diskExpiryThreadIntervalSeconds: 使用过期算法清除磁盘中失效对象的间隔;
        memoryStoreEvictionPolicy: 当超过最大内存限制时,根据指定的策略去清理内存。默认策略是LRU。
                         清理内存的三种算法: LRU(最近最少使用) 、LFU(较少使用)、FIFO(先进先出)
    --> 
    <cache name="resCache"
        maxEntriesLocalHeap="10000"
        eternal="false"
        timeToIdleSeconds="60"
        timeToLiveSeconds="60"
        maxEntriesLocalDisk="10000000"
        diskExpiryThreadIntervalSeconds="30"
        memoryStoreEvictionPolicy="LRU">
        <!-- 
                                持久化策略: localTempSwap、localRestartable
        -->
        <persistence strategy="localTempSwap"/>   
    </cache>
</ehcache>


ResHttpServlet.java

package com.what21.resource;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.coobird.thumbnailator.Thumbnails;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;

@WebServlet(urlPatterns = "/res/*", loadOnStartup = 1, asyncSupported = true)
public class ResHttpServlet extends HttpServlet {

	private static final long serialVersionUID = -1609934533558476383L;

	private Cache resCache;

	@Override
	public void init() throws ServletException {
		String path = ResHttpServlet.class.getResource("/ehcache.xml").getPath().toString();
		System.out.println("path = " + path);
		// 创建 CacheManager
		CacheManager manager = CacheManager.create(path);
		// 获取默认的
		resCache = manager.getCache("resCache");
		System.out.println("resCache = " + resCache);
	}

	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		// 1、获取请求地址和请求参数
		String uri = request.getRequestURI();
		if(!"".equals(request.getContextPath())) {
			uri = uri.substring(request.getContextPath().length(), uri.length());
		}
		String spec = request.getParameter("spec");
		System.out.println("请求地址 = " + uri + ",请求参数=" + spec);

		// 2、计算出压缩尺寸
		int width = -1;
		int height = -1;
		if(spec!=null) {
			String[] strs = spec.split("×");
			if (strs != null && strs.length == 2) {
				width = Integer.parseInt(strs[0]);
				height = Integer.parseInt(strs[1]);
			}
		}
		
		// 4、根据配置参数判断是否压缩处理
		int configWidth = 300; // 来自后台配置参数
		int configHeight = 150; // 来自后台配置参数
		String path = "E:\\Apps\\image\\";
		byte[] resBytes = new byte[512];
		Element element = null;
		if (width != -1 || height != -1) {
			if (configWidth == width && configHeight == height) {
				// 从缓存中取
				element = resCache.get(uri);
				if (element == null) {
					ByteArrayOutputStream bout = new ByteArrayOutputStream();
					Thumbnails.of(path + uri).width(configWidth).height(configHeight).toOutputStream(bout);
					resBytes = bout.toByteArray();
					element = new Element(uri, resBytes);
					resCache.put(element);
					System.out.println("图片按照规格已缓存.......");
				} else {
					resBytes = (byte[]) element.getObjectValue();
					System.out.println("访问到缓存中.......");
				}
			} else {
				// 根据客户端请求参数压缩
				Thumbnails.of(path + uri).width(width).height(height).toOutputStream(response.getOutputStream());
				return;
			}
		} else {
			// 根据系统配置参数压缩输出
			element = resCache.get(uri);
			if (element == null) {
				ByteArrayOutputStream bout = new ByteArrayOutputStream();
				Thumbnails.of(path + uri).width(configWidth).height(configHeight).toOutputStream(bout);
				resBytes = bout.toByteArray();
				element = new Element(uri, resBytes);
				resCache.put(element);
				System.out.println("图片按照规格已缓存.......");
			} else {
				resBytes = (byte[]) element.getObjectValue();
				System.out.println("访问到缓存中.......");
			}
		}
		response.getOutputStream().write(resBytes);
	}

}


访问查看效果:

http://127.0.0.1:8090/res/res/2/123.png

http://127.0.0.1:8090/res/res/2/123.png?spec=800×600


评论

表情

分享到: