AmazonS3-Java對接


AmazonS3-Java對接

1、Amazons3?

S3 是一個全球存儲區域網絡(SAN),它表現為一個超大的硬盤,可以存儲AWS用戶上傳的資源文件。S3可根據AWS用戶需求不同創建不同區域、不同名稱的Bucket(桶),代碼調用的時候可直接根據BucketNamed對Bucket進行訪問(前提是AWS憑證認證通過)。

2、基礎配置

1、AWS用戶憑證設置

AWS用戶憑證有一下集中方式可配置:

1:LocalFile(本地配置文件)
2:Java.profile/.java文件中設置變量
3:配置環境變量(暫未測試)

1、LoaclFile

1、AWS官網查看用戶Id/Key:
  
  

 

 
         

   


2、Windows設置:

  指定目錄下創建文件夾(.aws)及下屬文件(config/credentials)
  

   config文件:

    區域可根據自己需求(以及服務所在區域)設置

   

  credentials文件:
  

 

 3:CLI設置憑證

  見:https://www.cnblogs.com/StefanieYang/p/13229382.html

 

2、pom.xml配置

只需要引入如下依賴即可,版本可根據自行需求設定

        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-s3</artifactId>
            <version>1.11.759</version>
        </dependency>  

 

3、代碼示例

1、AmazonS3連接(正常連接)

package com.stefanie.sun.bean.AWS.Rekognition;

import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.ClientConfiguration;
import com.amazonaws.Protocol;
import com.amazonaws.auth.AWSCredentials;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
import com.amazonaws.auth.profile.ProfileCredentialsProvider;
import com.amazonaws.regions.Regions;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.*;
import com.amazonaws.util.IOUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;

/**
 * Created with IntelliJ IDEA
 * StefanieSun
 *
 * @Description: AWS S3桶連接
 * @Author: zy
 * @Date: 2020-06-28 15:51
 * @Version: 1.0.0
 */
@Slf4j
public class S3client {
  
  private final static String REGION = "us-east-2";
  private final static String ACCESSKEY = "your id";
  private final static String SECREYKEY = "your key";

  public static void main(String[] s) throws Exception {
        AmazonS3 s3 = amazonS31();
        try {
            //遍歷bucket信息
            for (Bucket bucket : s3.listBuckets()) {
                System.out.println("bucker名稱:" + bucket.getName() + "/bucker創建時間:" + bucket.getCreationDate() +
                        "/bucker-owner:" + bucket.getOwner());
            }
        } catch (AmazonClientException ace) {
            log.error(ace.getMessage());
        }
    }

  
  //1-讀取默認配置連接AmazonS3
    public static AmazonS3 amazonS31() {
        AWSCredentials credentials = null;
        try {
            credentials = new ProfileCredentialsProvider("default").getCredentials();
        } catch (Exception e) {
            throw new AmazonClientException("Exception on credentials.", e);
        }
        AmazonS3 s3 = new AmazonS3Client(credentials);
        return s3;
    }

   
  //2-默認連接方式
  public static AmazonS3 amazonS32() {
      AmazonS3 s3 = AmazonS3ClientBuilder.defaultClient();
      return s3;
  }
  
  
  //3-手動設置區域連接
  public static AmazonS3 amazonS33(){
   AWSCredentials credentials = null;
        try {
            //獲取憑證信息
            credentials = new ProfileCredentialsProvider().getCredentials();
        } catch (Exception e) {
            throw new AmazonClientException(
                    "Cannot load the credentials from the credential profiles file. " +
                            "Please make sure that your credentials file is at the correct " +
                            "location (~/.aws/credentials), and is in valid format.",
                    e);
        }

        //通過美國區域設置獲取
        AmazonS3 s3 = AmazonS3ClientBuilder.standard()
                .withCredentials(new AWSStaticCredentialsProvider(credentials))
                .withRegion(REGION)
                .build();
        return s3;
  }

  
  //4-使用S3客戶端創建連接
  public static AmazonS3 amazonS34(){
    AmazonS3 s3 = new AmazonS3Client(new DefaultAWSCredentialsProviderChain());
    return s3;
  }

  
  //5-使用Java.profile/.Java變量連接
  public static AmazonS3 amazonS35(){
     BasicAWSCredentials  awsCreds= new BashicAWSCredentials(ACCESSKEY,SECRETKEY);
     AmazonS3 s3 = AmazonS3ClientBuilder.standard()
             .withCredentials(new AWSStaticCredentialsProvider(awsCreds))
             .withRegion(Region.US-EASE-2)
             .build();
     return s3;
  }
}

2、異常區域無法訪問

1、錯誤信息

  場景:在使用 "us-east-1"區域訪問的時候無法連接,其他區域均可正常連接 

