展开
拓展 关闭
订阅号推广码
GitHub
视频
公告栏 关闭

亚马逊服务上传视频,返回预览链接

<dependency>
    <groupId>software.amazon.awssdk</groupId>
    <artifactId>aws-sdk-java</artifactId>
    <version>2.14.26</version>
</dependency>
  • 工具类
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import software.amazon.awssdk.auth.credentials.AwsBasicCredentials;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import software.amazon.awssdk.services.s3.model.S3Exception;
import software.amazon.awssdk.services.s3.presigner.S3Presigner;
import software.amazon.awssdk.services.s3.presigner.model.GetObjectPresignRequest;
import software.amazon.awssdk.services.s3.presigner.model.PresignedGetObjectRequest;
import software.amazon.awssdk.services.s3.presigner.model.PresignedPutObjectRequest;
import software.amazon.awssdk.services.s3.presigner.model.PutObjectPresignRequest;
import software.amazon.awssdk.utils.IoUtils;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.time.Duration;

@Slf4j
@RequestMapping("/loadtest")
@RestController
public class UpLoadController {

    @Autowired
    private AwsS3Config s3Config;
    
    @PostMapping("/uploadFile")
    public String uploadFile(@RequestPart(value = "file") MultipartFile multipartFile) {
        String fileUrl = "";
        try {
            // 调用方法2 将MultipartFile转为File
            File file = convertMultiPartToFile(multipartFile);
            // 获取原文件名称
            String fileName = multipartFile.getOriginalFilename();
            // 使用终端节点连接到aws服务,终端节点是作为 AWS Web 服务的入口点的 URL
            Region region = Region.CN_NORTHWEST_1;
            String presignUrlDurationMinutes = "5000";
            // 签名url有效期
            long presignUrlDurationMinutesLong = Long.valueOf(presignUrlDurationMinutes);
            // 文件类型 IMAGE_PNG_VALUE = "image/png"
            String contentType = MediaType.IMAGE_PNG_VALUE;;
            // 创建资格证书
            AwsBasicCredentials awsBasicCredentials = AwsBasicCredentials.create(s3Config.getAccessKey(),s3Config.getSecretKey());
            // 构建签名器
            S3Presigner s3Presigner = S3Presigner.builder().region(region).credentialsProvider(StaticCredentialsProvider.create(awsBasicCredentials)).build();
            // 调用方法3 获取预签署地址(要上传到的地址);参数(构建签名器、bucketName、原文件名、终端节点、keyId、AccessKey、签名有效期)
            URL presignedUrl = generatePresignedUrl(s3Presigner, s3Config.getBucketName(), fileName, region, s3Config.getAccessKey(),s3Config.getSecretKey(), presignUrlDurationMinutesLong);
            // 调用方法5 上传文件;参数(预签署地址、原文件名称、文件类型)
            uploadObject(presignedUrl, fileName, contentType);
            // 调用方法4 获取预览url;参数(签名构建器、bucketName、原文件名称)
            URL url = getPresignedUrl(s3Presigner, s3Config.getBucketName(), fileName);
            fileUrl = url.toString();
            // 删除临时文件
            file.delete();
        } catch (Exception e) {
            return "UploadController().uploadFile().Exception : " + e.getMessage();
        }
        return fileUrl;
    }

    // 将MultipartFile转为File
    private File convertMultiPartToFile(MultipartFile file) throws IOException {
        File convFile = new File(file.getOriginalFilename());
        FileOutputStream fos = new FileOutputStream(convFile);
        fos.write(file.getBytes());
        fos.close();
        return convFile;
    }

    /**
     * 返回预签署地址
     * @param s3Presigner   构建签名器
     * @param bucketName    bucketName
     * @param objectKey     原文件名
     * @param region    终端节点
     * @param accessKeyId   keyId
     * @param secretAccessKey   AccessKey
     * @param presignUrlDurationMinutesLong 签名有效期
     * @return
     */
    private static URL generatePresignedUrl(S3Presigner s3Presigner, String bucketName, String objectKey, Region region, String accessKeyId, String secretAccessKey, long presignUrlDurationMinutesLong) {
        // 上传文件请求
        PutObjectRequest putObjectRequest = PutObjectRequest.builder().bucket(bucketName).key(objectKey).build();
        // 上传文件预签名请求
        PutObjectPresignRequest putObjectPresignRequest = PutObjectPresignRequest.builder().signatureDuration(Duration.ofMinutes(presignUrlDurationMinutesLong)).putObjectRequest(putObjectRequest).build();
        PresignedPutObjectRequest presignedPutObjectRequest = s3Presigner.presignPutObject(putObjectPresignRequest);
        // 获取到预签署地址
        URL presignedUrl = presignedPutObjectRequest.url();
        log.info("Presigned URL: ", presignedUrl);
        log.info("Method needed: ", presignedPutObjectRequest.httpRequest().method());
        s3Presigner.close();
        return presignedUrl;
    }

