英文:
Upload file to Amazon S3 without SDK
问题
Sure, here's the translation:
我的Java项目没有使用Maven或任何依赖项。是否有一种纯Java代码的简单方法来将文本文件上传到我的Amazon S3存储桶?这不是一个作业项目。
英文:
My Java project is not set up with Maven or any dependencies. Is there an easy way to upload a text file to my Amazon S3 bucket with pure Java code? This is not a homework project.
答案1
得分: 1
你可以使用位于java.net
包中的HttpURLConnection类来调用S3 REST端点。以下是一个使用PUT
S3端点上传png文件的示例(在localstack上进行了测试):
英文:
You can use the HttpURLConnection class, included in the java.net
package, to call the S3 REST endpoints.
Here's a sample that uploads a png file using the PUT
S3 endpoint (tested with localstack):
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
public class S3Uploader {
// Example AWS region
private static final String REGION = "eu-central-1";
// <localstack_endpoint>/<bucket_name>
// For real S3, use <bucket-name>.s3.<aws_region>.amazonaws.com
private static final String BUCKET_ENDPOINT = "http://localhost:4566/uploadtest";
// key of the object to save
private static final String OBJECT_NAME = "object.png";
public static void main(String[] args) throws IOException {
// File in the example is in the current dir
Path file = Paths.get(OBJECT_NAME);
String type;
long fileSize;
try {
// Probe content type and size
type = Files.probeContentType(file);
fileSize = Files.size(file);
} catch (IOException e) {
System.err.println("Cannot analyze file " + OBJECT_NAME + "!");
e.printStackTrace();
return;
}
URL url = new URL(BUCKET_ENDPOINT + "/" + OBJECT_NAME);
HttpURLConnection httpConnection;
try {
// Connect to S3
httpConnection = (HttpURLConnection) url.openConnection();
} catch (IOException e) {
System.err.println("Cannot connect to bucket " + BUCKET_ENDPOINT + "!");
e.printStackTrace();
return;
}
httpConnection.setRequestMethod("PUT");
httpConnection.setRequestProperty("Host", BUCKET_ENDPOINT);
httpConnection.setRequestProperty("Content-Type", type);
httpConnection.setRequestProperty("Content-Length", String.valueOf(fileSize));
String datetime = LocalDateTime.now().atOffset(ZoneOffset.UTC).format(DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmssZ"));
// Example AWS headers
// More: https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html
httpConnection.setRequestProperty("x-amz-date", datetime);
httpConnection.setRequestProperty("x-amz-server-side-encryption", "AES256");
httpConnection.setRequestProperty("x-amz-tagging", "description=triangle");
// Authorization (IAM authentication)
// You must sign the request manually
// Reference: https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-auth-using-authorization-header.html
httpConnection.setRequestProperty("Authorization", "AWS4-HMAC-SHA256 " +
// Credential=<access_key_id>/<date_in_yyyyMMdd_format>/<aws_region>/<aws_service>/aws4_request
"Credential=abc123/" + datetime.substring(0, datetime.indexOf('T')) + "/" + REGION + "/s3/aws4_request," +
// Headers used in sign process
"SignedHeaders=host;content-type;x-amz-server-side-encryption;x-amz-date;x-amz-tagging," +
// 256-bit signature (you must calculate it manually)
// this is an example
"Signature=fe5f80f77d5fa3beca038a248ff027d0445342fe2855ddc963176630326f1024");
// Write the object to S3
// and read the response, if failure
httpConnection.setDoInput(true);
httpConnection.setDoOutput(true);
try(BufferedOutputStream outstream = new BufferedOutputStream(httpConnection.getOutputStream())) {
// Write the file to S3
Files.copy(file, outstream);
} catch(IOException e) {
System.err.println("Cannot send object to bucket " + BUCKET_ENDPOINT + "!");
e.printStackTrace();
httpConnection.disconnect();
return;
}
int responseStatus = httpConnection.getResponseCode();
if (responseStatus == 200) {
// Success
System.out.println(OBJECT_NAME + " uploaded successfully to bucket " + BUCKET_ENDPOINT + "!");
} else {
// Failure
System.out.println(OBJECT_NAME + " upload failed!");
System.out.println("Status " + responseStatus);
System.out.println("Response:");
System.out.println();
try(BufferedReader reader = new BufferedReader(new InputStreamReader(httpConnection.getErrorStream()))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch(IOException e) {
System.err.println("Cannot read from " + BUCKET_ENDPOINT + "!");
e.printStackTrace();
}
}
// Close the connection to S3
httpConnection.disconnect();
}
}
As you can see, you need a lot of manual work to interact with S3 through the REST API, as opposed to using the AWS SDK, especially for authentication.
On the IAM part, I inserted mock values: you must sign the request with AWS Signature Version 4.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论