How to accept both multipart and application/x-www-form-urlencoded? - java

I built a servlet that allows uploading a file or alternatively uploading a list as input. So far I've handled it by setting the servlet to accept multipart/form-data so even if there is no file, I read the list as a part.
I'm now trying to call this servlet to upload a list through a JQuery AJAX method instead of through a form. If I try to upload a list normally through the method, I get:
org.apache.tomcat.util.http.fileupload.FileUploadBase$InvalidContentTypeException: the request doesn't contain a multipart/form-data or multipart/mixed stream, content type header is application/x-www-form-urlencoded; charset=UTF-8
If I set the contentType as multipart/form-data like so:
$.ajax({
url: someUrl,
type: 'POST',
contentType: 'multipart/form-data',
data: {list: inputList}
});
I get this error instead:
org.apache.tomcat.util.http.fileupload.FileUploadException: the request was rejected because no multipart boundary was found
My question is if there is some way to configure the servlet to accept both content types or alternatively is there some way to write the ajax data to upload multipart/form-data?
I know it's simple to upload multipart/form-data using the FormData API, but I need to support IE9 so this is not an option.

I suggest you to use Apache Commons FileUpload library. It provides you with a uniform interface, no matter which type of form was submitted, and makes it easy to work with uploaded files. See Section Processing the uploaded items of the User Guide, it should give you a general idea how it works.

Related

How to send file via Ajax call to Servlet

I have an HTML form in AEM where I have to attach the files and the same files will be sent to one Rest API via Java Servlet.
I am calling the Java Servlet via Ajax and able to send other String data to Java Servlet but not able to send the file Array which contains the files attached to the HTML Form attachment option while submitting the Form. How can I get the file in Java servlet?
In JS
var myFile [] is what I am sending in a ajax call.
$.ajax({
url: /servletUrl,
type: 'post',
data: {
'myFile': myFile,
},
success: function(response){
}
});
In Java :
Enum paramObject = request.getparameter();
When I put the object in HashMap and try to get the file, its type is coming as String not Object.
I am not sure where I am setting it as String.
The servlet has to be able to process Multipart-Messages.
I do not know AEM, but in Jakarta / Java Enterprise Edition / JEE / J2EE:
you have to specifically add the #Multipart annotation to the servlet.
Now, open your browser, press F12 to go into debug details, and when you trigger the request, the Network tab will display alle the infos that are posted. Look up the name of the parameter, usually it's calles file[]
When handling the request in the servlet, you can use the HttpServletRequest's request.getParts() method to find all parameter parts.
With final Part filePart = request.getPart(pFileParamName); and final InputStream filecontent = filePart.getInputStream(); you will be able to access the data.
And this will probably be very similar in most servlet frameworks.

Finding the downloaded filetype from HTTP message

I am trying to build a basic downloaded file scanning extension for the popular open source security application ZAP. using the built in sniffer, I can access the HTTP response messages. I am unable to determine the filetype of the file being downloaded. Although the Mozilla blog regarding HTTP talks about using the MIME Type in the 'Content-Type' header to determine the file type, I find that none of the response messages that I get have anything other than application/json or text/html or application/octet-stream. How do I determine if the corresponding HTTP response body contains any particular file type? . I am thus stuck at a dead end!
I am a beginner in this field and there might be something that I am over looking. Any help or pointers would be greatly appreciated.
The Content-Type entity-header field indicates the media type of the entity-body sent to the recipient or, in the case of the HEAD method, the media type that would have been sent had the request been a GET.
Taken from https://www.rfc-editor.org/rfc/rfc2616 under "14.17 Content-Type"
They give this as an example:
Content-Type: text/html; charset=ISO-8859-4
This HTTP request or response contains text in the form of a body of HTML.
If you do not trust this header (which most of the time you can), the next step would be analyzing the file contents. For example, if the file contains opening and closing HTML tags, then there is a good chance that the file is an HTML file. If the file begins with a [ or { and ends with a ] or } then there is a good chance that it is a JSON file. An actual analysis would and should be much more detailed, of course.

Some information about how Spring MVC recive and use the Accept Header in these two case

