You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Spring WebClient通过预签名URL传文件到AWS S3遇凭证格式错误

使用Spring WebClient通过预签名URL上传文件到AWS S3时的AuthorizationQueryParametersError问题及解决方法

场景说明

使用响应式Spring框架,通过Spring WebClient实现将.csv文件通过预签名URL上传至AWS S3,运行环境为Windows平台下的Java 1.8,未在WebClient中设置任何请求头。

代码实现

WebClient Bean配置

@Bean
public WebClient webClient(WebClient.Builder webClientBuilder) {
    ConnectionProvider provider = ConnectionProvider
        .builder("customFixedConnectionPool").maxConnections(maxConnections).pendingAcquireTimeout(
            Duration.ofMillis(acquireTimeout)).build();
    HttpClient httpClient = HttpClient.create(provider).resolver(DefaultAddressResolverGroup.INSTANCE);
    return webClientBuilder
        .clientConnector(new ReactorClientHttpConnector(httpClient))
        .build(); 
}

FileUploadClient实现

说明:以下代码中,BodyInserters.fromResource(resource)返回BodyInserter<Resource, ReactiveHttpOutputMessage>

@Component
public class FileUploadClient implements FileUploadClientInterface {
  public FileUploadClient(WebClient webClient) {
    this.webClient = webClient.mutate()
        .build();
  }
  private final WebClient webClient;
  @Override
  public Mono<FileUploadResponse> uploadFIle(String preSignedUrl, String filePath) {
    Resource resource = new PathResource(filePath);
    return webClient.put()
        .uri(preSignedUrl)
        .body(BodyInserters.fromResource(resource))
        .exchangeToMono(response -> {
          if (response.statusCode().equals(HttpStatus.NO_CONTENT)) {
            fileUploadResponse.setCode(HttpStatus.NO_CONTENT.value());
            fileUploadResponse.setMessage("FILE_UPLOAD_SUCCESS");
            return Mono.just(fileUploadResponse);
          } else {
            return response.bodyToMono(String.class)
                .flatMap(responseBodyString -> {
                  fileUploadResponse.setCode(response.statusCode().value());
                  fileUploadResponse.setMessage(responseBodyString);
                  return Mono.just(fileUploadResponse);
                });
          }
        }).onErrorResume(throwable -> {
          fileUploadResponse.setCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
          fileUploadResponse.setMessage(throwable.getMessage());
          System.out.println("uploadLog Error: "+ throwable.getMessage());
          return Mono.just(fileUploadResponse);
        });
  }
}

错误信息

执行时出现如下错误:

<?xml version="1.0" encoding="UTF-8"?> <Error><Code>AuthorizationQueryParametersError</Code><Message>Error parsing the X-Amz-Credential parameter; the Credential is mal-formed; expecting "&lt;YOUR-AKID&gt;/YYYYMMDD/REGION/SERVICE/aws4_request".</Message><RequestId>xxxxxx</RequestId><HostId>xxxxxx</HostId></Error>

预签名URL示例

使用的预签名URL格式如下:

https://xxx-xx-xxx-xx.s3.ap-southeast-1.amazonaws.com/PG00009912/PENDING/REQ_PG00009912_11112022.csv?X-Amz-Security-Token=dzEIz%2F%2F%2F%2F%2F%2F%2F%2F%2F%2FwEaDLAplr5Vvi%2F0mZqIMSLABMetINeSCoOWcMxBPkBQN44hB1gyNBFfSPoAOLe0FY8lhBgsBis%2F7oRp3WU8H6qDUpI%2BsxCZEIFMWTkoP%2FIZP%2FAUG5ib8qAIx3gCuVtFLLx77kxdclqm8PhC6OlkYZ5fBrlUl7hHvY9w8hdFAWvRByaqsNKGWiiwwhaMvWZNI65O%2BoWZ84ESwBQCZxbp3e4TdWvUEuB%2FnVpyoMbUfugGxVK2rG58rgJpUKK5E9rv8ZTzIkUqjH7Ql5ZL%2FCt0%2FTa%2Fbj98617MKMk2bPu7dcLZpurNJ75J4AIH2a5%2Bql5tk7FB2f8uwIad3ZskiV5rtz%2FmyoqxFxc5eaaC6YbXDC06eHcMirg81U15XXqFgM2Qi%2FFjx3yutm0E59aPHSEz1K0ucfe2%2FUYLYbB57V%2FgFD8MO8pwHKmLDC0hXVFhXny8nnpPq5PBkqzZomk%2BBOiwBnkP5H98tRXRshwhqnmIMh80xyEy6%2FfCLBRSmJEMrzTpQqDpi%2B1%2Fg7wnOK8Gpv2iyLIU%2FBTD1%2FwgQ716qVsDjH8eTyPga513G6uZ94Kp4pKr1M1E1wsh2IbuvfMlPQ%2FOnL7zA07jZtNxWe%2B538Gs5%2FMwtz9fM%2FoEkeNolx96k3cgDCyQCiD8HU%2FKJk8UYUttSv8CBwkI3PwAW1Sdty0O2L0dGGyFFwwtu6wql8%2BJYxkAZOdZCxDDg2YoaeayVrjYq9mp9yZ%2BxJR1OsVuwmfRkQZcgkUPj7MnCGdgKN1KJAiNk6uVs%2FpSRxEWtSeJlhU806%2FACCiznbObBjIrEwg1WuV%2BkReFAoD86rDec%2BE%2BKmhjb2ahFqHqtY9V4YAYF82RtEzUQld6MQ%3D%3D&X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20221110T101307Z&X-Amz-SignedHeaders=host&X-Amz-Expires=26212&X-Amz-Credential=H2DP6FQ%2F20221110%2Fap-southeast-1%2Fs3%2Faws4_request&X-Amz-Signature=787c80356d749c9e0e1231ceb75d64df77f1cf40830146dfa

解决方案

问题原因是WebClient对预签名URL进行了不必要的二次编码,将代码中的.uri(preSignedUrl)改为.uri(URI.create(preSignedUrl))即可解决。


内容的提问来源于stack exchange,提问作者techmagister

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 04:30:58