领先一步
VMware 提供培训和认证,以加速您的进步。
了解更多在之前的文章中,我描述了我们如何使用自定义 ANT 任务来上传 Spring 产品组合中基于 ANT 的项目的夜间快照。在这篇文章中,我将描述我们如何使用 Amazon S3 为每个项目的快照生成页面并允许用户下载快照。
正如我在上一篇文章中提到的,S3 主要用作 RESTful 服务。这意味着虽然我使用 Java 来进行上传部分,但我可以自由地使用其他语言来进行下载部分。在这种情况下,我选择使用 PHP,因为它已经安装在我的工作服务器上,并且是最简单的方案。
这项工作分为两个部分。首先,我需要查询 Amazon S3 服务以获取给定 Spring 项目的快照列表。为此,您可以创建一个带有前缀参数的 REST 查询。
http://s3.amazonaws.com/static.springframework.org/?prefix=$prefix
既然您已经了解了查询的基本方法,我想回到之前的示例,并指出上传定义中的一些重要部分。
<aws:s3 accessKey="${s3.accessKey}" secretKey="${s3.secretKey}">
<upload bucketName="static.springframework.org"
file="${target.release.dir}/${release-with-dependencies.zip}"
toFile="SPR/spring-framework-${spring-version}-with-dependencies-${tstamp}-${build.number}.zip"
publicRead="true"/>
<upload bucketName="static.springframework.org"
file="${target.release.dir}/${release.zip}"
toFile="SPR/spring-framework-${spring-version}-${tstamp}-${build.number}.zip"
publicRead="true"/>
</aws:s3>
首先你会注意到,对于 Spring 工件,我选择以SPR作为前缀。文件名基本上是自由格式的,因此您可以使用斜杠创建虚拟目录结构来进行查询。如果您查看 Spring Web Flow 的构建,您会看到其工件以SWF作为前缀,Spring LDAP 的工件以LDAP作为前缀,Spring Modules 的工件以MOD作为前缀。因此,现在通过自定义我们的查询参数,我们可以专门选择一个项目。
http://s3.amazonaws.com/static.springframework.org/?prefix=SPR
http://s3.amazonaws.com/static.springframework.org/?prefix=SWF
http://s3.amazonaws.com/static.springframework.org/?prefix=LDAP
http://s3.amazonaws.com/static.springframework.org/?prefix=MOD
第二点需要注意的是publicRead=true声明。默认情况下,S3 不允许任何人查看或下载您的存储桶中的内容。您可以使用您的密钥和访问密钥创建令牌来授予他们权限,从而允许下载。但是,对于这项工作,我认为没有必要。快照是公开可访问的,所以我放松了安全性,允许它们无需令牌即可下载。
现在您可以调用 S3 REST 服务并获取存储桶中项目的已正确过滤的列表,但是响应是原始 XML。即使我是 Spring 开发人员,在 Web 浏览器中查看原始 XML 也并不会让我兴奋。;) 所以下一步是将 XML 转换为有用的 HTML 页面。此时我有两种选择。我可以执行服务器上的转换以生成 HTML,然后将其返回给用户,或者我可以将 XML 与 XSLT 文件一起返回给用户,并让用户的浏览器为我执行转换。老实说,后者减轻了服务器的负载,实际上允许用户的浏览器缓存转换以提高性能。但现实情况是,我没有访问 XSLT PHP 库,所以如果我想的话,我无法进行服务器端转换。我意识到一些旧的浏览器在这个设置下会有问题,但是我们会到时候再解决这个问题。
所以我需要获取返回的 XML
<ListBucketResult xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<Name>static.springframework.org</Name>
<Prefix>SPR</Prefix>
<Marker/>
<MaxKeys>1000</MaxKeys>
<IsTruncated>false</IsTruncated>
<Contents>
<Key>SPR/spring-framework-2.0.5-20070411-50.zip</Key>
<LastModified>2007-04-11T13:27:34.000Z</LastModified>
<ETag>"1ab20ad18ca0edb4a360279f27409d54"</ETag>
<Size>10725241</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
<Contents>
<Key>SPR/spring-framework-2.0.5-20070411-51.zip</Key>
<LastModified>2007-04-12T01:25:58.000Z</LastModified>
<ETag>"de2e5833ae8fe4cc06987935bea06e57"</ETag>
<Size>10727049</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
<Contents>
<Key>SPR/spring-framework-2.0.5-20070412-52.zip</Key>
<LastModified>2007-04-13T01:22:23.000Z</LastModified>
<ETag>"414b947226fc4e08bd118e0f16a6be67"</ETag>
<Size>10736732</Size>
<StorageClass>STANDARD</StorageClass>
</Contents>
...
并将其转换为 HTML
从服务返回的大部分内容对这项工作没有用,因此 XSLT 变得非常简单。
<xsl:template match="/">
<head>
<style type="text/css" media="all">@import "./snapshot-download.css";</style>
</head>
<body>
<xsl:apply-templates select="s3:ListBucketResult"/>
</body>
</xsl:template>
<xsl:template match="s3:ListBucketResult">
<xsl:variable name="bucket-name" select="s3:Name"/>
<table>
<tr>
<th class="name"><xsl:value-of select="s3:Prefix"/> Project Snapshots</th>
<th class="size">Size</th>
</tr>
<xsl:for-each select="s3:Contents">
<tr>
<td class="name">
<a class="name" href="http://s3.amazonaws.com/{$bucket-name}/{s3:Key}">
<xsl:value-of select="substring-after(s3:Key, '/')"/>
</a>
</td>
<td class="size"><xsl:value-of select="format-number(s3:Size div 1048576, '###,###.0')"/> MB</td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
转换以一些 HTML 声明开头,然后迭代存储桶的每个项目。然后它使用对象标识符来创建指向 S3 服务器上文件的链接。就是这样。PHP 页面调用 S3 获取 XML,然后将其与 XSLT 声明一起传递给用户的浏览器。
<?php
$prefix = $HTTP_GET_VARS["project"];
$url = "http://s3.amazonaws.com/static.springframework.org/?prefix=$prefix";
$xml = file_get_contents($url);
header('Content-Type: text/xml; charset=UTF-8');
echo '<?xml version="1.0" encoding="UTF-8"?>';
echo '<?xml-stylesheet type="text/xsl" href="./snapshot-download.xsl"?>';
echo substr($xml, 39);
?>
使用请求参数为每个项目添加一些自定义内容,您将获得每个项目的单独下载页面。
这就完成了我对 Amazon S3 服务的探索。我现在可以根据经验说,如果您有大量数据和大量的带宽需求,没有多少地方能给您提供更好的价格。并且使用 RESTful 接口,它足够灵活,可以与您最喜欢的语言一起使用。感谢您的参与,我现在接受任何问题。:)