Java tutorial
/** * Copyright (c) 2014 http://www.lushapp.wang * * Licensed under the Apache License, Version 2.0 (the "License"); */ package com.lushapp.common.web.servlet; import net.sf.ehcache.Cache; import net.sf.ehcache.CacheManager; import net.sf.ehcache.Element; import org.apache.commons.io.IOUtils; import org.apache.commons.lang3.ArrayUtils; import org.springframework.context.ApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; import com.lushapp.common.web.utils.WebUtils; import javax.activation.MimetypesFileTypeMap; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; /** * ??Servlet. * <p/> * EhCache???, ?,?Gzip. * <p/> * ? * static-content?contentPath=img/logo.jpg * static-content?contentPath=img/logo.jpg&download=true * * @author honey.zhao@aliyun.com */ public class StaticContentServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** ?GzipMime. */ private static final String[] GZIP_MIME_TYPES = { "text/html", "application/xhtml+xml", "text/plain", "text/css", "text/javascript", "application/x-javascript", "application/json", "application/javascript" }; /** ?Gzip??. */ private static final int GZIP_MINI_LENGTH = 512; private MimetypesFileTypeMap mimetypesFileTypeMap; /** * Content?. */ private Cache contentInfoCache; @Override public void init(ServletConfig config) throws ServletException { super.init(config); ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(getServletContext()); String cacheManager = config.getInitParameter("CacheManager"); CacheManager ehcacheManager = (CacheManager) context.getBean(cacheManager); String cacheKey = config.getInitParameter("cacheKey"); contentInfoCache = ehcacheManager.getCache(cacheKey); //?mimeTypes, css,. mimetypesFileTypeMap = new MimetypesFileTypeMap(); mimetypesFileTypeMap.addMimeTypes("text/css css"); } /** * ??. */ @Override public void init() throws ServletException { } @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //??. String contentPath = request.getParameter("contentPath"); ContentInfo contentInfo = getContentInfoFromCache(contentPath); //?EtagModifiedSince Header?, ??304,. if (!WebUtils.checkIfModifiedSince(request, response, contentInfo.lastModified) || !WebUtils.checkIfNoneMatchEtag(request, response, contentInfo.etag)) { return; } //Etag/ WebUtils.setExpiresHeader(response, WebUtils.ONE_YEAR_SECONDS); WebUtils.setLastModifiedHeader(response, contentInfo.lastModified); WebUtils.setEtag(response, contentInfo.etag); //MIME response.setContentType(contentInfo.mimeType); //,Header if (request.getParameter("download") != null) { WebUtils.setDownloadableHeader(response, contentInfo.fileName); } //OutputStream OutputStream output; if (WebUtils.checkAccetptGzip(request) && contentInfo.needGzip) { //outputstream, http1.1 trunked??content-length. output = WebUtils.buildGzipOutputStream(response); } else { //outputstream, content-length. response.setContentLength(contentInfo.length); output = response.getOutputStream(); } //?. FileInputStream input = new FileInputStream(contentInfo.file); try { //byte?OutputStream, ?4k. IOUtils.copy(input, output); output.flush(); } finally { //??Input/Output Stream. IOUtils.closeQuietly(input); IOUtils.closeQuietly(output); } } /** * ?Content?, ?. */ private ContentInfo getContentInfoFromCache(String path) { Element element = contentInfoCache.get(path); if (element == null) { ContentInfo content = createContentInfo(path); element = new Element(content.contentPath, content); contentInfoCache.put(element); } return (ContentInfo) element.getObjectValue(); } /** * Content?. */ private ContentInfo createContentInfo(String contentPath) { ContentInfo contentInfo = new ContentInfo(); String realFilePath = getServletContext().getRealPath(contentPath); File file = new File(realFilePath); contentInfo.contentPath = contentPath; contentInfo.file = file; contentInfo.fileName = file.getName(); contentInfo.length = (int) file.length(); contentInfo.lastModified = file.lastModified(); contentInfo.etag = "W/\"" + contentInfo.lastModified + "\""; String mimeType = getServletContext().getMimeType(realFilePath); if (mimeType == null) { mimeType = "application/octet-stream"; } contentInfo.mimeType = mimeType; if (contentInfo.length >= GZIP_MINI_LENGTH && ArrayUtils.contains(GZIP_MIME_TYPES, contentInfo.mimeType)) { contentInfo.needGzip = true; } else { contentInfo.needGzip = false; } return contentInfo; } /** * Content?. */ static class ContentInfo { protected String contentPath; protected File file; protected String fileName; protected int length; protected String mimeType; protected long lastModified; protected String etag; protected boolean needGzip; } }