我应该手动返回304响应缓存请求(ETag)在Restlet



我在我的应用程序中添加了一个自定义缓存行为,类似于Thierry在本文中提出的。对于我的静态内容中的每个CSS, JS和HTML文件服务器,我添加了以下两个头:

// Added by me
ETag: "0c635aa7113262fac7606da2432e00f5" // md5(last_mod_date_of_file)
Cache-Control: max-age=31536000 // one year
// Automatically added by Restlet (probably Directory class?)
Date: Wed, 09 Nov 2016 11:50:53 GMT
Expires: Wed, 09 Nov 2016 12:00:53 GMT
Last-Modified: Wed, 09 Nov 2016 17:30:56 GMT

这工作得很好,但是我注意到,在测试服务器上部署代码并在Chrome中点击F5后,我再次获取整个响应体(返回HTTP 200)。

我注意到这些请求也使用正确的头:

Cache-Control:max-age=0
If-Modified-Since: Wed, 09 Nov 2016 17:30:56 GMT
If-None-Match: "0c635aa7113262fac7606da2432e00f5"

我的问题是,我应该在我的服务器过滤器中对If-None-Match头进行任何手动验证并返回304响应然后吗?还是由Restlet处理?

注意:在这个问题中有点奇怪的是,它似乎在我的本地开发环境中正常工作。我也有点困惑,为什么Expires是由Restlet设置为日期 Last-Modified之前。我将尝试调试,如果这是邪恶的根源,但它并没有使我的问题无效关于手动设置304状态和检查服务器上的ETags。

好的,所以我已经能够解决这个问题,我在下面发布答案。

我应该在我的服务器过滤器中对If-None-Match头进行任何手动验证并返回304响应吗?

不,你不需要自己手动做。这是由Restlet自动处理的(DirectoryServerResource负责)。

问题是什么?

问题确实是与Last-Modified头被设置为未来的日期。这是因为我的生产服务器在UTC-8时区,而我在UTC+1开发。

我如何修复它?

这需要熟悉Restlet API,但当时的解决方案微不足道。我确保当我的应用程序启动时,它从操作系统读取我的应用程序目录的File Last Modified属性,因为这是我想在Last-Modified头中使用的值。现在,您不能仅仅在Filterresponse上设置这个头,因为在前面提到的DirectoryServerResource类中,HTTP缓存头的自动处理发生在此之前。所以解决方案如下:

创建一个扩展DSR的类(为您免费提供所有自动缓存处理)并修改其handle()方法,以便在此逻辑开始之前设置Last-Modified头:

 public class WebAssetsResource extends DirectoryServerResource {
    @Override
    public Representation handle() {
        Date desiredDate = ...; // I read this from File System
        getInfo().setModificationDate(desiredDate);
        return super.handle(); // Automatic logic will use desired date
    }
 }

现在,确保您新创建的资源被自定义Directory类使用。

public class CachedWebAssetsDirectory extends Directory {
    public CachedWebAssetsDirectory(Context context, Reference rootLocalReference) {
        super(context, rootLocalReference);
        setTargetClass(WebAssetsResource.class); // Needed so that Restlet will use our implementation of a ServerResource to serve static files
    }
}

之后,您可以随意使用CachedWebAssetsDirectory,在其上构建任何自定义过滤器。

最新更新