如果对静态资源指定浏览器缓存的有效期啊?

独孤小败 发布于 2013/01/26 13:10
阅读 1K+
收藏 2
静态资源如.css .jpg .js 之类的

以下是问题补充:

@独孤小败:我找到别的人解决方案了,但是他说的那个类没看到 http://bbs.chinaunix.net/forum.php?mod=viewthread&tid=3589321 (2013/01/26 13:29)
@独孤小败:我在查看资料的过程中,发现有好多人提起 .htaccess 文件, Tomcat也可以通过 .htaccess 配置吗? (2013/01/26 13:54)
加载中
0
删除
删除

那个类的代码

package com.test.web.filter;

import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.LinkedHashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Set the "expires" header on pages which are configured in expires.properties
 * 
 * 1) Create a file "expires.properties" in your src/main/resources. It should
 * be accessible via the classpath '/expires.properties'.
 * 
 * 2) Each line in the properties file is a resource path regex mapped to the
 * age of the page. Examples:
 * 
 * ^/images/.*$ = 2M # 2 month expiry for all resources in images directory
 * ^.*\\.css$ = 1M # 1 month expiry for all pages which have .css extension ^/$
 * = 1h # 1 hr expiry for home page .* = 1m # 1 min expiry for all other pages
 * 
 * Left hand side is full regex. Right hand side is the age. The supported units
 * are:
 * 
 * m - minutes h - hours d - days w - weeks M - months
 * 
 * 3) Order is important. The first matching regular expression will be used.
 * 
 * @author Vineet Manohar http://www.vineetmanohar.com
 * 
 *         Etag: W/"14961-1287895605000"
 * 
 *         Expires: Wed, 24 Nov 2010 08:48:33 EST
 */
public class PageExpiryFilter implements javax.servlet.Filter {
  private static final org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory
      .getLog(PageExpiryFilter.class);

  private Map<String, Integer> pathRegex;

  public void destroy() {
    // no resources to be released
  }

  /**
   * The doFilter method of the Filter is called by the container each time a
   * request/response pair is passed through the chain due to a client request
   * for a resource at the end of the chain.
   */
  public void doFilter(ServletRequest request, ServletResponse response,
      FilterChain chain) throws IOException, ServletException {
    if (response instanceof HttpServletResponse) {
      if (request instanceof HttpServletRequest) {
        HttpServletRequest httpServletRequest = (HttpServletRequest) request;
        String path = httpServletRequest.getServletPath();
        HttpServletResponse httpServletResponse = (HttpServletResponse) response;

        String expiryDate = null;
        String lastModified = null;

        for (String regex : pathRegex.keySet()) {
          if (path.matches(regex)) {
            Integer age = pathRegex.get(regex);
            // expiry date
            {
              Calendar calendar = Calendar.getInstance();
              calendar.add(Calendar.MINUTE, age);

              expiryDate = new SimpleDateFormat(
                  "EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH)
                  .format(calendar.getTime());
              httpServletResponse
                  .setHeader("Expires", expiryDate);
              log.debug("expiration date set for path: " + path
                  + " = " + expiryDate);
            }
            // last modified
            /*
             * { Calendar calendar = Calendar.getInstance();
             * calendar.add(Calendar.MINUTE, -age);
             * 
             * lastModified = new SimpleDateFormat(
             * "EEE, dd MMM yyyy HH:mm:ss z")
             * .format(calendar.getTime());
             * 
             * httpServletResponse.setHeader("Last-Modified",
             * lastModified);
             * log.debug("last modified date set for path: " + path
             * + " = " + lastModified); }
             */

            break;
          }
        }

        if (expiryDate == null) {
          log.warn("No expiration date set for path: " + path);
        }
      }
    }

    // chain.doFilter() should be called after writing the header. If it is
    // called _before_ writing the header
    chain.doFilter(request, response);
  }

  /**
   * Get the expiry header to set for the given path
   * 
   * @param path
   *            the relative path of the resource within the application. e.g.
   *            /images/logo.png
   * 
   * @return the expiry header formatted as "EEE, dd MMM yyyy HH:mm:ss z", or
   *         null if no expiry date has been specified
   */
  private String getExpiryHeaderFor(String path) {
    for (String regex : pathRegex.keySet()) {
      if (path.matches(regex)) {
        Integer age = pathRegex.get(regex);
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.MINUTE, age);

        return new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.ENGLISH)
            .format(calendar.getTime());
      }
    }

    return null;
  }

  /**
   * Called by the web container to indicate to a filter that it is being
   * placed into service.
   */
  public void init(FilterConfig filterConfig) throws ServletException {
    pathRegex = new LinkedHashMap<String, Integer>();

    Properties properties = new Properties();

    String resourceName = "/expires.properties";

    InputStream inputStream = getClass().getResourceAsStream(resourceName);

    if (inputStream != null) {
      try {
        properties.load(inputStream);
      } catch (IOException e) {
        throw new ServletException(
            "Error while opening classpath resource '"
                + resourceName
                + "'. Make sure that it is a valid properties",
            e);
      }
    }

    for (Object key : properties.keySet()) {
      String regex = (String) key;
      String value = properties.getProperty(regex);

      if (value != null && value.length() == 0) {
        value = null;
      }

      Integer expInMinutes = getExpirationInMinutes(value);

      pathRegex.put(String.valueOf(key), expInMinutes);
    }
  }

  static Integer getExpirationInMinutes(String value) {
    if (value == null) {
      return null;
    }
    value = value.trim();
    if (value.length() == 0) {
      return null;
    }
    Pattern pattern = Pattern.compile("^(\\d+)(m|M|h|d|w)$");
    Matcher m = pattern.matcher(value);
    if (m.matches()) {
      int val = Integer.parseInt(m.group(1));
      String denomination = m.group(2);
      int factor;
      if (denomination.equals("m")) {
        factor = 1;
      } else if (denomination.equals("h")) {
        factor = 60;
      } else if (denomination.equals("d")) {
        factor = 60 * 24;
      } else if (denomination.equals("M")) {
        factor = 60 * 24 * 30;
      } else if (denomination.equals("w")) {
        factor = 60 * 24 * 7;
      } else {
        throw new RuntimeException(
            "Developer error. Unhandled pattern '" + value + "'"
                + " for '" + value
                + "'. Valid patterns are 2m, 10h, 1d, 1w, 1M");
      }

      return val * factor;
    } else {
      throw new RuntimeException(
          "Invalid pattern '"
              + value
              + "'"
              + " for '"
              + value
              + "'. Valid patterns are '2m' for 2 minutes, '10h' for 10 hours, '1d' for 1 day, '1w' for 1 week, '1M' for 1 month");
    }
  }
}


独孤小败
独孤小败
我也找到了
0
龙上
龙上

,浏览器默认永久保存的. url.jpg?v=2012000 后面加个时间参数不同浏览器就会刷新的

独孤小败
独孤小败
你可以看一下我发的那个链接,或许你就明白了
0
大大
大大
看 apache mod_expire 手册
0
0x0001
0x0001
用代码设置这个头( Expires) 就可以了,对java来说可以使用过滤器 参考 http://baike.baidu.com/view/5064905.htm
返回顶部
顶部