I am studying on the Spring MVC showcase example dowlodable from the STS dashboard.
In this time I am studying on the Converters section of this example and I have some question for you.
To start, in my view I have the following two links:
<li>
<a id="writeJsonAccept" class="writeJsonLink" href="<c:url value="/messageconverters/json" />">Write JSON via Accept=application/json</a>
</li>
<li>
<a id="writeJsonExt" class="writeJsonLink" href="<c:url value="messageconverters/json" />">Write JSON via ".json"</a>
</li>
The first link generate an HTTP Request towards the URL: messageconverters/json
The second link generate an HTTP Request towards the URL: /messageconverters/json.json (differently from the first URL this one end with .json extension
Ok, both these links have class="writeJsonLink" and related to the click event of these links the following JQuery callback function is called:
$("a.writeJsonLink").click(function() {
var link = $(this);
$.ajax({
url: this.href,
beforeSend: function(req) {
if (!this.url.match(/\.json$/)) {
req.setRequestHeader("Accept", "application/json");
}
},
success: function(json) {
MvcUtil.showSuccessResponse(JSON.stringify(json), link);
},
error: function(xhr) {
MvcUtil.showErrorResponse(xhr.responseText, link);
}});
return false;
});
This function only execute an AJAX call and wait for an HTTP Response passing its content to an handler that will show the output in the view...ok...
Before sending the request, the function check if the URL don't end with .json extension
If this request don't end with .json extension the following header is added to my HTTP Request:
Accept = application/json
From what I know the Accept Header say which specific mediatype is considerable acceptable for the HTTP Response, in this case say that the only acceptable media type is a JavaScript object having JSON format, ok...
This Request is handled from the following method of my controller class that return a valorized object that will be converted in JSON forma using Jaxb2RootElementHttpMessageConverter
#RequestMapping(value="/json", method=RequestMethod.GET)
public ResponseEntity<JavaBean> writeJson() {
// Oggetto che rappresenta gli HTTP Header dell'HTTP Response
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.TEXT_PLAIN);
return new ResponseEntity<JavaBean>(new JavaBean("bar", "apple"), headers , HttpStatus.OK);
// return new JavaBean("bar", "apple");
}
Now, my question is about the differences from the two links.
The first one don't end with .json extension, so the Accept header is added and it is setted on application/json sayng that the browsers expects to receive a JSON object
The second one end with .json extension, so the Jquery method don't set the Accept Header
But, this thing what mean? that when an URL end with .json the Accept header is automatically setted? Or more generally, when I have an URL that end with some kind extension (for example like .xml) the relative Accept header is automatically setted?
Or simply in this second case, don't set the Accept Header mean don't handle the media type that I can recive in the body of the HTTP Response?
Ok, your english is not-so-hot, so let me try to help you the best I can.
In my understanding, which may very well be wrong, is that you want to know if the browser will set the Accept: header to be json when the URL ends in json? I do not believe this is the case. I may be greatly mistaken on this, but you can test this by using something like Firebug or Chrome's Developer Tools, or if you like IE get Fiddler, and see exactly what headers get sent from the browser.
Now, if you are asking if Spring will magically put the headers there, then again I think the answer is "no". The HTTP headers on the request come from the browser, and although you could put in a Servlet Filter or something to set the request filters, I think this would be dangerous to assume all browsers handle these request headers the same way.
No, if the question is "how are my requests all getting to my Controller's writeJson() method?", then the answer has nothing to do with the "Accept" header at all. Your method is matching on any URI pattern that ends in /json, and in both cases your URL ends in /json. If you want to filter on things that have an "Accept" header of JSON, then I think you want to do something like this:
#RequestMapping(value="/someUriPattern", headers = {"Accept=application/json"})
Please understand I typed the above from memory, so you may need to tweak it a tad.

How to parse multipart/mixed content from JSP to servlets

I'm sending multipart/mixed content message from JSP to servlets but when I used
ServletFileUpload.isMultipartContent(request);
method to check if the request is Multipart or not, I'm getting the output as "false". This is how content type header of my message is looking like:
multipart/mixed;
boundary="----=_Part_26_2184190.1271924416255"
Could anyone please tell me how can I parse the request using Apache fileupload API? How the above method can return me an output as "true"
The conditions are:
the request method must be post
the content-type must start with multipart/
Check these two via request.getMethod() and request.getContentType()

Posting contents of a file using HttpClient?

I want to send the contents of a file as part of a http request using Apache HttpClient and I could not figure out how to pass on the file contents in the request body.
You didn't specify the format....
Most likely, you want to send a POST request, the contents will be multipart/form-data MIME type. This emulates what a browser sends from an <INPUT type="file" ...> form element. This requires some pretty sophisticated parsing on the server side to extract the multiple parts from the body and correctly extract the file data from the other fields (if any). Fortunately, commons-fileupload does this perfectly. The first answer regarding FilePart is exactly right.
Alternatively, you could simply post the raw contents of a file as the body of the request by using an InputStreamRequestEntity. This may be much simpler if you're writing your own server side to receive the data. The server side is as simple as streaming the request's InputStream to disk. I use this technique for uploads with Google Gears.
Check out FilePart and related.
Here's the sample.

Categories