I have been uploading files from a website quite happily using a combination of Play Framework (1.2.4) with Java and jQuery/javascript.
On the client side I attach a blob object to a FormData object and then send that to my Play Framework controller, which accepts the file. I have written a class UploadImg to upload this file to Amazon S3. I then initiate the class by passing in a File object and filename (which is a String), and call the doUpload() method:
public static void myController(File f){
UploadImg imgToUpload = new UploadImg(File file, String filename);
imgToUpload.doUpload();
// ...
I now have a bunch of images on my desktop and I writing a 'bulk uploader'. I did something lik:
File img = new File("/pics/Repin 301.jpg");
UploadImg fileToUpload = new UploadImg(img);
fileToUpload.doUpload()
But I get an error telling me that my input is null.
The path /pics/ doesn't look like it would point to your desktop, if pics is relative to where you are running the app from then drop the leading slash.
Try this to confirm the file is being found:
File img = new File("/pics/Repin 301.jpg");
if(img.exists()) {
UploadImg fileToUpload = new UploadImg(img);
fileToUpload.doUpload()
}else{
System.out.println("File not found");
}
Related
I'm trying to develop a Java program which retrieves a file from the Google Drive and try to reupload it "as is". However, during that process, It loses the format.
Here is how I retrive the file:
private static java.io.File downloadFile(File uploadedFile)
throws IOException {
java.io.File downloadedFile = new java.io.File(parentDir, uploadedFile.getTitle() + UUID.randomUUID().toString());
try (OutputStream out = new FileOutputStream(downloadedFile)) {
drive.files().export(uploadedFile.getId(), "text/html").executeMediaAndDownloadTo(out);
}
return downloadedFile;
}
Here is how I update the file:
private static File updateFile(Drive service, String fileId, File file, java.io.File newContent) throws IOException {
FileContent mediaContent = new FileContent("text/html", newContent);
return service.files().update(fileId, file, mediaContent).execute();
}
And here is how I combine those methods (pretty dummy):
java.io.File downloaded = downloadFile(files.get(0));
updateFile(drive, files.get(0).getId(), files.get(0), downloaded);
This is the file before and after:
The process is fine when I export & re-import the Google file as RTF or PDF, but I really need an editable format. Did I miss something?
This is the expected outcome. PDFs are one way of ensuring the formats are preserved. For Google Docs, not so much.
I am trying to open a Pdf file from the local storage with pdf.js in java, but it seems like I am passing the pdf path in wrong format, or the Pdf.js only supporting opening a file when it is inside the project.
Wondering if anyone can help...
WebEngine engine = webView.getEngine();
File file = new File("C:\Users\User\AppData\Local\filename.pdf");
String pdfViewer = PdfWebViewController.class.getResource("web/viewer.html").toString();
engine.setJavaScriptEnabled(true);
engine.load(pdfViewer);
// listener to determine if the page has been loaded
engine.setOnStatusChanged((WebEvent<String> status) -> {
String s = status.getData();
if (s != null && s.equals("done")) {
//This line should call the open pdf file function in Javascript file
engine.executeScript("PDFViewerApplication.open('" + file.getAbsolutePath() + "');");
}
});
I don't get it - I'm trying to get the path of a file so that the file (an image) can be included as an attachment in an email.
My system consists of two parts - a web app and a jar. (actually three parts - a common shared jar containing DAOs etc.)
They're both built using maven.
They both contain this image in this path:
src/main/resources/logo_48.png
WebApp:
String logo1 = getClass().getClassLoader().getResource("logo_48.png").getPath();
This works perfectly - both on local (Windows) and Linux
Jar Application:
String logo1 = getClass().getClassLoader().getResource("logo_48.png").getPath(); //doesn't work
I've taken advice from here:
How to access resources in JAR file?
here:
Reading a resource file from within jar
here:
http://www.coderanch.com/t/552720/java/java/access-text-file-JAR
and others
Most answers offer to load the file as a stream etc. but I'm only wishing to get the path assigned to the String. Other resources have led me to hacking the code for hours only to find the end result doesn't work.
After so many instances of /home/kalton/daily.jar!logo_48.png does not exist errors I was frustrated and settled on the following workaround:
Copy the logo_48.png directly to the folder where the jar resides (/home/kalton/)
Alter my jar application code to:
String logo1 = "/home/kalton/logo_48.png";
And it works.
Could anyone show me the right way to get the PATH (as a String) of a file in the resources folder from a JAR that is not unpacked?
This issue was driving me crazy for weeks!
Thanks in advance.
KA.
Adding actual use code of 'path' for clarity of use:
public static MimeMultipart assemble4SO(String logoTop, String emailHTMLText) throws MessagingException, IOException {
MimeMultipart content = new MimeMultipart("related");
String cid = Long.toString(System.currentTimeMillis());
String cidB = cid + "b";
String cssStyle = "";
String body = "<html><head>" + cssStyle + "</head><body><div>" + "<img src='cid:" + cid + "'/>" + emailHTMLText + "<img src='cid:" + cidB + "'/></div></body></html>";
MimeBodyPart textPart = new MimeBodyPart();
textPart.setContent(body, "text/html; charset=utf-8");
content.addBodyPart(textPart);
//add an inline image
MimeBodyPart imagePart = new MimeBodyPart();
imagePart.attachFile(logoTop);
imagePart.setContentID("<" + cid + ">");
imagePart.setDisposition(MimeBodyPart.INLINE);
content.addBodyPart(imagePart);
.............
From the top…
A .jar file is actually a zip file. A zip file is a single file that acts as an archive. The entries in this archive are not separate files, they're just sequences of compressed bytes within the zip file. They cannot be accessed as individual file names or File objects, ever.
Also important: The getPath method of the URL class does not convert a URL to a file name. It returns the path portion of the URL, which is just the part after the host (and before any query and/or fragment). Many characters are illegal in URLs, and need to be “escaped” using percent encoding, so if you just extract the path directly from a URL, you'll often end up with something containing percent-escapes, which therefore is not a valid file name at all.
Some examples:
String path = "C:\\Program Files";
URL url = new File(path).toURI().toURL();
System.out.println(url); // prints file:/C:/Program%20Files
System.out.println(url.getPath()); // prints /C:/Program%20Files
File file = new File(url.getPath());
System.out.println(file.exists()); // prints false, because
// "Program%20Files" ≠ "Program Files"
String path = "C:\\Users\\VGR\\Documents\\résumé.txt";
URL url = new File(path).toURI().toURL();
// Prints file:/C:/Users/VGR/Documents/r%C3%A9sum%C3%A9.txt
System.out.println(url);
// Prints /C:/Users/VGR/Documents/r%C3%A9sum%C3%A9.txt
System.out.println(url.getPath());
File file = new File(url.getPath());
System.out.println(file.exists()); // prints false, because
// "r%C3%A9sum%C3%A9.txt" ≠ "résumé.txt"
Based on your edit, I see that the real reason you want a String is so you can call MimeBodyPart.attachFile. You have two options:
Do the work of attachFile yourself:
URL logo = getClass().getLoader().getResource("logo_48.png");
imagePart.setDataHandler(new DataHandler(logo));
imagePart.setDisposition(Part.ATTACHMENT);
Copy the resource to a temporary file, then pass that file:
Path logoFile = Files.createTempFile("logo", ".png");
try (InputStream stream =
getClass().getLoader().getResourceAsStream("logo_48.png")) {
Files.copy(stream, logoFile, StandardCopyOption.REPLACE_EXISTING);
}
imagePart.attachFile(logoFile.toFile());
As you can see, the first option is easier. The second option also would require cleaning up your temporary file, but you don't want to do that until you've sent off your message, which probably requires making use of a TransportListener.
I'm developing a java based application using NetBeans.
What i want to do:
My project folder includes a resources folder which contains all the Images that are needed by the project for basic stuff (setting background,icons etc).
Now suppose end user wants to save an new Image on the run time. File Chooser opens up. User selects a source(.jpg) file and the image gets copied. What i want is, to save this image to my resources folder rather than on LocalDisk path. I'm having no trouble copying this image to a LocalDisk path.
Is there any way through which i can do this?
My resource folder path is:
(ProjectName)\src\resources
Code I'm using to save image to Local Address:
InputStream input = null;
OutputStream output = null;
String fileName = itemId.getText();
try
{
input = new FileInputStream(srcPath.getText()); //Getting Source File Absolute Path Through FileChooser
output = new FileOutputStream("C:\\Users\\BUN\\Documents\\Folder\\"+fileName+".jpg");
byte[] buf = new byte[1024];
int bytesRead;
while((bytesRead = input.read(buf))>0)
{
output.write(buf,0,bytesRead);
}
}
catch(IOException ex)
{
ex.printStackTrace();
}
Thank's in advance!
I am familiar with AWS Java SDK, I also tried to browse the corresponding Javadoc, but I could not realize how do I create a sub directory, i.e., a directory object within a bucket, and how do I upload files to it.
Assume bucketName and dirName correspond to already existing bucket (with public permission) and a new (object) directory which needs to be created within the bucket (i.e. bucketName/dirName/)
I have tried the following:
AmazonS3Client s3 = new AmazonS3Client(
new BasicAWSCredentials(ACCESS_KEY, SECRET_KEY));
s3.createBucket(bucketName + "/" + dirName); //throws exception
which throws an exception on the second line.
A short snippet which creates a sub-directory and uploads files to it will be deeply appreciated.
There are no "sub-directories" in S3. There are buckets and there are keys within buckets.
You can emulate traditional directories by using prefix searches. For example, you can store the following keys in a bucket:
foo/bar1
foo/bar2
foo/bar3
blah/baz1
blah/baz2
and then do a prefix search for foo/ and you will get back:
foo/bar1
foo/bar2
foo/bar3
See AmazonS3.listObjects for more details.
Update: Assuming you already have an existing bucket, the key under that bucket would contain the /:
s3.putObject("someBucket", "foo/bar1", file1);
s3.putObject("someBucket", "foo/bar2", file2);
...
Then you can list all keys starting with foo/:
ObjectListing listing = s3.listObjects("someBucket", "foo/");
S3 doesn't see directories in the traditional way we do this on our operating systems.
Here is how you can create a directory:
public static void createFolder(String bucketName, String folderName, AmazonS3 client) {
// create meta-data for your folder and set content-length to 0
ObjectMetadata metadata = new ObjectMetadata();
metadata.setContentLength(0);
// create empty content
InputStream emptyContent = new ByteArrayInputStream(new byte[0]);
// create a PutObjectRequest passing the folder name suffixed by /
PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName,
folderName + SUFFIX, emptyContent, metadata);
// send request to S3 to create folder
client.putObject(putObjectRequest);
}
As casablanca already said you can upload files to directories like this:
s3.putObject("someBucket", "foo/bar1", file1);
Read the whole tutorial here for details, and the most important thing is you will find info how to delete the directories.
In newer versions of the SDK, you can do something like this (no need to create empty InputStream) to create an empty folder:
String key = parentKey + newFolderName;
if (!StringUtils.endsWith(key, "/")) {
key += "/";
}
PutObjectRequest putRequest = PutObjectRequest.builder()
.bucket(parent.getBucket())
.key(key)
.acl("public-read")
.build();
s3Client.putObject(putRequest, RequestBody.empty());
Leaving this answer here just in case someone stumbles upon this. I have been using aws sdk version - 1.11.875 and the following successfully created a folder for me when trying to upload a file into S3 bucket. I did not have to explicitly create the folder as mentioned in the earlier answer.
private void uploadFileToS3Bucket(final String bucketName, final File file) {
final String fileName = "parent/child/" + file.getName();
final PutObjectRequest putObjectRequest = new PutObjectRequest(bucketName, fileName, file);
amazonS3.putObject(putObjectRequest);
}
This will create the parent and parent/child folders in the specified S3 bucket and upload the file into child folder.
This worked for me. I used spring boot and file uploaded according to Multipart mechanism. I wanted to save my images inside the photos folder in my aws s3 bucket. My need is save like this photos/mypic.jpg
----controller class method----
#PostMapping("/uploadFile")
public String uploadFile(#RequestPart(value = "file") MultipartFile file) throws IOException {
return this.amazonClient.uploadFile(file);
}
----service class (Implementation of controller)----
public String uploadFile(MultipartFile multipartFile) throws IOException {
try {
File file = convertMultiPartToFile(multipartFile);
String fileName = "photoes/"+generateFileName(multipartFile); //here give any folder name you want
uploadFileTos3bucket(fileName, file);
} catch (AmazonServiceException ase) {
logger.info("Caught an AmazonServiceException from GET requests, rejected reasons:");
}
return fileName;
}
The point is concatenate the folder name you want as prefix of the fileName
additionally I will show you how to delete folder. The point is give the folder name as the keyName(key name is uploaded object name in the s3 bucket.). I will show code snippet also.
----controller class method----
#DeleteMapping("/deleteFile")
public String deleteFile(#RequestPart(value = "keyName") String keyName) {
return this.amazonClient.deleteFile(keyName);
}
----service class (Implementation of controller)----
public String deleteFile(String keyName){
try {
s3client.deleteObject(new DeleteObjectRequest(bucketName, keyName));
} catch (SdkClientException e) {
e.printStackTrace();
}
return "deleted file successfully!";
}
for delete photos folder that we created , call method like this. deleteFile("photos/")
important:- / is mandatory
if You want to create folder then you need to use put command using following keys to create folder1 in:
in root of bucket -> folder1/folder1_$folder$
in path folder2/folder3/ -> folder2/folder3/folder1/folder1_$folder$
It is always all_previous_folders/folderName/folderName_$folder$