【问题标题】:Need to upload file on S3 in Java需要用 Java 在 S3 上上传文件
【发布时间】:2014-04-25 11:50:48
【问题描述】:

我最近开始在 AWS 上工作。我目前正在开发上传到 S3 存储的功能。

据我了解,可能有两种方法可以将文件上传到 S3:-

  1. 客户端的文件被上传到我的服务器,我使用我的凭据将该文件上传到 S3 服务器。 [我也可以对客户端隐藏它,因为我不会显示上传详细信息。]

  2. 直接上传到 S3

我能够使用 simple upload api 实现第一种方法,但我想跳过“将上传的文件写入服务器磁盘”部分并将内容直接流式传输到 S3 存储,同时保存在我的数据库中上传详细信息。我也想实现AWS细节的抽象。我该怎么做 ??请帮忙。 提前致谢

【问题讨论】:

标签: jakarta-ee file-upload amazon-web-services upload amazon-s3


【解决方案1】:

我正在使用字节流数组将文件数据写入 S3 对象。

接收上传文件的servlet代码:-

import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import com.src.code.s3.S3FileUploader;

public class FileUploadHandler extends HttpServlet {

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doPost(request, response);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriter out = response.getWriter();

        try{
            List<FileItem> multipartfiledata = new ServletFileUpload(new DiskFileItemFactory()).parseRequest(request);

            //upload to S3
            S3FileUploader s3 = new S3FileUploader();
            String result = s3.fileUploader(multipartfiledata);

            out.print(result);
        } catch(Exception e){
            System.out.println(e.getMessage());
        }
    }
}

将此数据作为 AWS 对象上传的代码:-

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.List;
import java.util.UUID;

import org.apache.commons.fileupload.FileItem;

import com.amazonaws.AmazonClientException;
import com.amazonaws.AmazonServiceException;
import com.amazonaws.auth.ClasspathPropertiesFileCredentialsProvider;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3Client;
import com.amazonaws.services.s3.model.ObjectMetadata;
import com.amazonaws.services.s3.model.PutObjectRequest;
import com.amazonaws.services.s3.model.S3Object;

public class S3FileUploader {


    private static String bucketName     = "***NAME OF YOUR BUCKET***";
    private static String keyName        = "Object-"+UUID.randomUUID();

    public String fileUploader(List<FileItem> fileData) throws IOException {
        AmazonS3 s3 = new AmazonS3Client(new ClasspathPropertiesFileCredentialsProvider());
        String result = "Upload unsuccessfull because ";
        try {

            S3Object s3Object = new S3Object();

            ObjectMetadata omd = new ObjectMetadata();
            omd.setContentType(fileData.get(0).getContentType());
            omd.setContentLength(fileData.get(0).getSize());
            omd.setHeader("filename", fileData.get(0).getName());

            ByteArrayInputStream bis = new ByteArrayInputStream(fileData.get(0).get());

            s3Object.setObjectContent(bis);
            s3.putObject(new PutObjectRequest(bucketName, keyName, bis, omd));
            s3Object.close();

            result = "Uploaded Successfully.";
        } catch (AmazonServiceException ase) {
           System.out.println("Caught an AmazonServiceException, which means your request made it to Amazon S3, but was "
                + "rejected with an error response for some reason.");

           System.out.println("Error Message:    " + ase.getMessage());
           System.out.println("HTTP Status Code: " + ase.getStatusCode());
           System.out.println("AWS Error Code:   " + ase.getErrorCode());
           System.out.println("Error Type:       " + ase.getErrorType());
           System.out.println("Request ID:       " + ase.getRequestId());

           result = result + ase.getMessage();
        } catch (AmazonClientException ace) {
           System.out.println("Caught an AmazonClientException, which means the client encountered an internal error while "
                + "trying to communicate with S3, such as not being able to access the network.");

           result = result + ace.getMessage();
         }catch (Exception e) {
             result = result + e.getMessage();
       }

        return result;
    }
}

注意:- 我正在使用 aws 属性文件获取凭据。

希望这会有所帮助。

