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、前端上传文件,将要上传的文件名称传到后台

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预签名