在S3存储桶中没有密钥时收到消息。我检索该存储桶中的所有对象,并将这些键与给定的搜索关键字匹配。如果可用,则返回URL-String,否则返回消息'指定的密钥不存在'。
是否可以通过其他方式在访问密钥时提高性能,这在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时。如果
答案 0 :(得分:3)
在给定密钥的情况下,使用getObjectMetadata
快速确定对象是否存在。如果成功,则该对象存在。如果没有,请检查错误以确认它不是需要重试的瞬态错误。如果没有,就没有这样的钥匙。
通过对象进行迭代不仅不会扩展,而且实际上也更加昂贵,因为列表请求每个请求的价格高于获取对象或获取其元数据,这应该非常快。此操作向S3发送HTTP HEAD
请求,仅当对象存在时才返回200 OK
。
但是,从设计的角度来看,我认为这项服务不应该真正关心对象是否存在。为什么你会收到不存在的对象的请求?谁在要求这个?这应该是调用者的问题 - 如果您为不存在的对象生成签名URL,则当调用者尝试使用URL时,请求将失败并显示错误...但是为一个生成签名的URL不存在的对象是一个完全有效的操作。在实际上传对象之前,可以对进行签名,并且,只要URL未过期,一旦创建了对象,它将仍然有效,如果它是稍后创建的。
答案 1 :(得分:0)
Amazon S3:检查密钥存在并生成PresignedUrl
使用 getObjectMetadata():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,objectName); - [aws-java- SDK-68年1月10日]
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.";
}
必需的Jars [aws-java {sdk,sdk-core,sdk-s3}, fasterxml。jackson {databind,core,annotations}, joda - 时间,http {clent,core}]