【讨论】:

    【解决方案2】:

    尝试使用 POST 对象。您无需编写任何代码即可使用它。在http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-UsingHTTPPOST.html中查看更多详细信息

    如果您不怕 javascript,另一种选择是适用于 S3 的 Javascript SDK。您可以在浏览器中运行它。 http://docs.aws.amazon.com/AWSJavaScriptSDK/latest/frames.html

    预签名的url也可以,你可以在浏览器(通过javascript)或后端生成url,让浏览器直接向S3发送请求。

    【讨论】:

    • 非常感谢@okwap 的回复。我只是有点困惑,如果我应用预签名 URL 方法,用户将能够看到亚马逊 url,对吗??我也不想使用 node.js。
    • 是的。如果您的考虑是安全性,您可以使用一些 POST 对象策略(不是存储桶策略!)。见docs.aws.amazon.com/AmazonS3/latest/API/…
    • 谢谢。就像在this 示例中,在示例策略和表单下声明了表单,表单操作写为
      examplebucket.s3.amazonaws.com" method="post" enctype="multipart/form- data">

      这是不希望的,因为我不想让用户知道我正在使用亚马逊的 AWS。有什么办法吗??
    • 嗯...使用虚域怎么样? docs.aws.amazon.com/AmazonS3/latest/dev/…
    【解决方案3】:

    在 Linux 服务器上创建一个 cfg 文件

    vim ~/.aws/credentials
    
    [default]
    aws_access_key_id=AKIAIRVAQ7MASDFRTY
    aws_secret_access_key=PSIAiFv1Fj/2DySyUQWeCfTyosEoOLwqdmqrRlI
    

    并保存该文件。在 NetBeans 中编写代码。同时添加库:

    httpcore-4.4.9.jar
    aws-java-sdk-s3-1.11.367.j​​ar
    aws-java-sdk-kms-1.11.367.j​​ar
    aws-java-sdk-core-1.11.367.j​​ar
    aws-java-sdk-1.4.0.1.jar
    joda-time-2.8.1.jar
    jmespath-java-1.11.367.j​​ar
    jackson-dataformat-cbor-2.6.7.jar
    jackson-databind-2.6.7.1.jar
    jackson-core-2.6.7.jar
    jackson-annotations-2.6.0.jar
    ion-java-1.0.2.jar
    httpcore-4.3.2.jar
    httpclient-4.5.5.jar
    commons-logging-1.1.3.jar
    commons-codec-1.10.jar

    package tests3;
    
     /**
    *
     * @author ravi.tyagi
    */
    import java.io.File;
    import com.amazonaws.AmazonServiceException;
    import com.amazonaws.auth.DefaultAWSCredentialsProviderChain;
    import com.amazonaws.services.s3.AmazonS3;
    import com.amazonaws.services.s3.AmazonS3Client;
    import com.amazonaws.services.s3.transfer.Download;
    import com.amazonaws.services.s3.transfer.TransferManager;
    import com.amazonaws.services.s3.transfer.TransferManagerBuilder;
    import com.amazonaws.services.s3.transfer.Upload;
    
    public class TestS3 {
    
    
    
    
        public static void main(String[] args) throws Exception {
            String bucketName = "*******BucketName*******";
            String keyName = "recordings/0035db40bb32f4d95f0f23b4514d123g/videos/output/0035db40bb32f4d95f0f23b4514d123g"; // Also the name path from which you want save on S3 without Extension it will be same source file
            String filePath = "/usr/local/WowzaStreamingEngine-4.7.6/content/0035db40bb32f4d95f0f23b4514d123g.mp4";
            try {
                AmazonS3 s3Client = new AmazonS3Client(DefaultAWSCredentialsProviderChain.getInstance());
                TransferManager tm = TransferManagerBuilder.standard().withS3Client(s3Client).build();
                Upload upload = tm.upload(bucketName, keyName, new File(filePath));  
                System.out.println("---****************--->"+s3Client.getUrl(bucketName, "0035db40bb32f4d95f0f23b4514d123g.mp4").toString());
                upload.waitForCompletion();
                System.out.println("---*--->"+s3Client.getUrl(bucketName, "0035db40bb32f4d95f0f23b4514d123g.mp4").toString());
                System.out.println("--**->"+upload.getProgress());
                System.out.println("---***--->"+s3Client.getUrl(bucketName, "0035db40bb32f4d95f0f23b4514d123g.mp4").toString());
                System.out.println("--****->"+upload.getState());
                System.out.println("---*****--->"+s3Client.getUrl(bucketName, "0035db40bb32f4d95f0f23b4514d123g.mp4").toString());
                System.out.println("--******->0");
                System.out.println("Object upload complete");
                System.out.println("--**********-->1");
                tm.shutdownNow();
            } catch (AmazonServiceException e) {
                System.out.println("Exception :- "+e);
            }
            System.out.println("----->2");
    
        }
    
    }
    

    【讨论】:

      【解决方案4】:

      这里你会得到一个简单的 spring boot 项目来上传 s3 桶上的文件。

      您需要从要上传文件的 aws 帐户获取这些凭据。

         aws.s3.access.key =************
         aws.s3.secret.key=**************
         aws.s3.bucket.name=*************
         aws.s3.region=************* 
      

      Please click here for code

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-05-07
        • 2020-04-29
        • 1970-01-01
        • 2017-03-31
        • 1970-01-01
        • 2019-10-31
        • 1970-01-01
        相关资源
        最近更新 更多