Upload file to Amazon S3 without SDK: 将文件上传到Amazon S3而无需使用SDK。

huangapple go评论50阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2023年5月18日 12:42:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/76277792.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定