I had to remake the example a bit since I got question to provide a sample application. When extracting the code I noticed it did not work anymore. The reason is probably the one mentioned at this blog: http://mcatr.blogspot.com/2010/01/multipart-requests-and-jsf.html.To make it work again, I did a solution that I am not happy with but it works. It takes the idea from this blog, joined with some from the other blogs mentioned. The former blog states that a multipart request to JSF 2 do not work, because it can not extract parameters from that kind of request.
The problem is that for what I actually wanted it was not right and one was a little bit overkill. So as usual I took another approach. I got some helf from Uploading files with JSF 2.0 and Servlet 3.0 but that solution includes making a custom component and renderer, and is dependant on classes found in Uploading files in Servlet 3.0. I actually copied all the code and tried it...but I got a failure when loading the page. So I wanted something with less code. and simpler to use, and I have a case when I am going to store vCards in a database so a solution to save the file on disk means I have to modify code anyway.
I took the following approach:
- Use standard html <input type="file" />
- Use @ManagedBean
- I first had a base class to handle the file and extended the Managed bean with this one, but since this stopped working I had to add:
- A Wrapper to wrap multipart requests
- A Filter to catch multipart request and transform them to the Wrapper type.
- I also have a FacesUtil class to simplify getting request and parameters
Here is the code:
In the view (vCardForm.xhtml)
Class to represent the uploaded file (UploadFile.java)
I created a class to store some information about the file being upload, I can later choose if I want to store to disk or in a database, for example sending this to an EJB and the EJB descides what to do.The managed bean (VCardBean.java)
The interesting thing going on here is that i initialize the base class with the request for use of the request. Probably I could have done this in the constructor of the baseclass, but something you have to have to refactor.MultipartRequestWrapper
MultipartRequestFilter
Session bean for handling the storage.
For the example this only stores it in the session.Finally the class to inherit to make it all work
This is now obsolete, but I keep it in case JSF will handle the mutlipart form in the future. But even then it may not be needed.The only thing needed in the Managed bean is to call findFile("vcardFile") on the multipart request to get the file that is being uploaded and take action on that.
A sample project (for netbeans) can be found here: http://sites.google.com/site/ironicprogrammer/home/jsf-file-upload-example
it would be of great help if you could upload this sample application ..
ReplyDeleteOk, Maybe I will. It is part of a bigger application. I rewrote the code on the blog a little, but when I have time I will make a stripped version and put it on the Google-site.
ReplyDeletegreat .. thanks for uploading the sample app ..
ReplyDeleteHope you saw I had to rewrite a bit. Anyway, the sample project should work.
ReplyDeleteDoes it work with https as well ? Many file-upload components are not working over https if you are using a self-signed certificate ..
ReplyDeleteHave not tried, but can not see why not. Test and see what happen :)
ReplyDeleteWhere does it save to? can i save the file to my desktop? what configuration have to be changed? Thks
ReplyDeleteIt does not save it anywhere, or whereever you want it to be. I used EJB to save it to a database. But you can write any code you want in the business layer or the web project to save the file where you want it.
ReplyDeleteThe sample application is great.
ReplyDeleteI just have a problem with validation. First, as far as I know I cannot add standard JSF validators to tag and second, if the specified file does not exist, where would I throw ValidationException?
Thanks
It doesn't works here, the wrapper rans down and no parts were in the request to loop through...
ReplyDelete@n3whous3: Running on glassfish v3? How is it set up otherwise? This worked for me.
ReplyDeleteThis solution works perfectly for file uploads. However, I have a strange problem. When using enctype="multipart/form-data" the code in this example gets executed. The fields in forms are correctly transformed, however in one form I have a selectManyListbox and this list box always returns only one option when used in conjunction with the file upload solution. Do you have an idea why this could happen?
ReplyDeleteHave not used JSF for long, but probably the requestwrapper does something that makes that listbox behaving differently. Put som debugging on that to see what happens.
ReplyDeleteThis tutorial's great but how do i upload a file to folder?it would be great if you could help me how to upload it to folder.Thank you
ReplyDeleteHi "minhltnt", have a look here > http://www.mkyong.com/struts/struts-file-upload-example/ to get inspiration how to save it to the file system.
ReplyDeleteHi,thanks your support and i have a questions again: i use EJB3+JSF+Primcefaces,i have method handle upload image in folder and it work well but it just work when server deploy first,when i upload image to server(folder:/WEB-INF/item/) have image but i re-start server i can't find image which was uploaded.How do i solve this problem?Hope your support again.Thanks!
ReplyDeleteThis tutorial is great, works perfectly for me.
ReplyDeleteYou literally saved my ass. Thanks !
Your project does not mention the list of jar used
ReplyDeleteWell, I do not solve everything for everyone. If you use Netbeans you would probably figure it out or get all the help you need to use it.
ReplyDeleteAnyway, I also imply that you have some basic knowledge, and I also post stuff to document things I have done and maybe will need again. For me it is not interesting to list jar-files
Man, I still have an issue: never had problems with the stuff written by you, on the contrary, the issue I have is the following:
ReplyDeletewith the JSF implementation I use - Mojarra 2.* - when I put the enctype to multipart stuff, the controller methods in the managed bean (the stuff you put at action="" in h:commandButton) DOES NOT GET CALLED. Now that is a 100 points question, what shall I do about that...
Well, I do not know Mojarra 2. Probably some issues with framworks and the order stuff gets called. Does Mojarra use som call stack like struts that for some reason overrides/removes stuff on the way?
ReplyDeletedoes not work on jboss - tomcat: https://issues.apache.org/bugzilla/show_bug.cgi?id=49711
ReplyDeleteI see you did not post my second comment :) - the second one, very curious if you found anything offensive as I merely pointed out an issue. The discussion was getting interesting.
ReplyDeleteI have posted all comments I have seen. Not offensive, but I am not really interested in discussions with anonymous on things I did 2 years ago. But I really do not know wich comment you mean should have been offensive? Was it the jboss-tomcat issue?
ReplyDeleteWTF ... it is COMPLICATED!!!!! to upload a simple f***** file !
ReplyDeleteHi dear author,
ReplyDeletetell us please there we can get your FacesUtil.class ?
You cant. I do not work at the same place as I wrote this code.
ReplyDeleteYou need to do the work yourself. What it does is to wrap code like:
HttpServletRequest req = (HttpServletRequest)FacesContext.getCurrentInstance().getExternalContext().getRequest();
To avoid having that much code everytime it just do that in
FacesUtil.getRequest()
It has some bugs and these are the solutions:
ReplyDeleteBug1: "WARNING: StandardWrapperValve[Faces Servlet]: PWC1406: Servlet.service() for servlet Faces Servlet threw exception"
http://www.imixs.org/roller/ralphsjavablog/entry/using_multipartconfig_in_a_servlet
This worked! Now it can upload files and download.
Bug2: "java.io.FileNotFoundException: d:\tmp\upload_633d607a_143cc20a63e__7ffb_00000011.tmp (The device is not ready)", caused by my disk name.
Bug3: "javax.faces.FacesException: PWC3991: getOutputStream() has already been called for this response"
This doesn't matter too much since the function works just fine now.
This bug I'm trying to solve by using my knowledge – UploadFile.java implements Serializable and close all stream. Solution: Add this "FacesContext.getCurrentInstance().responseComplete();" from http://stackoverflow.com/questions/5662455/jsf-2-0-convert-xhtml-page-to-pdf-using-flying-saucer-java-lang-illegalstateexc or https://community.oracle.com/thread/1726938?start=0&tstart=0
Changes:
1)add the following to web.xml
f:\tmp
20848820
418018841
1048576
2)In VCardBean, findVCard method add "
output.flush();
FacesContext.getCurrentInstance().responseComplete();"
3)create folder f:\tmp
Bugs? Yes maybe depending how the environment is set up. Considder also that I wrote this post 4 years ago, so the App-server you are running on, and versions of Servlet API etc, may differ now.
ReplyDelete