2016-04-15 43 views
0

要在S3存儲區中不存在密鑰時收到消息。 iam檢索該桶中的所有對象,並將這些鍵與給定的搜索鍵進行匹配。如果可用,則返回URL字符串,否則返回消息'指定的鍵不存在'。S3:爲給定密鑰生成預先簽名的URL。 [密鑰可能/不存在]

是他們在訪問密鑰時提高性能的任何其他方式,這在S3存儲桶中不可用。

這裏是我的代碼:

public class S3Objects { 
    static Properties props = new Properties(); 
    static InputStream resourceAsStream; 
    static { 
     ClassLoader classLoader = new S3Objects().getClass().getClassLoader(); 
     resourceAsStream = classLoader.getResourceAsStream("aws.properties"); 
     try { 
      props.load(resourceAsStream); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    public static void main(String[] args) throws IOException, AmazonServiceException, AmazonClientException, InterruptedException { 
     AWSCredentials awsCreds = new 
         BasicAWSCredentials(props.getProperty("accessKey"), props.getProperty("secretKey")); 
         // PropertiesCredentials(resourceAsStream); 
     AmazonS3 s3Client = new AmazonS3Client(awsCreds); 

     String s3_BucketName = props.getProperty("bucketname"); 
     String folderPath_fileName = props.getProperty("path"); 

     //uploadObject(s3Client, s3_BucketName, folderPath_fileName); 
     //downloadObject(s3Client, s3_BucketName, folderPath_fileName); 
     //getSignedURLforS3File(s3Client, s3_BucketName, folderPath_fileName); 
     String url = getSingnedURLKey(s3Client, s3_BucketName, folderPath_fileName); 
     System.out.println("Received response:"+url); 
    } 
    // <MaxKeys>1000</MaxKeys> 
    private static String getSingnedURLKey(AmazonS3 s3Client, String s3_BucketName, String folderPath_fileName) { 
     String folderPath = folderPath_fileName.substring(0,folderPath_fileName.lastIndexOf("/"));  
     ObjectListing folderPath_Objects = s3Client.listObjects(s3_BucketName, folderPath); 

     List<S3ObjectSummary> listObjects = folderPath_Objects.getObjectSummaries(); 
     for(S3ObjectSummary object : listObjects){ 
      if(object.getKey().equalsIgnoreCase(folderPath_fileName)){ 
       return getSignedURLforS3File(s3Client, s3_BucketName, folderPath_fileName); 
      } 
     } 
     return "The specified key does not exist."; 
    } 

    // providing pre-signed URL to access an object w/o any AWS security credentials. 
    // Pre-Signed URL = s3_BucketName.s3.amazonaws.com/folderPath_fileName?AWSAccessKeyId=XX&Expires=XX&Signature=XX 
    public static String getSignedURLforS3File(AmazonS3 s3Client, String s3_BucketName, String folderPath_fileName){ 
     GeneratePresignedUrlRequest request = new GeneratePresignedUrlRequest(s3_BucketName, folderPath_fileName, HttpMethod.GET); 
     request.setExpiration(new Date(System.currentTimeMillis() + 1000 * 60 * 15)); // Default 15 min 

     String url = s3Client.generatePresignedUrl(request).toString(); 
     System.out.println("Pre-Signed URL = " + url); 
     return url; 
    } 

    public static void uploadObject(AmazonS3 s3Client, String s3_BucketName, String folderPath_fileName) 
      throws AmazonServiceException, AmazonClientException, InterruptedException{ 
     TransferManager tm = new TransferManager(s3Client); 

     PutObjectRequest putObjectRequest = 
       new PutObjectRequest(s3_BucketName, folderPath_fileName, new File("newImg.jpg")); 
     Upload myUpload = tm.upload(putObjectRequest); 
     myUpload.waitForCompletion();//block the current thread and wait for your transfer to complete. 
     tm.shutdownNow();   //to release the resources once the transfer is complete. 
    } 
    // When accessing a key which is not available in S3, it throws an exception The specified key does not exist. 
    public static void downloadObject(AmazonS3 s3Client, String s3_BucketName, String folderPath_fileName) throws IOException{ 
     GetObjectRequest request = new GetObjectRequest(s3_BucketName,folderPath_fileName); 
     try{ 
      S3Object s3object = s3Client.getObject(request); 
      System.out.println("Content-Type: " + s3object.getObjectMetadata().getContentType()); 
      S3ObjectInputStream objectContent = s3object.getObjectContent(); 

      FileUtils.copyInputStreamToFile(objectContent, new File("targetFile.jpg")); 
     }catch(AmazonS3Exception s3){ 
      System.out.println("Received error response:"+s3.getMessage()); 
     } 
    } 

} 

aws.properties

accessKey =XXXXXXXXX 
secretKey =XXXXXXXXX 

bucketname =examplebucket 
path  =/photos/2006/February/sample.jpg 

請讓我知道他們的天氣是任何其他方式來減少節數迭代在所有的鑰匙並得到一些消息'鑰匙不存在'。

當請求密鑰來生成預先簽名的URL。如果

  • 密鑰存在«返回簽名的URL。
  • 密鑰不存在«消息作爲密鑰不可用。
+0

爲什麼你需要知道密鑰是否存在?對於在生成簽名URL時不存在的密鑰創建簽名URL沒有限制。當使用URL時,如果此時對象不存在,則S3會向客戶端返回錯誤,但是如果在創建簽名URL的時間與使用簽名URL的時間之間創建對象,則簽名的URL仍然有效且可用。 –

+0

當用戶通過提供S3對象名稱向REST服務發送請求時。 如果該對象存在,那麼只有REST服務必須返回** [**簽名URL](http://docs.aws.amazon.com/AmazonS3/latest/dev/ShareObjectPreSignedURLJavaSDK.html)**作爲字符串* *,否則它必須返回** null **。因此,爲了檢查S3 iam中存在的對象是否獲取了文件夾路徑中所有對象的列表並使用給定的鍵檢查了這些鍵。但問題是需要更多時間,如果文件夾路徑有更多的鍵。 – Yash

回答

0

使用getObjectMetadata快速確定一個對象是否存在,給定的關鍵。如果成功,則存在該對象。如果沒有,檢查錯誤以確認它不是一個需要重試的瞬態錯誤。如果沒有,就沒有這樣的鑰匙。

當你正在做的事情中迭代對象不僅不會縮放,而且還會大大增加成本,因爲列表請求的每個請求的價格高於獲取對象或獲取其元數據的價格,這應該是非常高的快速。該操作向S3發送HTTP HEAD請求,僅當該對象在那裏時才返回200 OK

但是,從設計的角度來看,我認爲這個服務不應該真的關心對象是否存在。爲什麼你會收到不存在的對象請求?誰在問這個?這應該是調用者的問題 - 並且如果爲不存在的對象生成簽名URL,則當調用者嘗試使用URL時,請求將失敗並顯示錯誤...但是爲不存在的對象是完全有效的操作。在之前,該對象實際上傳之前可以對該URL進行簽名,並且只要該URL尚未過期,一旦對象被創建(如果稍後創建),它仍然可以工作。

+0

對於任何熟悉S3 API的人來說,看起來像是一個明顯正確的答案都有一個匿名downvote,我真的不知道該怎麼想。 –

0

亞馬遜S3:檢查鍵存在和使用getObjectMetadata()生成PresignedUrl

:AmazonS3Client這是僅獲得該對象的元數據是有用的,並且避免了上提取所述對象數據浪費帶寬。

private static String getPreSignedURLAsString_GetMetaData(AmazonS3 s3Client, String s3_BucketName, String folderPath_fileName) { 
    GetObjectMetadataRequest request = new GetObjectMetadataRequest(s3_BucketName,folderPath_fileName); 
    try{ 
     ObjectMetadata objectMetadata = s3Client.getObjectMetadata(request); 
     System.out.println("Key Exists in S3"); 
     return getSignedURLforS3File(s3Client, s3_BucketName, folderPath_fileName); 
    }catch(AmazonS3Exception s3){ 
     System.out.println("Received error response:"+s3.getMessage()); 
    } 
    return "Key Not Found."; 
} 

使用doesObjectExist():AmazonS3Client內部,它正在爲getObjectMetadata(bucketName,對象名)的呼叫; - [AWS-java的SDK-68年10月1日]

private static String getPreSignedURLAsString_DoesKeyExists(AmazonS3 s3Client, String s3_BucketName, String folderPath_fileName) { 
    try{ 
     boolean doesObjectExist = s3Client.doesObjectExist(s3_BucketName, folderPath_fileName); 
     if (doesObjectExist) { 
      System.out.println("Key Exists in S3"); 
      return getSignedURLforS3File(s3Client, s3_BucketName, folderPath_fileName); 
     } 
    }catch(AmazonS3Exception s3){ 
     System.out.println("Received error response:"+s3.getMessage()); 
    } 
    return "Key Not Found."; 
} 

需要的jar [aws-java {SDK,SDK核,SDK-S3}, fasterxml。 jackson {數據綁定,核心,註釋}, joda - 時間,http {克倫特,核心}]