使用AWS SDK for Java 上傳和下載文件

使用AWS SDK for Java 上傳和下載文件。 已有 amazonaws.cn 中國區賬號。

本文敘述了怎樣獲取訪問密鑰,進行demo配置,demo運行出錯的解決辦法。

1. 獲取訪問密鑰

登錄 https://console.amazonaws.cn/iam/home,點擊左側“用戶”,選擇自己的賬號;點擊“安全證書”,可以看到下方有訪問密鑰,我的賬號只能申請2個密鑰,之前的key已經不知道了,刪掉舊的申請個新的即可。得到的就是aws_access_key_id 和 aws_secret_access_key 。

2. 配置密鑰

2.1 配置文件方式

參考文章 http://docs.aws.amazon.com/zh_cn/sdk-for-java/v1/developer-guide/setup-credentials.html,在本地系統上的 AWS 憑證配置文件中設置憑證,該配置文件位於:

~/.aws/credentials (在 Linux、macOS 或 Unix) 上
C:\Users\USERNAME\.aws\credentials (在 Windows 上)

文件包含以下格式的行,用自己的 AWS 憑證值替換值 your_access_key_id 和 your_secret_access_key。

[default]
aws_access_key_id = your_access_key_id
aws_secret_access_key = your_secret_access_key

AmazonS3 的初始化

AmazonS3 s3client = new AmazonS3Client(new ProfileCredentialsProvider());

2.2 參數方式

官方文檔中給出的密鑰配置方式需要在特定目錄下放置配置文件,工程部署不方便。找了參數方式初始化的方法。

AWSCredentials credentials = new BasicAWSCredentials(
        myConfig.AWS_ACCESS_KEY_ID, myConfig.AWS_SECRET_ACCESS_KEY);
AmazonS3 s3Client = new AmazonS3Client(credentials);

3. 我的第一個上傳demo

參考官方文檔
http://docs.aws.amazon.com/zh_cn/AmazonS3/latest/dev/UploadObjSingleOpJava.html
在自己的工程裏新建了UploadObjectSingleOperation類,需要配置的三項如下:

private static String bucketName     = "手動在AWS S3中創建的桶名稱";
private static String keyName        = "希望這個文件上傳後的key,需要注意的,這個key不要重複,否則會覆蓋掉舊的文件";
private static String uploadFileName = "待上傳的本地文件路徑和名稱";

依賴包(gradle)

// https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-s3
compile group: 'com.amazonaws', name: 'aws-java-sdk-s3', version: '1.11.238'

Demo失敗原因1

java.lang.reflect.InvocationTargetException: null
……
Caused by: org.apache.http.conn.ConnectTimeoutException: Connect to englishresourcebucket.s3.amazonaws.com:443 [englishresourcebucket.s3.amazonaws.com/54.231.33.147] failed: Read timed out
……
Caused by: java.net.SocketTimeoutException: Read timed out

解決辦法,設置區域:

String regionName = "cn-north-1";
Region region = Region.getRegion(Regions.fromName(regionName));
s3client.setRegion(region);
String serviceEndpoint = region.getServiceEndpoint(ServiceAbbreviations.S3);
s3client.setEndpoint(serviceEndpoint);

s3client.putObject(new PutObjectRequest(bucketName, keyName, file));

4. 文件下載

參考官方文檔,
http://docs.aws.amazon.com/zh_cn/AmazonS3/latest/dev/GettingObjectsUsingAPIs.html
http://docs.aws.amazon.com/zh_cn/AmazonS3/latest/dev/RetrievingObjectUsingJava.html GetObject.java

同樣的也加上區域設置的代碼,就可以跑通這段demo了。

5. 我的Demo

    private AmazonS3 s3Client;
    private String bucketName;

    public S3Service(MyConfig myConfig) {
        AWSCredentials credentials = new BasicAWSCredentials(
                myConfig.AWS_ACCESS_KEY_ID, myConfig.AWS_SECRET_ACCESS_KEY);
        s3Client = new AmazonS3Client(credentials);

        String regionName = myConfig.AWS_REGION;
        Region region = Region.getRegion(Regions.fromName(regionName));
        s3Client.setRegion(region);
        final String serviceEndpoint = region.getServiceEndpoint(ServiceAbbreviations.S3);
        s3Client.setEndpoint(serviceEndpoint);

        bucketName = myConfig.AWS_BUCKET_NAME;
    }

    public void upload(MultipartFile file, String keyName)
            throws MyException {
        ObjectMetadata metadata = new ObjectMetadata();
        metadata.setContentType(file.getContentType());
        metadata.setContentLength(file.getSize());
        try {
            s3Client.putObject(new PutObjectRequest(
                    bucketName, keyName, file.getInputStream(), metadata));
        } catch (AmazonServiceException ase) {
            logger.warn("Caught an AmazonServiceException, which " +
                    "means your request made it " +
                    "to Amazon S3, but was rejected with an error response" +
                    " for some reason.");
            logger.warn(printAse(ase));
            throw new MyException ("upload file failed",
                    MyExceptionType.AWS_UPLOAD_FAILED);
        } catch (AmazonClientException ace) {
            logger.warn("Caught an AmazonClientException, which " +
                    "means the client encountered " +
                    "an internal error while trying to " +
                    "communicate with S3, " +
                    "such as not being able to access the network.");
            logger.warn("Error Message: " + ace.getMessage());
            throw new MyException ("upload file failed",
                    MyExceptionType.AWS_UPLOAD_FAILED);
        } catch (IOException ioe) {
            logger.warn("Caught an IOException: " + ioe.getMessage());
            throw new MyException ("upload file failed",
                    MyExceptionType.AWS_UPLOAD_FAILED);
        }
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章