InputStream closed in Apache FileUpload API - java

This is a very specific question. I hope there's someone here with good knowledge in FileUpload API.
If you have been worked with this API you should know that when the max size of a file has been exceeded the next items cannot be read because the FileSizeLimitExceededException is thrown and if you attempt to call one more time to hasNext() method to iterate to the next item an IOException is thrown because an inputstream is closed and you attempt to read it again.
This scenario is very bad because the next parameters cannot be read. Supose this form:
<form action="..." method="post" enctype="multipart/form-data">
<input type="hidden" name="param1" value="foo"/>
<input type="file" name="myFile"/><br/>
<input type="hidden" name="param2" value="bar"/>
<input type="submit"/>
</form>
Now the file exceeds the maximum size. Result:
"param1" is read.
"myFile" generates FileSizeLimitExceededException.
"param2" is not read.
I'm trying to rewrite part of the API -with no luck- because I want to read the next items ("param2" in this case).
Anyone has had the same problem? How have you fixed it?
Thanks.
EDIT: Well, I've implemented the solution proposed by BalusC. For the future:
FileUpload wrapper
FileUpload wrapper usage
If you consider that this wrapper needs anything else just say it. I don't accept it as a real solution because the ideal is to modify and fix the API itself.

A way without hacking the API would be so set the upload file size limit to "unlimited" and examine the upload file size yourself afterwards by FileItem#getSize(). This may only take longer before the enduser get feedback about that, because the entire file needs to be read fully first (but you need to do it anyway in order to get all subsequent items).
As a completely different alternative, you may want to look at the new HTML5 File API which offers you a way to examine the file size using JavaScript before the request is actually been sent.
var size = document.getElementById("fileFieldId").files[0].size;
// ...

Related

JSON Data Limit

