I know the title is probably a common question, but I am a bit confused on everything I'm trying to do, so I am trying to piece it together, and figured a common title would be better than a confusing one.
I am basically developing a web application and one part of that is a file uploader. I am using Apache Commons File Upload via the Streaming API, and that all works fine, except I need to access the file I'm uploading, because that contains data to additional files to upload. I.e., Read File A, get paths to images, upload images with File A to server and save on server. The API can be found here http://commons.apache.org/proper/commons-fileupload/streaming.html
I was told there is a security risk via the web and would be impossible via a browser, since the user needs to select all files to upload, i cannot tell the browser to upload additional files, so I am left with a client side option.
I am confused if there is a special library I need, or as I have been seeing threads that talk about using the built in UrlConnection Class or http://hc.apache.org/
I basically need to be able to read the file, which technically gives me a path to a Database on the user's system which I then read to get the additional images. After I get all of that I then need to post the data as a multipart form as that is what the FileUpload requires.
form method="POST" enctype="multipart/form-data" action="fup.cgi">
File to upload: <input type="file" name="upfile"><br/>
Notes about the file: <input type="text" name="note"><br/>
<br/>
<input type="submit" value="Press"> to upload the file!
</form>
This is the example found in the Overview section of the Fileupload which can be accessed from the link above.
There wouldn't be an issue if the users uploaded all of the data themselves, but since I have to do some of it automatically it causes some "concerns/issues."
Basically these files are created and packaged from another application, so the images, and the db will always be in the same place, and that file that they are uploading is a file the other program creates, so everything will always be known, I just need to upload it, and then POST it as enctype="multipart/form-data" So that my servlet can read it and save it on my server.
So I would appreciate it if anyone had any suggestions on where to begin my journey with this. I have heard of a few applications like curl and wget that are used for this, but those seem to be more C based. As mentioned earlier it seeems the httpcomponets from apache might work well, but I want to make sure.
Related
Context
My application enables users to upload an .mp4 file to Google Cloud Storage through Google App Engine using the createUploadUrl() pattern. The upload works fine and I'm able to obtain the corresponding FileInfo object in the handler. I'm using the App Engine SDK 1.8.2 for Java.
The Challenge
I need to grab the "duration" property off of the .mp4 file and store it in my database but the FileInfo object doesn't provide access to this metadata. I have a few ideas on how I might go about doing this (which I've listed below) but none of them are very straightforward given that the project I'm working on has several legacy dependencies.
I'd love to hear any ideas or suggestions you have on how to tackle this (and ideally any success stories if you have!)
Ideas
I know that there are scripts and utilities like ffmpeg and mdls (for mac) that can read metadata off of the file but my understanding is that these wouldn't be able to run in Google App Engine and I would need to kick off separate processes using something like Google Compute Engine.
I could create a custom flash upload control that reads the duration logic when the user selects the file for upload and passes it in through standard form submission.
I'm also aware that there's a Google Cloud Storage JSON API that's been in Beta stage now. I don't see any functionality that would allow me to read the "duration" property off of the .mp4 file but I may be missing something...
Code
HTML Form
<form name="myForm" id="myForm" action="<%=createUploadUrl("/upload, uploadOptions)%>" method="POST" enctype="multipart/form-data">
<input type="file" name="uploadFileControl" id="uploadFileControl" value="Select...">
<input type="submit" value="Submit">
</form>
Server Side Handler
DAO dao = new DAO();
BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
Map<String, List<FileInfo>> fileInfos = blobstoreService.getFileInfos(req);
List<FileInfo> uploadedFile = fileInfos.get("uploadFileControl");
if(uploadedFile != null) {
FileInfo file = uploadedFile.get(0);
String fileName = file.getFilename();
}
Google Cloud Storage is content-type agnostic, i.e., it treats any kind of content in the same way (videos, music, zip files, documents, you name it). It also doesn't parse or "read" uploaded content (which is encrypted at REST anyway). Because of that Google Cloud Storage can't possibly know about the specifics of a given file format like mp4, hence you won't find any such functionality in the APIs. I am assuming the same holds for AppEngine and its FileInfo object.
You could google "python mp4 parser" and see if anything comes up...
Posting back with the solution I ended up going with.
I used a video player plug-in called mediaelement.js (http://mediaelementjs.com/) to load in the uploaded file from GCS. The video player has a "duration" property that gets updated every time a new video file is loaded which makes the whole thing quite straightforward.
Two other options I was investigating involved 1) using a java utility called mp4parser (https://code.google.com/p/mp4parser/) to load in the uploaded file from Google Cloud Storage into GAE and manually extracting out the duration metadata and 2) updating an open source upload utility called Plupload (http://plupload.com/) to extract out the duration metadata as the file was being uploaded.
Hope this helps anyone else who runs into a similar issue!
It is quite a common question but I can't find an answer to it
I have a simple HTML with an input text box (type=file) and a submit button. On clicking the submit button, I call a js function where I try to get the complete path of the file
var data = $('#fileName').val();
the issue is I am not getting complete file path of the file I am uploading. I know due to security reasons chrome gives me a C:\fakePath\filename and firefox gives me only the fileName. But in case I need a complete path what shall I do?
PS: Further I will make an ajax call and give that file path to the back-end which needs it to read that file using FileReader
You cannot get the complete path! there is no way to do that!! Even though you are on an intranet and you have enough permissions.
A workaround for this is to have a textarea and ask the user to enter the complete path of the file.
In short you can't have the full name of a file once is loaded on server side, you will just have the file name and its content in a raw byte array (among other attributes). This is not a Java thing nor other server side technologies issue, is related to browser implementation (but it looks that IE6 may contain a flaw about this).
Not directly related to your question but caught my attention
PS: Further I will make an ajax call and give that file path to the back-end which needs it to read that file using FileReader
Usually, you can't handle a file upload using ajax because it can lead to security holes. Still, there are some browsers (like Chrome and Firefox) that allows you to send a file using XMLHttpRequest but that isn't allowed on some browsers (like IE8-) so you have to use an iframe in order to make the file ajax uploading work.
In order to avoid handling all these problems, I would advice you to use a third-party js library that handles the ajax file upload. An example is blueimp jQuery file upload that also has Java server side examples (DISCLAIMER: I do not work in this project nor I'm associated with blueimp in any way). Note that using this plugin requires that you have a mid knowledge on HTML/JavaScript/jQuery/Java Server Side so if you're a starter it may take you some time to make it work, but once it does is pretty good.
I dont know which technology you are using.. but you can always get file name once it is uploaded on server (Using php or .net )
your steps to upload should be like below:
1) Upload file to the server (e.z. /uploadedFiles/...filename
2) Create a method which will fetch file name from the uploaded path
3) simply insert file name in to the database (this will give you flexibility to change folder name of uploaded docs in future if required)
Generally filenames are not stored as it is . to avoid name conflict in future. So it is a advisable to always rename your filename by adding minutes & seconds after itsname.
If any doubts do ask.
Hope it helps.
Browsers block the filepath access on javascript for securit reasons.
The behavior makes sense, because the server doesn't have to know where the user stores the file on his computer, it is irrelevant to the upload process.
This was a question about testing file upload functionality using a local java server on Windows 7 platform. Since the question evolved with Marko's input, I have edited it, so that those who run into the same challenge do not waste time on evolution details and reach conclusions sooner.
The challenge was to direct uploaded file to a folder outside of the WAR structure and successfully read it from there. For example: upload an image into c:/tmp/ and then redirect to a confirmation page that displays the image <img src="c:/tmp/test.jpg" />. The upload worked but image would not be displayed. And based on Marko's input, this makes sense because browser sitting at localhost will refuse to load anything from local disk structure using c:. Maybe these are security considerations similar to those with file input control where we cannot set a default path...
The following tag will work in a locally created .html file but when pasted into a jsp, it won't work. And the difference is that browser uses localhost to get to the jsp.
<img src="c:/tmp/test.jpg" />
Solutions
I think that Marko's answer pretty much defines what needs to be done. While I didn't go with that approach, it clearly is the better way to do it and I will accept that as the answer. Thanks, Marko!
For those who don't want to bother installing a Web server and are willing to live with a bit of a hack, here's what I have done. Again, I didn't want to upload files into my WAR structure because I would then need to remember about clearing that folder before deploying to the server. But that upload folder still needs to be accessible, so I simply created another dummy project and put that upload folder under its WebContent. This works for the purposes of my local testing. The only nuisance is that after uploading a file, I need to refresh the dummy project's WebContent in Eclipse.
config.properties
#for uploading files
fileUploadDirectory=C:/javawork/modelsite/tmp/WebContent
#for building html links
publicFileServicePrefix=http://localhost:8080/tmp
<img src="http://localhost:8080/tmp/test.jpg" /> // this works - tmp is the name of my dummy project.
If you are citing literally the HTML that goes to the browser (the one that you access via "vieew source") then this has nothing to do with Java. The browser is the one who interprets these links. If they fail to load, the problem is in the browser/file system.
UPDATE
According to the results of your additional diagnostics, I conclude that the browser (sensibly!) refuses to load anything from your local disk if it is referenced from an HTML file coming from an internet URL, even when that URL is localhost.
UPDATE 2
(Deleted, irrelevant)
UPDATE 3
However you handle the files uploaded to the server, it's definitely not going to look like your solution -- the file is on the server's local filesystem, not client's. This sort of thing can be handled at the Apache HTTP server level -- reserve an URL section for static content and configure Apache with a base directory from which to serve the static content. Even if you run the server locally, on the same machine where you test it, you still need to go through the network interface.
I have often wonder how Facebook is able to handle uploading multiple files on the server when I am uploading my pictures.
I am quite not sure how it is being implemented. As I know, you could only send one file to the server through http one at a time unless you are going to make use of Applets.
Does anybody know how Facebook implements this? Is this Flash or an applet or something?
There's nothing special that you need to do on your web page - multiple <input type="file"> elements in the same <form> will upload multiple files at once.
The tricky part is handling all those files on the server. Take a look at a library such as Apache Commons FileUpload
Edit
You might want to take a look at this thread - people have suggested quite a few readily available components that you can use (note that these are for the client-side i.e. in the browser. You still need to handle the uploaded files on the server using something like the FileUpload library I mentioned before)
Here's I want to do, I want to upload a file that will be processed by a servlet. I would use Apache Commons - File Upload to handle the file to be uploaded.
I've seen the gmail-like AJAX file upload, where there would be a hidden iframe that would later be populated with a javascript to stop showing the upload image or displaying a message that the upload is succesful. However, this uses PHP, where the php file to handle the file upload would include the javascript inside the iframe.
My question is, how would I do this in Java using servlets, without resorting to JSP and imitating the above implementation on PHP. I don't even know if this is possible, so please guide me on a good implementation (without external libraries except for commons fileupload).
Note: I am aware that there are libraries out there that could do this easily, but I first want to know how this happens, how this is possible, and to dirty my hands and learn this.
Edit: Just to add, I would use the streaming API of Apache-Commons FileUpload
It is exactly the same.
The client makes an HTTP request to the server (by submitting a form).
The server responds with some HTML (which links to or embeds some JavaScript).
Switching from PHP to Java is just a drop in replacement. You don't need to change any of the JavaScript. The user guide tells you how to set it up.
http://oreilly.com/pub/a/javascript/2002/02/08/iframe.html is the best idea to file-upload. i done file upload using hidden iframe. Please consult with attached link.