chirag
chirag

Reputation: 218

Upload image from url to Amazon S3 using Java SDK

I am trying to upload an image from postimage.org to Amazon S3 bucket using java sdk. I can see that a file is created in s3 bucket at the folder location where I want it to be created. However, the image file is not same as the original image in postimage.org. Infact, it is just an "empty" image file of 11.5 kb.

[Refer my code below]

My code :

    @Test
    void uploadToS3() throws IOException {
        AWSCredentials credentials = new BasicAWSCredentials(KEY, SECRET);
        AmazonS3 amazonS3= AmazonS3ClientBuilder
                .standard()
                .withCredentials(new AWSStaticCredentialsProvider(credentials))
                .withRegion(REGION)
                .build();
        URL imageURL=new URL("https://i.postimg.cc/NMp9ZvMD/4X1.jpg");
        InputStream is = getImageInputStream(imageURL);
        ObjectMetadata metadata = new ObjectMetadata();
        metadata.setContentType("image/jpeg");
        amazonS3.putObject(new PutObjectRequest(MY_BUCKET, "my/folder/path/4X1.jpg",is,metadata));
        is.close();

    }

    // THIS IS A COPIED CODE FROM ANOTHER STACKOVERFLOW QUESTION
    private InputStream getImageInputStream(URL url) throws IOException {


        // This user agent is for if the server wants real humans to visit
        String USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 Safari/537.36";

        // This socket type will allow to set user_agent
        URLConnection con = url.openConnection();

        // Setting the user agent
        con.setRequestProperty("User-Agent", USER_AGENT);

        //Getting content Length
        int contentLength = con.getContentLength();
        System.out.println("\n\n\n\n\n *****************File contentLength = " + contentLength + " bytes ****************\n\n\n\n");


        // Requesting input data from server
        return con.getInputStream();

    }

On debugging, I found out that the "content length" of the image's input stream is -1. What is wrong here? Is there a better way to upload images from URL to S3 Bucket?

Upvotes: 1

Views: 2025

Answers (1)

Clinton Bosch
Clinton Bosch

Reputation: 2589

There are 2 things wrong here, firstly you should get the contentLength of the file using HEAD call as follows:

public static Long getContentLength(String urlStr) {
    Long contentLength = null;
    HttpURLConnection conn = null;
    try {
        URL url = new URL(urlStr);
        conn = (HttpURLConnection) url.openConnection();
        conn.setRequestProperty("User-Agent", "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36");
        conn.setRequestMethod("HEAD");
        contentLength = conn.getContentLengthLong();
        LOG.info("Content length {}", contentLength);
    } catch (Exception e) {
        LOG.info("Error getting content length: {}", e.getMessage());
    } finally {
        if (conn != null) {
            conn.disconnect();
        }
    }
    return contentLength;
}

And then secondly, you must set the content-length header on the S3 metadata when uploading

....
           metadata.setContentLength(getContentLength(fileUrl));
....
 

Upvotes: 3

Related Questions