【问题标题】:How do I directly stream a multipart file as inputstream to AWS S3 in Java?如何在 Java 中将多部分文件作为输入流直接流式传输到 AWS S3?
【发布时间】:2018-04-11 22:53:51
【问题描述】:

现在我的代码获取 MultipartFile 并转换为 java.util.File 并上传到 S3。

try {
    final ObjectMetadata objectMetadata = new ObjectMetadata();
    objectMetadata.setContentType(file.getContentType());
    byte[] contentBytes = null;
    try {
        final InputStream is = file.getInputStream();
        contentBytes = IOUtils.toByteArray(is);
    } catch (final IOException e) {
        log.error("Failed while reading bytes from %s" + e.getMessage());
    }

    final Long contentLength = Long.valueOf(contentBytes.length);
    objectMetadata.setContentLength(contentLength);
    objectMetadata.setHeader("filename", fileNameWithExtn);

    /*
     * Reobtain the tmp uploaded file as input stream
     */
    final InputStream inputStream = file.getInputStream();

    final File convFile = new File(fileNameWithExtn);
    file.transferTo(convFile);

    FileUtils.copyInputStreamToFile(inputStream, convFile);
    try {
        final AmazonS3 s3Client = AmazonS3ClientBuilder.standard().build();
        versionId = s3Client.putObject(new PutObjectRequest("bucketName", name, convFile))
                .getVersionId();
    } catch (final 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());
    } catch (final 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.");
        System.out.println("Error Message: " + ace.getMessage());
    }
} catch (final Exception e) {
    log.error("You failed to upload " + name + " => " + e.getMessage());
}

我不想这样做的原因是,在我的桌面上,我在浏览器中上传的图像暂时停留在 tomcat 服务器中,然后它被上传到 S3。

但是当我的 webapp 在 Ec2 中运行时,由于权限问题(或其他原因),从浏览器上传的图像似乎没有留在 tomcat 服务器中。因此整个图像上传失败。

我尝试了本文Converting MultipartFile to java.io.File without copying to local machine 中提供的解决方案,但运气不佳。

有人可以指导我使用代码将多部分文件直接流式传输到 S3 吗?

【问题讨论】:

    标签: java amazon-web-services tomcat amazon-s3 amazon-ec2


    【解决方案1】:

    在 jsp 的表单标签中确保你写 enctype="multipart/form-data"。并在 servlet 之后声明以下代码

    @WebServlet(name = "ServletName", urlPatterns = {"/ServletName"})

     @MultipartConfig(fileSizeThreshold=1024*1024*10,  // 10 MB (You can specify according to your choice)
                     maxFileSize=1024*1024*50,       // 50 MB  (You can specify according to your choice)
                     maxRequestSize=1024*1024*100)
    

    您可以在servlet中编写以下代码,以inputStream的形式获取文件并上传到S3。

        Part filePart=  request.getPart("FileName"); // The name of <input type=file name="FileName"> in jsp form. Here, FileName 
    
     try {
    
                        InputStream inputStream=null;
    
                        if(filePart!=null){
    
                        inputStream=filePart.getInputStream();   //get file in form of inputstream
    
    
                                          }
    
              ObjectMetadata md = new ObjectMetadata();
              md.setContentLength(filePart.getSize());
              md.setContentType(filePart.getContentType());
    
            try {
            final AmazonS3 s3Client = AmazonS3ClientBuilder.standard().build();
            versionId = s3Client.putObject(new PutObjectRequest("bucketName", name, inputStream,md))
                    .getVersionId();
                } catch (final 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());
        } catch (final 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.");
            System.out.println("Error Message: " + ace.getMessage());
        }
    } catch (final Exception e) {
        log.error("You failed to upload " + name + " => " + e.getMessage());
    }
    

    【讨论】:

    • 我不认为有一个带有三个参数的 PutObjectRequest 构造函数
    猜你喜欢
    • 2013-11-14
    • 1970-01-01
    • 2014-12-06
    • 2017-12-29
    • 2012-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多