    /**
     *  获取预签名对象:https://docs.amazonaws.cn/sdk-for-java/latest/developer-guide/examples-s3-presign.html
     *  从预签名 S3 存储桶中读取内容
     * @param presigner 签名构建器
     * @param bucketName    bucketName
     * @param keyName   原文件名称
     * @return  预览地址
     */
    public static URL getPresignedUrl(S3Presigner presigner, String bucketName, String keyName) {
        try {
            // 获取对象请求;参数(bucketName、原文件名称)
            GetObjectRequest getObjectRequest = GetObjectRequest.builder().bucket(bucketName).key(keyName).build();
            GetObjectPresignRequest getObjectPresignRequest = GetObjectPresignRequest.builder().signatureDuration(Duration.ofMinutes(1000)).getObjectRequest(getObjectRequest).build();
            // 预签名对象
            PresignedGetObjectRequest presignedGetObjectRequest = presigner.presignGetObject(getObjectPresignRequest);
            log.info("Presigned URL: ", presignedGetObjectRequest.url());
            // 打开连接,获取网络对象HttpURLConnection
            HttpURLConnection connection = (HttpURLConnection) presignedGetObjectRequest.url().openConnection();
            // 添加请求头信息
            presignedGetObjectRequest.httpRequest().headers().forEach((header, values) -> {
                values.forEach(value -> {
                    connection.addRequestProperty(header, value);
                });
            });
            // 发送服务需要的任何请求有效负载(当isBrowserExecutable为true时不需要)
            if (presignedGetObjectRequest.signedPayload().isPresent()) {
                connection.setDoOutput(true);
                try (InputStream signedPayload = presignedGetObjectRequest.signedPayload().get().asInputStream();
                     OutputStream httpOutputStream = connection.getOutputStream()) {
                    IoUtils.copy(signedPayload, httpOutputStream);
                }
            }
            // 下载执行请求的结果
            try (InputStream content = connection.getInputStream()) {
                log.info("Service returned response: ");
                // 内容复制
                IoUtils.copy(content, System.out);
            }
            presigner.close();
            // 返回预览地址
            return presignedGetObjectRequest.url();
        } catch (S3Exception e) {
            e.getStackTrace();
        } catch (IOException e) {
            e.getStackTrace();
        }
        return null;
    }

    /**
     * 上传文件到亚马逊服务器
     * @param presignedUrl  预签署地址
     * @param objectLocalPath   原文件名称
     * @param contentType   文件类型
     */
    private static void uploadObject(URL presignedUrl, String objectLocalPath, String contentType) {
        // 缓冲字节输出流
        BufferedOutputStream bufferedOutputStream = null;
        // 缓冲字节输入流
        BufferedInputStream bufferedInputStream = null;
        try {
            // 打开连接,获取网络对象HttpURLConnection
            HttpURLConnection httpURLConnection = (HttpURLConnection) presignedUrl.openConnection();
            // 设置是否向HttpURLConnection输出
            httpURLConnection.setDoOutput(true);
            // 设置文件类型
            httpURLConnection.setRequestProperty("Content-Type", contentType);
            // 设置请求方式
            httpURLConnection.setRequestMethod("PUT");
            // 获取缓冲字节输出流
            bufferedOutputStream = new BufferedOutputStream(httpURLConnection.getOutputStream());
            // 传入参数本地文件路劲
            bufferedInputStream = new BufferedInputStream(new FileInputStream(new File(objectLocalPath)));
            byte[] buffer = new byte[1024];
            // 缓冲输入流读到buffer数组
            int length = bufferedInputStream.read(buffer);
            while (length > 0) {
                // 缓冲输出流将buffer数组中的字节写到远程服务
                bufferedOutputStream.write(buffer);
                length = bufferedInputStream.read(buffer);
            }
            // 刷新缓冲输出流,并关闭
            bufferedOutputStream.flush();
            bufferedOutputStream.close();
            log.info("Response Code: ", httpURLConnection.getResponseCode());
            log.info("Response Message: ", httpURLConnection.getResponseMessage());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (bufferedOutputStream != null) {
                try {
                    bufferedOutputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bufferedInputStream != null) {
                try {
                    bufferedInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}
posted @ 2022-05-12 15:44  DogLeftover  阅读(99)  评论(0编辑  收藏  举报