国内使用亚马逊S3一些注意事项

一、亚马逊国内和海外是有区别的

新项目要使用亚马逊服务器,最近就在研究使用亚马逊的一些服务功能,亚马逊的文档看起来有点恶心,不像阿里这些,简单易懂。而且海外和国内是有区别的。记录一些使用心得。

二、这里主要讲S3的功能

先讲一些亚马逊平台上的功能把。国内亚马逊从账号申请下来开始算时间,有免费试用服务的,都可以试用,直接选中服务使用就行。但是是有免费额度的,额度根据你使用的服务官网写的一些限制内都是免费的。在右上角的菜单栏,可以查看免费额度使用情况。
在这里插入图片描述
在这里插入图片描述
控制台找到S3服务进入,看到如下页面,开始新建桶资源。

在这里插入图片描述
新建桶操作如下,填入桶名称:
在这里插入图片描述
开启是否阻止公网访问权限,打开后互联网不能直接访问。如下:
在这里插入图片描述
其他使用默认选择直接保存。根据你的是否阻止公网访问,显示如上图桶列表的情况,公开或者存储桶和对象不是公有的两种情况,这两种情况要根据你的实际使用来区分。下面区分两种情况的操作。

公开桶,如图片等网站直接需要访问的

在创建新的桶的时候,现在关闭阻止公网访问权限保存成功后。点击列表进入桶,如下进入权限栏:
在这里插入图片描述
选择编辑存储桶策略,添加该策略后,才能使这个桶下面的对象被查询到。如下:在这里插入图片描述

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Statement1",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:GetObject",
            "Resource": "你自己的存储桶 ARN/*"
        }
    ]
}

然后,也是最重要的一点:亚马逊中国区,必须进行ICP 备案,申请开发80或443端口,否则是不能通过网址直接访问s3内部对象的。
如果你进行了完整备案后,那么恭喜你,你可以通过对象地址直接在浏览器访问该地址查看。在这里插入图片描述

代码操作桶内容

准备配置亚马逊秘钥
在这里插入图片描述
在这里插入图片描述下载秘钥文档使用秘钥配置进代码里面,直接上代码。maven对应的包

		<dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-s3</artifactId>
            <version>1.12.292</version>
        </dependency>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-sts</artifactId>
            <version>1.12.261</version>
        </dependency>
public class OssConfiguration {
    public static String accessKey;

    public static String secretKey;

    public static String region;
    @Bean
    public AmazonS3 amazonS3() {
        return AmazonS3ClientBuilder.standard()
                .withCredentials(
                        new AWSStaticCredentialsProvider(
                                new BasicAWSCredentials(OssConfiguration.accessKey, OssConfiguration.secretKey)))
                .withRegion(OssConfiguration.region)
                .build();
    }
}

实现方法类如下:我使用的都是文件上传比较常规的用法,前端请求后端接口生成上传地址,前端通过地址直接上传文件,并且在保存信息的时候带上文件地址调用其他接口发送给后端,接口自行定义书写,我这就没传了。

	@Resource
    private AmazonS3 client;
	 /**
     * 预签名上传文件
     *
     * @param bucket bucket
     * @param fileName 文件名
     * @return {String} url
     */
	@Override
    public String preUploadFile(String bucket, String fileName) {
        // token设置1小时后过期
        DateTime expiration = DateUtil.offsetHour(new Date(), 1);
        URL url = client.generatePresignedUrl(new GeneratePresignedUrlRequest(bucket, fileName).withExpiration(expiration).withMethod(HttpMethod.PUT));
        return url.toString();
    }
    /**
     * 查询文件访问路径
     * @param bucket    bucket name
     * @param objectKey object name
     * @return download url
     */
     @Override
    public URL getObjectUrl(String bucket, String objectKey) {
        if (client == null) {
            createClient();
        }
        return client.generatePresignedUrl(bucket, objectKey,
                new Date(System.currentTimeMillis() + OssConfiguration.expire * 1000), HttpMethod.GET);
    }
	/**
     * 删除对象
     * @param bucket
     * @param objectKey
     * @return
     */
    @Override
    public Boolean deleteObject(String bucket, String objectKey) {
        if (!client.doesObjectExist(bucket, objectKey)) {
            return true;
        }
        client.deleteObject(bucket, objectKey);
        return true;
    }
	/**
     * 获取对象流
     * @param bucket
     * @param objectKey
     * @return
     */
    @Override
    public InputStream getObject(String bucket, String objectKey) {
        return client.getObject(bucket, objectKey).getObjectContent().getDelegateStream();
    }
	/**
    * @ Description 后端上传文件
    * @ Param [bucket, objectKey, input]
    * @ return void
    **/
    @Override
    public void putObject(String bucket, String objectKey, InputStream input) {
        if (client.doesObjectExist(bucket, objectKey)) {
            throw new RuntimeException("The filename already exists.");
        }
        PutObjectResult objectResult = client.putObject(new PutObjectRequest(bucket, objectKey, input, new ObjectMetadata()));
        log.info("Upload File: {}", objectResult.toString());
    }

非公开桶

不共开的桶只需要创建好就是不共开的桶,不共开的桶只有一个访问不一样。访问的时候,有两种方式,一种生成预签名地址,在有效期内,预签名地址是可以访问文件的。

	@Override
    public String downloadPreSignatureUrl(String bucket, String key) {
        DateTime expiration = DateUtil.offsetDay(new Date(), 7);
        return client.generatePresignedUrl(new GeneratePresignedUrlRequest(bucket, key).withExpiration(expiration).withMethod(HttpMethod.GET)).toString();
    }

另一种方式比较麻烦,使用用户临时凭证生成s3客户端的方式访问。需要开启账号的sts权限。
在OssConfiguration配置文件添加下面几个属性,后面两个属性根据添加的sts权限角色获取。

public static Long expire;//有效期

public static String roleSessionName;

public static String roleArn;

生成临时凭证,并且使用临时凭证生成s3客户端访问,如下:

	@Override
    public Credentials getCredentials() {
        AWSSecurityTokenService stsClient = AWSSecurityTokenServiceClientBuilder.standard()
                .withCredentials(new AWSStaticCredentialsProvider(
                        new BasicAWSCredentials(OssConfiguration.accessKey, OssConfiguration.secretKey)))
                .withRegion(OssConfiguration.region).build();

        AssumeRoleRequest request = new AssumeRoleRequest()
                .withRoleArn(OssConfiguration.roleArn)
                .withRoleSessionName(OssConfiguration.roleSessionName)
                .withDurationSeconds(Math.toIntExact(OssConfiguration.expire));
        AssumeRoleResult result = stsClient.assumeRole(request);
        Credentials credentials = result.getCredentials();
        BasicSessionCredentials awsCredentials = new BasicSessionCredentials(
                credentials.getAccessKeyId(),
                credentials.getSecretAccessKey(),
                credentials.getSessionToken());

        AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                .withCredentials(new AWSStaticCredentialsProvider(awsCredentials))
                .withRegion(OssConfiguration.region)
                .build();
        return credentials;

使用临时凭证生成的s3客户端可以上传下载对象等。到此s3的相关用法全部完成。最近因为项目要上海外,所以一直在研究亚马逊的服务,亚马逊在使用上对开发者来说真的没有阿里云友好,文档感觉很乱。

本文手打,转载请注明出处。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值