Polygramboy 2022-12-03 15:09 采纳率: 0%
浏览 21
已结题

s3生成预签名URL上传文件至AWS报a non-empty region must be provided in the credential


<?xml version="1.0" encoding="UTF-8"?>
<Error>
    <Code>AuthorizationQueryParamehttps://img-mid.csdnimg.cn/release/static/image/mid/ask/963362150076159.png "#left")
tersError</Code>
    <Message>Error parsing the X-Amz-Credential parameter; a non-empty region must be provided in the credential.</Message>
    <RequestId>8JNM9EGMK0JCZ6PE</RequestId>
    <HostId>2OulV6W9KIBrUTVjz1slprX+PmHCEnuwDiQS38/m4pkF+vuouyqyQaclRjn2kmPvo05X5IIGkmw=</HostId>
</Error>

用s3生成预签名URL,上传文件至AWS报错,求解

  • 写回答

1条回答 默认 最新

  • 龙星尘 2022-12-06 15:34
    关注

    望采纳:
    步骤:

    1、前端上传文件,将要上传的文件名称传到后台

    2、后台通过该文件名称生成预上传URL返回前端

    3、前端请求该URL,并携带文件上传至S3
    后端代码:

        /**
         * AWS预签名上传
         * @return
         */
        @GetMapping("/upload")
        public Object generatePreSignedUrl(String fileName){
            Map<String, Object> map = new HashMap<>();
            try {
                AWSCredentials awsCredentials = new BasicAWSCredentials(AWS_ACCESS_KEY, AWS_SECRET_KEY);
                AWSCredentialsProvider awsCredentialsProvider = new AWSStaticCredentialsProvider(awsCredentials);
                AmazonS3 s3Client = AmazonS3ClientBuilder.standard()
                        .withCredentials(new ProfileCredentialsProvider())
                        .withRegion(Regions.CN_NORTH_1)
                        .withCredentials(awsCredentialsProvider)
                        .build();
                java.util.Date expiration = new java.util.Date();
                long expTimeMillis = expiration.getTime();
                expTimeMillis += 1000 * 60 * 30;
                expiration.setTime(expTimeMillis);
                String name = fileName.substring(0,fileName.lastIndexOf("."));
                String fileType = fileName.substring(fileName.lastIndexOf("."));
                String prefixFileName = name+ "_"+String.valueOf(System.currentTimeMillis()).substring(6)+""+fileType;
                Review review = new Review();
                review.setName(name);
                GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(BUCKET_NAME, prefixFileName)
                        .withMethod(HttpMethod.PUT)
                        .withExpiration(expiration);
                URL url = s3Client.generatePresignedUrl(generatePresignedUrlRequest);
                if(url == null){
                    return map;
                }
                // 文件访问地址
                StringBuilder urlImage = new StringBuilder();
                urlImage.append(url.getProtocol()).append("://").append(url.getHost()).
                        append(URLDecoder.decode(url.getPath(), "UTF-8"));
                // 预签名put地址
                StringBuilder preUrl = new StringBuilder();
                preUrl.append(url.getProtocol()).append("://").append(url.getHost()).
                            append(URLDecoder.decode(url.getFile(), "UTF-8"));
                map.put("preUrl",preUrl);
                map.put("urlImage",urlImage);
                return map;
            } catch (Exception e) {
                e.printStackTrace();
                return map;
            }
        }
    
    

    前端代码:

    import axios from 'axios'
     
                    axios.put(preUrl, fileList[0], {
                    headers: {
                      'Content-Type': 'multipart/form-data'
                    },
                    onUploadProgress: progressEvent => {
                      let complete = (progressEvent.loaded / progressEvent.total * 100.).toFixed(2)
                      
                    }
                  })
                    .then((res: any) => {
                      if (res.status == 200) {
                        console.log(res)
                      }
                    }).catch(
                      err => {
                        console.log(err)
                      })
    
    

    当然也可以直接后台就上传到AWS,后端代码为:

        private void uploadContent(String imageUrl){
            // Set the pre-signed URL to expire after one hour.
            java.util.Date expiration = new java.util.Date();
            long expTimeMillis = expiration.getTime();
            expTimeMillis += 1000 * 60 * 5;
            expiration.setTime(expTimeMillis);
            // Generate the pre-signed URL.
            String fileType = imageUrl.substring(imageUrl.lastIndexOf("."));
            // 上传s3不保存后缀,
            String prefixFileName = UUIDUtils.getUUID()+""+fileType;
            GeneratePresignedUrlRequest generatePresignedUrlRequest = new GeneratePresignedUrlRequest(BUCKET_NAME, prefixFileName)
                    .withMethod( com.amazonaws.HttpMethod.PUT)
                    .withExpiration(expiration);
            URL url = amazonS3.generatePresignedUrl(generatePresignedUrlRequest);
            log.info("Generate the pre-signed URL: "+url);
            // Create the connection and use it to upload the new object using the pre-signed URL.
            HttpsURLConnection connection = null;
            OutputStream out = null;
            InputStream inputStream = null;
            try {
                // 需要上传的网络图片转为流
                URL url1 = new URL(imageUrl);
                HttpsURLConnection httpsURLConnection = (HttpsURLConnection) url1.openConnection();
                inputStream = httpsURLConnection.getInputStream();
                // 通过预签名url上传文件
                connection = (HttpsURLConnection) url.openConnection();
                connection.setDoOutput(true);
                connection.setRequestMethod("PUT");
                out = connection.getOutputStream();
                byte[] arr = new byte[1024]; //该数组用来存入从输入文件中读取到的数据
                int len; //变量len用来存储每次读取数据后的返回值
                //while循环:每次从输入文件读取数据后,都写入到输出文件中
                while( ( len=inputStream.read(arr) ) != -1 ) {
                    out.write( arr, 0, len);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                if(out != null){
                    try {
                        out.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if(inputStream != null){
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
    

    可以借阅这篇文章:
    AWS S3 实现预签名上传_酷爱编程的小猿同学的博客-CSDN博客_s3预签名

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 12月6日
  • 赞助了问题酬金15元 12月5日
  • 创建了问题 12月3日

悬赏问题

  • ¥15 is not in the mmseg::model registry。报错,模型注册表找不到自定义模块。
  • ¥15 安装quartus II18.1时弹出此error,怎么解决?
  • ¥15 keil官网下载psn序列号在哪
  • ¥15 想用adb命令做一个通话软件,播放录音
  • ¥30 Pytorch深度学习服务器跑不通问题解决?
  • ¥15 部分客户订单定位有误的问题
  • ¥15 如何在maya程序中利用python编写领子和褶裥的模型的方法
  • ¥15 Bug traq 数据包 大概什么价
  • ¥15 在anaconda上pytorch和paddle paddle下载报错
  • ¥25 自动填写QQ腾讯文档收集表