取得领先
VMware 提供培训和认证,以加速您的进步。
了解更多在之前的文章中,我介绍了如何使用自定义 ANT 任务从 Spring 产品组合中基于 ANT 的项目上传每日快照。 在这篇文章中,我将介绍如何使用 Amazon S3 为每个项目的快照生成页面,并允许用户下载快照。
正如我在上一篇文章中提到的,S3 主要用作 RESTful 服务。 这意味着虽然我使用 Java 进行上传部分,但我可以自由使用其他语言进行下载部分。 在这种情况下,我选择使用 PHP,因为它已经在我正在使用的服务器上可用,并且阻力最小。
这项工作分为两个部分。 首先,我需要查询 Amazon S3 服务以获取给定 Spring 项目的快照列表。 为此,您需要创建一个带有 prefix 参数的 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 界面,它足够灵活,可以与您喜欢的语言一起使用。 谢谢你邀请我,我现在可以回答任何问题。 :)