1

I am trying to upload file to aws-s3 bucket using spring mvc rest api. Here is my credentials format to access s3 bucket

[default]
aws_access_key_id = Access key id
aws_secret_access_key = secret access key

Here is my Java code:

@RestController
public class UploadController {

private static String bucketName= "mp4-upload-1";
private static String keyName= "secret access key";
public static final Logger logger=LogManager.getLogger(UploadController.class);

@RequestMapping(value="/uploadVideo", method = RequestMethod.POST, consumes=MediaType.MULTIPART_FORM_DATA_VALUE)
public ResponseEntity<String> uploadVideo(@RequestParam("file") MultipartFile file) throws IOException {


    AmazonS3 s3client = new AmazonS3Client(new ProfileCredentialsProvider());
    try {
        System.out.println("Uploading a new object to S3 from a file\n");

        InputStream is=file.getInputStream();

        s3client.putObject(new PutObjectRequest(bucketName, keyName,is,new ObjectMetadata()).withCannedAcl(CannedAccessControlList.PublicRead));


    } 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());
    } 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.");
        System.out.println("Error Message: " + ace.getMessage());
    }
    return new ResponseEntity<>(HttpStatus.OK);

}

}

The problem is I am not getting any error but file is not uploading to s3-bucket. am I missing anything here? Thanks in advance

Mohammad Hasan
  • 123
  • 1
  • 6
  • 22
  • 2
    Are they your real credentials? I suggest you remove them immediately. – realharry Nov 17 '17 at 05:31
  • do not just remove it, disable that key. As usually people have some custom scripts that looks for AWS Credentials, and will spin up lots of EC2 instances. – ian1095 Nov 17 '17 at 05:34
  • Remove the credentials from here and generate a new key (don't share that elsewhere). SO can still look into the issue without requiring the credentials – Balwinder Singh Nov 17 '17 at 05:35
  • This is not real credentials however edited..thanks for informing me... – Mohammad Hasan Nov 17 '17 at 05:38
  • use multipart upload method http://docs.aws.amazon.com/AmazonS3/latest/dev/llJavaUploadFile.html – R. S. Nov 17 '17 at 05:47
  • @ AntiCode the problem is how can I get filepath..since I am using postman to send form data..so how can i get file path location from postman request? – Mohammad Hasan Nov 17 '17 at 05:51

1 Answers1

1

The content length should be specified on the request when the stream is uploaded directly to S3.

ObjectMetadata objMetadata = new ObjectMetadata()
objMetadata.setContentLength(20L);

When uploading directly from an input stream, content length must be specified before data can be uploaded to Amazon S3. If not provided, the library will have to buffer the contents of the input stream in order to calculate it. Amazon S3 explicitly requires that the content length be sent in the request headers before any of the data is sent.

Refer this for content length calculation

Alternate Approach:-

Use org.springframework.util.FileCopyUtils.copyToByteArray() to convert the stream to byte[] and upload the byte array to S3.

notionquest
  • 37,595
  • 6
  • 111
  • 105
  • Hi My code is working now. The problem was I placed the credentials in wrong placed. However, This time I have created IAM user and get access_key_id and secret_access_key and then managed this credentials inside code rather than put in the home directory. Anyway thanks for your suggestion. – Mohammad Hasan Nov 21 '17 at 01:19
  • I have gone different approach, but your suggestion is working too. – Mohammad Hasan Jun 13 '19 at 15:48