2

When I try to upload content to an Amazon S3 bucket, I get an AmazonClientException: Data read has a different length than the expected.

Here is my code.

 public Object uploadFile(MultipartFile file) {
        String fileName = System.currentTimeMillis() + "_" + file.getOriginalFilename();
        log.info("uploadFile-> starting file upload " + fileName);

        Path path = Paths.get(file.getOriginalFilename());
        File fileObj = new File(file.getOriginalFilename());

        try (FileOutputStream os = new FileOutputStream(fileObj)) {
            os.write(file.getBytes());
            os.close();
            String uploadFilePath = bucketName + "/" + uploadPath;
            s3Client.putObject(new PutObjectRequest(uploadFilePath, fileName, fileObj));
            Files.delete(path);
        } catch (IOException ex) {
            log.error("error [" + ex.getMessage() + "] occurred while uploading [" + fileName + "] ");
        }
        log.info("uploadFile-> file uploaded process completed at: " + LocalDateTime.now() + " for - " + fileName);
        return "File uploaded : " + fileName;
    }
smac2020
  • 9,637
  • 4
  • 24
  • 38
R M
  • 69
  • 1
  • 7

2 Answers2

1

Amazon recommends using the Amazon S3 Java V2 API over use of V1.

The AWS SDK for Java 2.x is a major rewrite of the version 1.x code base. It’s built on top of Java 8+ and adds several frequently requested features. These include support for non-blocking I/O and the ability to plug in a different HTTP implementation at run time.

To upload content to an Amazon S3 bucket, use this V2 code.

public static String putS3Object(S3Client s3,
                                     String bucketName,
                                     String objectKey,
                                     String objectPath) {

        try {

            Map<String, String> metadata = new HashMap<>();
            metadata.put("myVal", "test");

            PutObjectRequest putOb = PutObjectRequest.builder()
                    .bucket(bucketName)
                    .key(objectKey)
                    .metadata(metadata)
                    .build();

            PutObjectResponse response = s3.putObject(putOb,
                    RequestBody.fromBytes(getObjectFile(objectPath)));

           return response.eTag();

        } catch (S3Exception e) {
            System.err.println(e.getMessage());
            System.exit(1);
        }
        return "";
    }

Full example here.

If you are not familiar with V2, please refer to this doc topic:

https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html

smac2020
  • 9,637
  • 4
  • 24
  • 38
  • Hey for v2 how to do STSAssumeRoleSessionCredentialsProvider ? with roleSessionName and roleArn – R M Apr 26 '21 at 18:44
  • https://stackoverflow.com/questions/67272319/how-to-configure-using-stsassumerolesessioncredentialsprovider-with-rolesessionn – R M Apr 26 '21 at 19:09
0

AWS Java SDK 1.x

s3.putObject(bucketName, key, new File(filePath));

AWS Java SDK 2.X

PutObjectRequest putObjectRequest = PutObjectRequest
  .builder()
  .bucket(bucketName)
  .key(key)
  .build();

s3Client.putObject(putObjectRequest, Paths.get(filePath));
GSSwain
  • 5,787
  • 2
  • 19
  • 24
  • Hey for v2 how to do STSAssumeRoleSessionCredentialsProvider ? with roleSessionName and roleArn – R M Apr 26 '21 at 18:45
  • https://stackoverflow.com/questions/67272319/how-to-configure-using-stsassumerolesessioncredentialsprovider-with-rolesessionn – R M Apr 26 '21 at 19:09
  • @RM You need to use StsAssumeRoleCredentialsProvider in v2. Answered in the question. – GSSwain Apr 26 '21 at 22:53