S3:为给定密钥生成预签名URL. [密钥可能存在/不存在] [英] S3: Generating Pre-Signed URL for a given Key. [Key may/not present]

查看:156
本文介绍了S3:为给定密钥生成预签名URL. [密钥可能存在/不存在]的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当S3存储桶中不存在该密钥时获取消息. iam检索该存储桶中的所有对象,并将这些键与给定的Search-key相匹配.如果可用,则返回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.
  • 密钥不存在«密钥消息不可用.

推荐答案

在给定键的情况下,使用getObjectMetadata快速确定对象是否存在.如果成功,则该对象存在.如果不是,请检查错误以确认它不是需要重试的暂时性错误.如果没有,则没有这样的密钥.

Use getObjectMetadata to quickly determine whether an object exists, given the key. If it succeeds, the object exists. If it doesn't, inspect the error to confirm it wasn't a transient error that needs to be retried. If not, there's no such key.

在执行操作时遍历对象不仅无法扩展,而且成本也高得多,因为列表请求的每个请求的价格比获取对象或获取其元数据的价格要高,后者应该非常快.此操作向S3发送HTTP HEAD请求,仅当对象存在时,该请求才返回200 OK.

Iterating through the objects as you are doing not only doesn't scale, it'a also substantially more expensive, since the list requests carry a higher price per request than getting an object or getting its metadata, which should be very fast. This operation sends S3 an HTTP HEAD request, which returns 200 OK only if the object is there.

但是,从设计的角度来看,我认为该服务不应该真正在乎对象是否存在.为什么会收到对不存在的对象的请求?谁要的?那应该是调用者的问题-如果您为不存在的对象生成一个签名URL,则当调用者尝试使用该URL时,请求将失败并显示一个错误.不存在的对象是完全有效的操作.可以在对象实际上载之前在 上对该URL进行签名,并且,只要URL尚未过期,则该对象创建后仍然可以使用(如果以后创建的话).

However, I would argue from a design perspective that this service shouldn't really care whether the object exists. Why would you receive requests for objects that don't exist? Who's asking for that? That should be the caller's problem -- and if you generate a signed URL for an object that doesn't exist, the request will fail with an error, when the caller tries to use the URL... But generating a signed URL for a non-existent object is a perfectly valid operation. The URL can be signed before the object is actually uploaded, and, as long as the URL hasn't expired, it will still work once the object is created, if it's created later.

这篇关于S3:为给定密钥生成预签名URL. [密钥可能存在/不存在]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