從 Amazon S3 查詢及下載

工程 | Ben Hale | 2007 年 4 月 30 日 | ...

先前的文章中,我描述了我們如何使用自定義 ANT 任務,從 Spring 作品組合中基於 ANT 的專案上傳夜間快照。 在這篇文章中,我將描述我們如何使用 Amazon S3 來為每個專案的快照產生頁面,並允許使用者下載快照。

正如我在前一篇文章中提到的,S3 主要用作 REST-ful 服務。 這表示雖然我使用 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

snapshot-download.png

從服務傳回的大部分內容對此工作沒有用處,因此 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 服務的探索。 我現在可以根據經驗說,如果您有大量數據和大量的頻寬需求,那麼沒有多少地方能提供更好的費率。 並且透過 REST-ful 介面,它足夠靈活,可以與您最喜歡的語言一起使用。 感謝您的邀請,我現在可以回答任何問題。 :)

取得 Spring 電子報

透過 Spring 電子報保持聯繫

訂閱

取得領先

VMware 提供培訓和認證,以加速您的進度。

了解更多

取得支援

Tanzu Spring 在一個簡單的訂閱中提供 OpenJDK™、Spring 和 Apache Tomcat® 的支援和二進制檔案。

了解更多

即將舉辦的活動

查看 Spring 社群中所有即將舉辦的活動。

查看全部