Amazon S3 file upload fail using Java - java

How to store a file in Amazon S3 using jsp page ????
I used FileInputstream but it doesn't work. Please give any suggestion about jsp code.
try
{
String bucketName = "phr12345";
File file=new File("a.txt");
String key = "ads/" + file.getName();
s3.putObject(bucketName, key, file);
out.println("file uploaded !!!!!!");
}
catch(IOException e)
{
e.printStackTrace();
}

Related

Spring Boot + AWS S3: Unable to delete files in the bucket

i am new to AWS, and my first module i try to learn is S3 for file storage.
Uploading works fine, the problem is with deleting.So when i upload a file i store the string version of the name of the file in AWS bucket mybucket and the whole URL in mysql database like this
-> https://mybucket.s3.eu-west-2.amazonaws.com/what.png
The problem with deleting is that even if i pass the whole URL in this case https://mybucket.s3.eu-west-2.amazonaws.com/what.png to the delete method, the method goes to each steps successfully, telling me that the file has been succesfully deleted but when i check the bucket, the file is still there.I have tried searching around here for a similar issue, but couldn't find something that could help me understand what the problem is.here is the code
#Service
public class AmazonS3ClientServiceImpl {
private String awsS3AudioBucket; //bucket name
private AmazonS3 amazonS3; // s3 object which uploads file
private static final Logger logger = LoggerFactory.getLogger(AmazonS3ClientServiceImpl.class);
#Autowired
public AmazonS3ClientServiceImpl(Region awsRegion, AWSCredentialsProvider awsCredentialsProvider, String awsS3AudioBucket) {
this.amazonS3 = AmazonS3ClientBuilder.standard()
.withCredentials(awsCredentialsProvider)
.withRegion(awsRegion.getName()).build();
this.awsS3AudioBucket = awsS3AudioBucket;
}
public String uploadFileToS3Bucket(MultipartFile multipartFile, boolean enablePublicReadAccess) {
String uploadedfile = ""; // the file path which is on s3
String fileName = multipartFile.getOriginalFilename();
try {
//creating the file in the server (temporarily)
File file = new File(fileName);
FileOutputStream fos = new FileOutputStream(file);
fos.write(multipartFile.getBytes());
fos.close();
PutObjectRequest putObjectRequest = new PutObjectRequest(this.awsS3AudioBucket, fileName, file);
if (enablePublicReadAccess) {
putObjectRequest.withCannedAcl(CannedAccessControlList.PublicRead);
}
this.amazonS3.putObject(putObjectRequest);
uploadedfile = String.valueOf(this.amazonS3.getUrl(awsS3AudioBucket, fileName));
System.out.println(this.amazonS3.getUrl(awsS3AudioBucket, fileName));
System.out.println(uploadedfile);
//removing the file created in the server
file.delete();
} catch (IOException | AmazonServiceException ex) {
logger.error("error [" + ex.getMessage() + "] occurred while uploading [" + fileName + "] ");
}
return uploadedfile;
}
public void deleteFileFromS3Bucket(String fileName) {
LOGGER.info("Deleting file with name= " + fileName);
final DeleteObjectRequest deleteObjectRequest = new DeleteObjectRequest(this.awsS3AudioBucket, fileName);
amazonS3.deleteObject(deleteObjectRequest);
LOGGER.info("File deleted successfully");
}
and when i call the deletemethod i use this
#GetMapping("/dashboard/showposts/delete/{id}")
public String deletePost(#PathVariable("id") Long id, Model model) {
System.out.println("GOT HERE");
//Retrieving Post image name
Post post = postService.findBydId(id);
String imageName = post.getImage();
System.out.println(imageName);
//Deleting image from S3 bucket
amazonClient.deleteFileFromS3Bucket(imageName);
//Deleting post from db
postService.detelePost(id);
String success = "Successfully deleted post with Id" + id;
model.addAttribute("success", success);
return "redirect:/admin/dashboard/showposts";
}
Any help would be greatly appreciated.
L.E For anyone having the same issue and searching for a quick answer.You have to pass only the string image name to the delete method not the whole URL.
You aren't checking the response returned from amazonS3.deleteObject() to see if it was actually successful or not. It is probably returning a failure status.
I'm guessing the root issue is that you are passing the full URL to the delete method, instead of just the path to the file within S3. For example with this URL: https://mybucket.s3.eu-west-2.amazonaws.com/what.png the S3 object path is simply what.png.
The simplest answer is to use the URL class. Something like:
URL url = null;
try {
url = new URL("https://mybucket.s3.eu-west-2.amazonaws.com/some/path/what.png");
} catch (MalformedURLException e) {
e.printStackTrace();
}
System.out.println( "file is \""+ url.getFile() + "\"" );
output would be "/some/path/what.png". You can remove the first "/" character to use for the key.
Aws S3 is eventual consistent. You might delete object and s3 list that object in browser . So it take few seconds or less to delete .
Please refer this link

Writing uploaded files with non-ASCII file names to disk from Java servlet

I have a servlet that writes uploaded files to disk, using Apache Commons fileupload. That's all working fine in general.
It runs on both Windows and Linux servers using Tomcat. On Windows it handles files with non-ASCII file names correctly and the files are saved properly.
On Linux (CentOS 6) however the file names are not saved correctly when containing non-ASCII characters.
If have tried three different versions of writing the file. In Windows all work, in Linux none do but they produce different results.
Version 1:
String fileName = URLDecoder.decode(encFilename, "UTF-8");
String filePath = uploadFolder + File.separator + fileName;
File uploadedFile = new File(filePath);
item.write(uploadedFile);
Version 2:
String fileName = URLDecoder.decode(encFilename, "UTF-8");
String filePath = uploadFolder + File.separator + fileName;
File uploadedFile = new File(filePath);
InputStream input = item.getInputStream();
try {
Files.copy(input, uploadedFile.toPath());
} catch (Exception e) {
log.error("Error writing file to disk: " + e.getMessage());
} finally {
input.close();
}
Uploading a file called: Это тестовый файл.txt I get the following results on Linux:
Version 1: A file named: ??? ???????? ????.txt
Version 2: Error writing file to disk: Malformed input or input contains unmappable characters: /tmp/Это тестовый файл.txt
While on a Windows machine with Tomcat 7 and Java 7 the file name is written correctly as Это тестовый файл.txt
A third version uses the approach from this post and doesn't use FileUpload. The result is the same as what's produced by version 2.
Version 3:
Part filePart = request.getPart("file");
String fileName = "";
for (String cd : filePart.getHeader("content-disposition").split(";")) {
if (cd.trim().startsWith("filename")) {
fileName = cd.substring(cd.indexOf('=') + 1).trim().replace("\"", "");
fileName = fileName.substring(fileName.lastIndexOf('/') + 1).substring(fileName.lastIndexOf('\\') + 1); // MSIE fix.
}
}
String filePath = uploadFolder + File.separator + fileName;
File uploadedFile = new File(filePath);
InputStream input = filePart.getInputStream();
try {
Files.copy(input, uploadedFile.toPath());
} catch (Exception e) {
log.error("Error writing file to disk: " + e.getMessage());
} finally {
input.close();
}
Tomcat is running with -Dfile.encoding=UTF-8 and locale shows LANG=en_US.UTF-8
touch "Это тестовый файл.txt" produces a file with that name.
The file contents are always written correctly. (except of course where no file is written at all).
What am I missing or doing wrong?
I solved the problem by converting all use of java.io.File to java.nio.Files and java.nio.Path. So it seems the java.io.File api is buggy. Using this it works fine on both Windows and Linux.
// The filename is passed as a URLencoded string
String fileName = URLDecoder.decode(request.getParameter("fileName"), "UTF-8");
Path filePath = Paths.get(uploadFolder, fileName);
Part filePart = request.getPart("file");
InputStream input = filePart.getInputStream();
try {
Files.copy(input, filePath);
} catch (Exception e) {
log.error("Error writing file to disk: " + e.getMessage());
} finally {
input.close();
}
I ran into the same problem in several other parts of the app that worked with the uploaded files and in all cases getting rid of java.io.File and using java.nio instead solved the problem.

Is there a way to upload file to Google Drive from InputStream in Drive SDK?

I have to load some data to Google Drive, but I can't use recommended by Drive SDK way to do it:
FileContent fileContent = new FileContent(mimeType, dataFile);
try {
File file = service.files().insert(body, fileContent).execute();
return file;
} catch (IOException e) {
System.out.println("An error occured: " + e);
return null;
}
because my data isn't always has the java.io.File as a source. Sometimes it may be an InputStream from encrypted storage or from other cloud storage and therefore I can't get FileContent from it. Is there a way to load data from InputStream to Google Drive without their intermediate storing on file system (as for Dropbox API method "putFileOverwrite", for example)?
Check this out
File file= drive.files().insert(body,
new InputStreamContent(
fileItemStream
.getContentType(),
new ByteArrayInputStream(
IOUtils.toByteArray(fileInputStream)))).execute;

How to create a folder and write a simple .txt file in that folder on Internal Storage on Android

I cant seem to get the following code to work; i've tried diffrent methods but none work, i wanna create a folder int he internal storage and a create and write to a simple .txt file within that folder. Can someone please provide a robust example of how to do it, and show me what i'm getting wrong
String DataIn = PhoneNumber + "," + dataLong + "," + dataLat;
FileOutputStream outputStream;
String filename = "LegionData";
try {
outputStream = openFileOutput(filename, Context.MODE_PRIVATE);
outputStream.write(DataIn.getBytes());
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
Try this
String filename = "myfile";
File file = new File(context.getFilesDir(), filename);

Control Uploaded file types (only specific extension can be uploaded)

i have a stupid question here i'm implementing upload button with vaadin and i want the users to upload only compressed files (.zip,.rar..), imake a search but i didn't find something useful :
so i tried to do this , i know it's not good solution because the user already uploaded the selected file :
#Override
public OutputStream receiveUpload(String filename, String mimeType) {
// Create upload stream
FileOutputStream fos = null; // Stream to write to
String fileName ;
String userHome = System.getProperty( "user.home" );
try {
// Open the file for writing.
file = new File(userHome+"/kopiMap/runtime/uploads/report/" + filename);
fileName= file.getName();
//Here i will get file extension
fos = new FileOutputStream(file);
} catch (final java.io.FileNotFoundException e) {
Notification.show(
"Could not open file<br/>", e.getMessage(),
Notification.TYPE_ERROR_MESSAGE);
return null;
}
return fos; // Return the output stream to write to
}
So how to do it before uploading
you can check the mimeType and if it is application/zip
#Override
public OutputStream receiveUpload(String filename, String mimeType) {
// Create upload stream
if(mimeType.equals("application/zip"))
//Here you can restrict
You can add this and it will work (all done by HTML 5 and most browser support now accept attribute) - this is example for .csv files:
upload.setButtonCaption("Import");
JavaScript.getCurrent().execute("document.getElementsByClassName('gwt-FileUpload')[0].setAttribute('accept', '.csv')");

Categories