从AmazonS3服务资源的惯用Wicket方式

从AmazonS3服务资源的惯用Wicket方式,wicket,Wicket,从AWS S3为用户上传的资产提供服务的Wicket方式是什么 要求: 没有从浏览器到S3的直接请求;所有流量都通过我们的服务器代理 允许浏览器通过缓存破坏功能缓存资产(通过校验和或数据库中的version字段) 资产仅提供给授权用户 我可以想出以下解决办法: 用于解析URL和流式传输资产的所有资源的单个SharedResource: // resource definition: mountResources("/assets/${path}", new ResourceReference

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

要求:

  • 没有从浏览器到S3的直接请求;所有流量都通过我们的服务器代理
  • 允许浏览器通过缓存破坏功能缓存资产(通过校验和或数据库中的
    version
    字段)
  • 资产仅提供给授权用户
我可以想出以下解决办法:

  • 用于解析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"))
    
  • 为每个资产创建一个新的ResourceReference,并将其直接传递给映像。通过让资源实现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"));
    
  • 以下哪种方法看起来更地道


    在第二个代码段中使用IStaticCacheableResource是否存在任何缺陷?

    以下是这两种方法的区别:

    页面实例锁定

    • 在1)中,对资源的请求是向应用程序范围的资源发出的
    • 在2)中,请求是指向页面范围的资源
    在第二种情况下,Wicket将在服务资源期间锁定对页面实例的访问。因此,我更喜欢使用应用程序范围的资源

    IStaticCacheableResource

    如果资源实现了这个接口,那么Wicket将破坏生成的资源url,并在其文件名中添加类似于
    -123456789
    的内容。此哈希是开发模式下的资源修改时间和生产模式下的MD5校验和。这有助于缓存

    我希望您认识到,您可以混合使用1)和2)-应用程序范围的资源引用+IStaticCacheableResource


    还有一件事:我通常使用
    new MyResourceReference()
    而不是
    new SharedResourceReference(“名称”)

    “在2)请求是对页面范围的资源”--这是否与ResourceReference的构造函数参数中指定的范围相同?否。我的意思是Wicket需要锁定对页面实例的访问,然后在组件树中查找映像,然后通过此映像查找资源引用。在该请求期间,您将无法使用页面中的任何(Ajax)链接。在1)请求是一个共享资源,没有任何锁定。谢谢,这澄清了一些事情!因此,使用IStaticCacheableResource进行用户上传(如头像等)并不是一件容易的事。正如我前面所说:您可以将应用程序范围内的资源与IStaticCacheableResource混合使用。