We have grails 2.2.4 application running on Tomcat that works with user camera and keystrokes, collects some data on the client side with Javascript and sends using POST.
In the view that collects data we have:
<g:form name="testResultsForm" id="testResultsForm" controller="customer" action="thankYou" method="post">
<h3>Dummy data!</h3>
<input type="text" style="visibility: hidden" name="testResults" id="testResults"/>
<button type="submit" class="btn btn-default">Submit dummy data</button>
</g:form>
In the JS, we assign all camera data to this html element and submit the form:
TestUtils.setValue('testResults', sendData);
$("#testResultsForm").submit();
In the grails controller we have the following line to parse the JSON:
def data = JSON.parse(params.testResults)
Everything works as expected except for when the user takes longer than normal and puts in lots of keystrokes. The errors looks something like:
2014-06-14 01:22:14,323 [http-8443-16] ERROR (org.codehaus.groovy.grails.web.errors.GrailsExceptionResolver) - JSONException occurred when processing request: [POST] /qbcheck/customer/thankYou
Expected a ',' or ']' at character 524288 of {"patkey":"","test_version":"1.4","data_version":"1.3","patientid":"","test_date":"","test_duration":0,"gender":"","dob":"","fov":62,"fps":26,"scale_factor":0,"country":46,"camera_data":{"x":[353,353,353,353,3......
It always fails at character 524288. This led us to investigate that there might be a limit on the amount of data, we looked at Tomcat and found that it allows 2MB data by default using maxpostsize property. Still we updated it to a bigger number just to be sure. Similarly, we tried looking on Grails and JS side but were not able to find any limitation.
Looking for any pointers in this regard. We are able to provide more details as required.
We found that the html "input" has a hard limit of 512 KB. Ideally, we should have received some kind of error/warning when trying to assign more data to an input value through JS. However, that does not happen
So we changed the input which was previously defined as:
<input type="text" style="visibility: hidden" name="testResults" id="testResults"/>
To a text-area:
<textarea style="visibility: hidden" name="testResults" id="testResults"/>
And this allowed us to transfer data greater than 512 KB.

Jsoup posting modified Document

I'm trying to create a web scraper for my coming android app. Therefore I need to use a simple search form on a website, fill it out and send my results back to the server.
As mentioned in the Jsoup-Cookbook, I scraped the site I needed from the Server and changed the values.
Now I just need to post my modified document back to the server and scrape the resulting page.
As far as I've seen in the Jsoup-API there is no way to post something back, except with the .data-Attribute in Jsoup.connection, which is unfortunately not able to fill out text fields by their id.
Any ideas or workarounds, how to post the modified document, or its parts back to the website ?
You seem to misunderstand how HTTP works in general. It is not true that the entire HTML document with modified input values is been sent from the client to the server. It's more so that the name=value pairs of all input elements are been sent as request parameters. The server will return the desired HTML response then.
For example, if you want to simulate a submit of the following form in Jsoup (you can find the exact HTML form syntax by opening the page with the form in your browser and do a rightclick, View Source)
<form method="post" action="http://example.com/somescript">
<input type="text" name="text1" />
<input type="text" name="text2" />
<input type="hidden" name="hidden1" value="hidden1value" />
<input type="submit" name="button1" value="Submit" />
<input type="submit" name="button2" value="Other button" />
</form>
then you need to construct the request as follows:
Document document = Jsoup.connect("http://example.com/somescript")
.data("text1", "yourText1Value") // Fill the first input field.
.data("text2", "yourText2Value") // Fill the second input field.
.data("hidden1", "hidden1value") // You need to keep it unmodified!
.data("button1", "Submit") // This way the server knows which button was pressed.
.post();
// ...
In some cases you'd also need to send the session cookies back, but that's a subject apart (and a question which has already been asked several times here before; in general, it's easier to use a real HTTP client for this and pass its response through Jsoup#parse()).
See also:
HTTP tutorial
HTTP specification
That's not the way. You should create a POST request (use Apache HTTP Components), get the response and then scrape it with JSoup.

Strange behavior with the method getUploadedBlobs

I've a problem with the methode blobstoreService.getUploadedBlobs(). I've a JSP page in wich one I set an uploader like this :
<formname='form' action='<%= blobstoreService.createUploadUrl("/Edit_Engine") %>' method='POST' enctype='multipart/form-data' >
<input label='...' multiple='false' name='myFile' />
//...and multiple input for text
</form>
and I retrieve this code with my servlet :
java.util.Map<String,BlobKey> blobs = blobstoreService.getUploadedBlobs(req);
BlobKey blobK = blobs.get("myFiles[]"); //I don't know why I need to add the characters 's[]' at the end...
But the behavior is strange. The first time I upload an image, everything works. However, the second time, I send my form without uploading somehting (only text data), and then my java code finds a BlobKey. But this BlobKey seems to be the previous sended data, or a corrupted data.
I mean that not normal, because when I deploy this version on my localhost, if the form uploads no file the method getUploadedBlobs returns an empty HashMap. However, when I deploy on google servers, if the form uploads no file, the method getUploadedBlobs seems to return a HashMap with wrong data.
Could you help me? Or tell me if this behaviro is normal...
Many thanks,
bat
If you're getting a valid BlobKey, then myFiles[] is most likely the name given to the file input field in the form. Is that the case? That seems like an odd name for an input field. Are you using a template library to help generate HTML from the JSP?

java - how to get data of a file from a form?

I've created a form and I need the user to enter some info then upload a picture.
So lets say I have something like this:
<form method="post" enctype="multipart/form-data" action="some servlet/filter">
<input type="file" name="logo">
</form>
I need to use java to change that data to a byte[] then to blob so I can insert to a table.
How do I get the data from this form?
A bit of info on this:
I created the page using javascript, then when submitted it will call a java function to handle the data from the form. It seems that when I submit the form the data for the file is not passed over to the servlet.
So far the few methods I've tried have returned null and I'm outta ideas...
Any examples/help is greatly appreciated!
I think the main question I have is where is the file data stored before the java file start working on it? Is a special global variable holding the data or something like that?
You can use the Apache Commons FileUpload library.
The Commons FileUpload package makes it easy to add robust, high-performance, file upload capability to your servlets and web applications.
FileUpload parses HTTP requests which conform to RFC 1867, "Form-based File Upload in HTML". That is, if an HTTP request is submitted using the POST method, and with a content type of "multipart/form-data", then FileUpload can parse that request, and make the results available in a manner easily used by the caller.
If I understood you right, you need something similar to this example:
http://www.servletworld.com/servlet-tutorials/servlet-file-upload-example.html
I used the following tutorial one year ago:
http://balusc.blogspot.com/2009/12/uploading-files-in-servlet-30.html
It looks like it's a lot, but it's actually easy to understand, and it has a lot of good information.

how to get full path from file type in JSP?

i written some code in JSP like this--
<input type="file" name="imagename" >
and in servlet i am retrieving 'imagename' value. But it is giving the name of the image instead of full path. My servlet code is like this:
String imagename = request.getParameter("imagename");
and i dont want to use javascript. any ideas? Thanks in advance
Maybe you should checkout this question: How to get the file path from HTML input form in Firefox 3
There is little to no reason why server should have to know full file path. If you want to upload a file, you'll need to use an appropriate library like Apache Commons FileUpload and transfer the file using.
<form action="upload-script-url" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit">
</form>
Apache Commons FileUpload will then accept and transform encoded file into a usable form.
Otherwise you'll need to use JavaScript to get that path.
Assuming that you are trying to upload a file to your server, please note that file uploads are a little more than what you are trying to do - do not expect that if you have a "file" input type in a form, on submission the file just reaches your sever, with no effort. There is a certain procedure to do that.
This article might e a good reference : http://www.cs.tut.fi/~jkorpela/forms/file.html
For Java, use Apache's commons-fileupload : http://commons.apache.org/fileupload/
imagename contains the variable you pass to the servlet... the actual HTTP request parameter. If you want the full path, be sure that the program that is calling your HTTP page is passing the full path instead of just the image name.

Categories

Resources