从Amazon S3提供资源的惯用Wicket方式

时间:2016-09-14 05:44:41

标签: wicket

从AWS S3提供用户上传资产的Wicket方式是什么?

要求:

  • 浏览器没有直接向S3发出请求;所有流量都通过我们的服务器代理;
  • 允许浏览器使用缓存清除缓存资源(通过校验和或数据库中的version字段);
  • 资产仅供授权用户使用。

我可以想到以下解决方案:

  1. 用于解析URL并流式传输资产的所有资源的单个SharedResource:

    // resource definition:
    mountResources("/assets/${path}", new ResourceReference("assets") {
        public IResource getResource() {
            return new AbstractResource() {
                public ResourceResponse newResourceResponse(RequestAttribute attributes) {
                    String path = attributes.getParameters().get("path").toString()
                    // request S3 and stream the content
                    // handle caching / busting by hand
                } 
            }
        }
    })
    
    // Usage:
    page.add(new Image("image", new SharedResourceReference("assets"), new PageParameters().add("path", "image.jpg"))
    
  2. 为每个资产创建一个新的ResourceReference,并将其直接传递给图像。通过让Resource实现IStaticCacheableResource:

    来插入Wicket的缓存
    class S3ResourceReference extends ResourceReference {
        private String path;
        public S3ResourceReference(String path) { ... }
        public IResource getResource() {
            return new S3Resource(path);
        }
    }
    class S3Resource extends AbstractResource implements IStaticCacheableResource {
        public S3ResourceStream getResourceStream() {
            S3Object object = getObject(path);
            return new S3ResourceStream(object);
        }
        public ResourceResponse newResourceResponse(Attributes attributes) {
            S3ResourceStream stream = getResourceStream();
            // populate response
        }
    }
    
    class S3ResourceStream extends AbstractResourceStream {
        S3ResourceStream(S3Object object) {
            // ...
        }
    
        public InputStream getInputStream() { return object.objectContent }
        // override metadata methods
    }
    
    // Usage:
    page.add(new Image("image"), new S3ResourceReference("image.jpg"));
    
  3. 这些方法中哪一种更具惯用性?

    在第二个片段中使用IStaticCacheableResource是否有任何陷阱?

1 个答案:

答案 0 :(得分:1)

Here are the differences in those two approaches:

Page instance locking

  • In 1) the requests for the resources are made to an application scoped resource
  • In 2) the request is to a page scoped resource

In the second case Wicket will lock the access to the page instance during the serving of the resource. For that reason I prefer using the application scoped resource.

IStaticCacheableResource

If the resource implements this interface then Wicket will mangle the produced url to the resource and will add something like -123456789 in its file name. This hash is the resource modification time in DEVELOPMENT mode and its MD5 checksum in PRODUCTION mode. This helps for caching.

I hope you realize that you can use a mix of 1) and 2) - an application scoped resource reference + IStaticCacheableResource.

One more thing: I usually use new MyResourceReference() instead of new SharedResourceReference("the-name").