I need to write REST resource that should receive a file and save it to the disk.
The files will be sent from jersey client.
For now, I see two options:
1. Using multipart
2. Just reading the inputstream as a string and saving it to a file.
What are the pros of using multipart? is it related to file size? or anything else?
Thanks
If you use Jersey server side, using multipart you gain
disk buffering (surely you don't want to retain huge files in memory)
automatic base64/binary stream conversion
If you choose the String option these benefits are unavailable.
See also my answer to the question JAX-RS Accept Images as input, there is a sample implementation of the multipart option
Related
How can I write a content of a file into http response? I prefer to write it to an entity first if possible. I searched for examples, but unfortunately didn't find any suitable working one..
Of course it is possible. After all that's what all web servers do when they serve you pages. Add proper Content-Type and Content-Lenght (if known) to your headers, open your file, read it and write it your response.
While uploading a image/doc/xlsx file from my AngularJS client to my server-side java using JAX-RS(Jersey) i am getting the following exception,
org.jvnet.mimepull.MIMEParsingException: Reached EOF, but there is no closing MIME boundary.
What is this? Why I am getting this exception? How can I get rid of this?
Note: It works for the files with extension .txt, .html, .yml, .java, .properties
But not working for the for the file with extension .doc, .xlsx, .png, .PNG, .jpeg.. etc.
My Server side code:
#POST
#Path("/{name}")
#Consumes(MediaType.MULTIPART_FORM_DATA)
public String uploadedFiles(#Nonnull #PathParam("name") final String name,
#FormDataParam("file") final InputStream inputStream,
#FormDataParam("file") final FormDataContentDisposition content) {
}
I encountered the same issue. Based on my research, the problem has no relation with the file type. It has a little relation with the size of the uploaded file.
I'm not sure if the root cause is when the uploading file is very big, before the file is uploaded to the server completely, the client disconnects to the server (such as timeout). And I also verified the guess. My test steps is,
1. In client, upload a very big file.
2. Before the get the response from server, which means is uploading file;
close the test client
3. check the server side, you will see the issue.
So To fix it, my solution is add timeout time in client side.
OK, I'm only guessing, but I think I can see a pattern here.
The file types that are working are text based
The file types that are not working are binary
This suggests to me that maybe the problem is that there is some kind of issue with the way that non-text data is being handled by the upload process. Maybe it is being transcoded when it shouldn't be.
Anyway, I suggest that you use some tool like Wireshark to capture the TCP/IP traffic in an upload to see if the upload request body has valid MIME encapsulation.
If a binary file uploaded using JSP, the binary data may contain some bytes that have special meaning to some network devices and will cause problems when passing through these devices, if I upload a file like a image, do I need to encode the file with Base64 or some other encodings?
If you are using form in jsp i.e
<form enctype="multipart/form-data">
Then no need of encoding.It will be send to server as Multipart file.
And it depends on your other technique what are you using to upload your file.
There is no need to encode the file. When you send data using some network protocol for example TCP the data is enclosed into protocol envelope. The envelope fields may be used by network hardware for example fields like IP address could be analyzed. But you data payload is not analyzed and therefore could not have any special meaning to routers, gateways etc.
Using Tomcat 6, I am using apache commons FileUpload to allow image uploads. I can set the max files using setSizeMax and setFileSizeMax. But it seems that an entire large file is uploaded and then checked too see if it is too big. According to another post, it seems that setSizeMax should cut off the upload, but that is not the behavior I get.
To test this, I set the sizeMax and fieSizeMax very low, and uploaded a rather large file. It took 15 secs uploading the large file, instead of cutting it off almost instantaneously.
Any idea? Here is some code, with a simplified exception clause.
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
upload.setFileSizeMax(30);
upload.setSizeMax(28);
List items = null;
try {
items = upload.parseRequest(request);
} catch (Exception e) {
out.println("exceeded max file size..");
return;
}
MORE INFO: Using tomcat 6. Setting the maxPostSize does not work for content-type: multipart/form-data. Also, checking the request content length again requires the entire file to be uploaded. Finally, using the steaming api of FileUpload also does not seem to work, as it again seems to require the entire file to be uploaded before the stream can be be closed; the upload will continue even if the servlet does not write the bytes to disk. There has to be a way to prevent huge uploads using tomcat 6, as uploading images and such is a very common task for web apps.
The client sends the bits whether you save them on the server or not. There is no way for the server to tell the client to stop sending bits short of forcibly closing the input stream (because of the nature of HTTP: response follows request -- they are not simultaneous). You can try that, but most application servers will drain the input stream from the client when you perform a close() so nothing will change.
If you can control the client and require the use of 100-Continue (via an Expect header), you may be able to snoop the Content-Length of the request and reject it by sending a negative reply instead of 100-Continue.
Tomcat has a maxPostSize attribute for its HTTP Connector. See Tomcat docs
Edit: Too bad that doesn't work for multipart/form-data. Have you considered using a signed Applet or using "Java Web Start" to manage the upload ?
I need to send X number of files to my servlet from an applet, which is the best way to do this?
And I need to send before the files, a java object populated.
I need to do it all in a single connection.
I'll upload my applet 3 ~ 10mb to my servlet.
I currently use FileInput together with the OutputStream and BufferedOutputStream to send a file, causing the buffer size is 8K.
First time I'll try to zip all the files to upload a zip file to the servlet, but I know it's not a good solution.
In the Applet side, send it as a normal multipart/form-data request by either URLConnection or HttpClient. In the Servlet side, use either HttpServletRequest#getParts() or Commons FileUpload to extract the parts from the request. This way the applet and servlet are not tight coupled to each other, but just reuseable on different servers (e.g. PHP) and/or clients (e.g. a simple HTML page).
Whether or not to zip the individual files into a single zip file is a decision you'd need to make yourself based on coding and performance impact.