java.lang.reflect.InvocationTargetException: null
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.amazonaws.http.conn.ClientConnectionManagerFactory$Handler.invoke(ClientConnectionManagerFactory.java:76)
    at com.amazonaws.http.conn.$Proxy2.connect(Unknown Source)
    at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:393)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:236)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
    at com.amazonaws.http.apache.client.impl.SdkHttpClient.execute(SdkHttpClient.java:72)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeOneRequest(AmazonHttpClient.java:1323)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeHelper(AmazonHttpClient.java:1139)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.doExecute(AmazonHttpClient.java:796)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.executeWithTimer(AmazonHttpClient.java:764)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.execute(AmazonHttpClient.java:738)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutor.access$500(AmazonHttpClient.java:698)
    at com.amazonaws.http.AmazonHttpClient$RequestExecutionBuilderImpl.execute(AmazonHttpClient.java:680)
    at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:544)
    at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:524)
    at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:5054)
    at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:5000)
    at com.amazonaws.services.s3.AmazonS3Client.invoke(AmazonS3Client.java:4994)
    at com.amazonaws.services.s3.AmazonS3Client.listBuckets(AmazonS3Client.java:993)
    at com.amazonaws.services.s3.AmazonS3Client.listBuckets(AmazonS3Client.java:999)
    at com.stefanie.sun.bean.AWS.Rekognition.S3client.main(S3client.java:49)
Caused by: java.net.UnknownHostException: s3.amazonaws.com
    at java.net.InetAddress.getAllByName0(InetAddress.java:1280)
    at java.net.InetAddress.getAllByName(InetAddress.java:1192)
    at java.net.InetAddress.getAllByName(InetAddress.java:1126)
    at com.amazonaws.SystemDefaultDnsResolver.resolve(SystemDefaultDnsResolver.java:27)
    at com.amazonaws.http.DelegatingDnsResolver.resolve(DelegatingDnsResolver.java:38)
    at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:112)
    at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:376)
    ... 28 common frames omitted
10:14:49.175 [main] DEBUG org.apache.http.impl.conn.DefaultManagedHttpClientConnection - http-outgoing-3: Shutdown connection
10:14:49.175 [main] DEBUG org.apache.http.impl.execchain.MainClientExec - Connection discarded
10:14:49.175 [main] DEBUG org.apache.http.impl.conn.PoolingHttpClientConnectionManager - Connection released: [id: 3][route: {s}->https://s3.amazonaws.com:443][total available: 0; route allocated: 0 of 50; total allocated: 0 of 50]
10:14:49.175 [main] ERROR com.stefanie.sun.bean.AWS.Rekognition.S3client - Unable to execute HTTP request: s3.amazonaws.com

Process finished with exit code 0

2、原因分析

1:需要調用的服務在US-EAST-1區,Bucket也在US-EAST-1區,但是連接時無法訪問,提示如上所示為請求有問題
2:通過日志比對訪問成功時與訪問失敗的日志可以看出https://------后面的連接有問題,如下圖所示:

 

   由上圖可以看出https請求地址不同。

 3:在找出時http請求地址有問題的情況下,查看源代碼,找出問題,但是並未找到哪里設置有問題。

 4:在源碼中查出AmazonS3.endpoint屬性存儲http請求地址,故更改屬性即可。

 5:使用原有生成AmazonS3的方式無法更改屬性(在構建的時候無法更改屬性)。

3、解決辦法

 public static AmazonS3 amazonS36() {
        AWSCredentials credentials = new BasicAWSCredentials(ACCESSKEY, SECRETKEY);
        ClientConfiguration clientConfig = new ClientConfiguration();
        clientConfig.setProtocol(Protocol.HTTP);
        clientConfig.withSignerOverride("S3SignerType");
        //noinspection deprecation
        AmazonS3 s3 = new AmazonS3Client(credentials, clientConfig);
        s3.setEndpoint("https://s3.us-east-1.amazonaws.com");//訪問地址類似,只是區別與用戶憑證的驗證 return s3;
    }

 

4、上傳圖片

/**
     * 上傳文件
     *
     * @param filePath   本地文件路徑
     * @param bucketName 桶名稱
     * @param keyName    桶路徑以及名稱  實例:"assets/test/1513132153/1.png";
     * @throws IOException
     */
    private static void uploadFileToBucket(String filePath, String bucketName, String keyName) throws IOException {
        AmazonS3 s3Client = amazonS36();
        File imageFile = new File(filePath);
        FileInputStream in = new FileInputStream(imageFile);
        MultipartFile file = new MockMultipartFile("file", imageFile.getName(), "text/plain", IOUtils.toByteArray
                (in));
        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) {
            ase.getMessage();
        }
    }

 

5、查看Bucket中資源

  /**
     * 獲取s3桶中數據
     */
    public static void getS3Object(String bucketName) {
        AmazonS3 amazonS3 = amazonS36();
        ListObjectsV2Result result = amazonS3.listObjectsV2(bucketName);
        List<S3ObjectSummary> objects = result.getObjectSummaries();
        for (S3ObjectSummary os : objects) {
            System.out.println("* " + os.getKey());
        }
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM