I know how to do file upload using Primefaces or using Tomahawk, however, I am trying to doing file upload using Apache Commons FileUpload and so far I am having a bit of road block. Even though my form use multipart/form-data
, when I submit my form, the content type become application/x-www-form-urlencoded
. Here is my code
<h:body>
<h:form enctype="multipart/form-data">
Upload File
<input type="file" name="file"/>
<p:commandButton value="Submit" action="#{viewBean.submit}"/>
</h:form>
</h:body>
Here is my ViewBean
@ManagedBean
@ViewScoped
public class ViewBean implements Serializable {
public void submit() {
String url = "/FileUploadServlet";
FacesContext context = FacesContext.getCurrentInstance();
try {
String contentType = context.getExternalContext().getRequestContentType();
context.getExternalContext().dispatch(url);
} catch (Exception e) {
logger.log(Level.SEVERE, "Exception when calling Servlet", e);
} finally {
context.responseComplete();
}
}
}
So when I try to print the content type above, it showed application/x-www-form-urlencoded
. If I put ajax="false"
to my p:commandButton
, then the submit()
method is not even invoked, but if I take out enctype="multipart/form-data"
(still keep ajax="false"
), then submit()
is invoked but it is not multipart, it is application/x-www-form-urlencoded
, so apache commons fileupload throw an exception since it is not multipart. Seems like whatever I do, I cant seems to get the multipart requrest. Please help
public class ServletFileUpload extends FileUpload. High level API for processing file uploads. This class handles multiple files per single HTML widget, sent using multipart/mixed encoding type, as specified by RFC 1867.
What is file-upload[.]com? file-upload[.]com provides a file hosting service, however, it also uses rogue advertising networks. Therefore, it contains dubious ads and promotes bogus, potentially malicious websites.
So when I try to print the content type above, it showed application/x-www-form-urlencoded.
The <p:commandButton>
sends by default an ajax request of level 1 XMLHttpRequest
. This does not support multipart/form-data
. Only level 2 XMLHttpRequest
supports it, but it's only supported in the newest browsers (those also supporting HTML5) and not implemented in JSF JS API nor in PrimeFaces JS API.
If I put ajax="false" to my p:commandButton, then the submit() method is not even invoked
This way however a fullworthy multipart/form-data
will be sent. That the submit method is not invoked is just because JSF prior to version 2.2 does not support multipart/form-data
requests out the box. JSF collects the submitted data by default using request.getParameter()
and getParameterMap()
on the underlying HTTP servlet request. However, this will return null
when an encoding other than application/x-www-form-urlencoded
is been used. As JSF determines the to-be-invoked action method based on submitted data, it won't be able to locate and invoke it when the data is null
.
In theory, if you create a Filter
which uses Apache Commons FileUpload or the new Servlet 3.0 request.getPart()
/getParts()
methods to extract the data from the multipart/form-data
request and wraps the current HTTP servlet request with a custom implementation which overrides the getParameter()
calls wherein a mapping of the extracted data is been supplied, then JSF will be able to do the needed job based on results of getParameter()
calls. You can find a concrete example utilizing the Servlet 3.0 API in this article and the same example which is slightly changed to utilize Apache Commons FileUpload in this answer.
The upcoming JSF 2.2 will have a new <h:inputFile>
component which is bindable to a Servlet 3.0 Part
property.
<h:form enctype="multipart/form-data">
<h:inputFile value="#{bean.file}" />
<h:commandButton value="submit" action="#{bean.submit}" />
</h:form>
with
private Part file;
JSF 2.2 final release is scheduled for late end of Q1, but is currently available as a snapshot release.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With