Reputation: 218
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
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