zoukankan      html  css  js  c++  java
  • 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());
            }
        }
    往外张望的人在做梦,向内审视的人才是清醒的
  • 相关阅读:
    IntelliJ IDEA 快捷键终极大全,速度收藏!
    49式!Python初级到高级招式都全了
    字节跳动三轮技术面_后端研发提前批
    这样让你的 IDEA 好用到飞起来!
    你 多久没有跳槽了?
    推荐几款能提升代码效率的笔记应用
    推荐 15 款编程游戏,从此谁都可以学编程!
    StackOverflow 创始人关于如何高效编程的清单
    11 条编程经验分享
    InnoDB和MyISAM存储引擎的区别
  • 原文地址:https://www.cnblogs.com/StefanieYang/p/13229128.html
Copyright © 2011-2022 走看看