我有一台服务器产生AWS S3前签署PUT网址的工作,然后我试图上传到byte[]
使用RestTemplate这个代码,网址:RestTemplate不与S3预签把网址
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.ALL));
HttpEntity<byte[]> entity = new HttpEntity<>("Testing testing testing".getBytes(), headers);
System.out.println(restTemplate.exchange(putUrl, HttpMethod.PUT, entity, String.class));
当我运行的代码,我得到这个错误:
Exception in thread "JavaFX Application Thread" org.springframework.web.client.HttpClientErrorException: 400 Bad Request
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:63)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:700)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:653)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:613)
at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:531)
at tech.dashman.dashman.controllers.RendererAppController.lambda$null$2(RendererAppController.java:95)
不幸的是,有没有在AWS S3日志,所以,我不知道发生了什么事。如果我使用完全相同的URL并将其放入IntelliJ IDEA的REST客户端,它就会起作用(它会在S3中创建一个空文件)。
任何想法我的Java代码有什么问题?
这里有一个完整的示例,它所做的签署,并试图上载一个小有效载荷S3:
import com.amazonaws.HttpMethod;
import com.amazonaws.auth.AWSStaticCredentialsProvider;
import com.amazonaws.auth.BasicAWSCredentials;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;
import com.amazonaws.services.s3.model.GeneratePresignedUrlRequest;
import org.joda.time.DateTime;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.web.client.RestTemplate;
import java.util.Date;
public class S3PutIssue {
static public void main(String[] args) {
String awsAccessKeyId = "";
String awsSecretKey = "";
String awsRegion = "";
String path = "";
String awsBucketName = "";
BasicAWSCredentials awsCredentials = new BasicAWSCredentials(awsAccessKeyId, awsSecretKey);
AmazonS3 s3Client = AmazonS3ClientBuilder.standard().withRegion(awsRegion).
withCredentials(new AWSStaticCredentialsProvider(awsCredentials)).build();
Date expiration = new DateTime().plusDays(1).toDate();
GeneratePresignedUrlRequest urlRequest = new GeneratePresignedUrlRequest(awsBucketName, path);
urlRequest.setMethod(HttpMethod.PUT);
urlRequest.setExpiration(expiration);
String putUrl = s3Client.generatePresignedUrl(urlRequest).toString();
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
HttpEntity<byte[]> entity = new HttpEntity<>("Testing testing testing".getBytes(), headers);
restTemplate.exchange(putUrl, org.springframework.http.HttpMethod.PUT, entity, Void.class);
}
}
从你所描述的我可以想象,你的代码不会产生与IDEA的REST客户端一样的调用。我可以推荐设置日志级别,这样你可以看到底层的HTTP相关日志,看看究竟发送了什么 - 我期望它的标题有些不同。另外,如果你不使用PUT的签名,你的代码是否工作? – Xonix
@Xonix:如何增加RestTemplate的日志输出?我认为所提出的要求几乎可以肯定,但我找不到差别。 – Pablo
你是什么意思的“预签名”网址? –