Sunday, August 5, 2012

Java class for Valums AJAX file uploader for IE9 with spring MVC

I wanted to have AJAX file upload which supports multiple files uploading for my recent project. The Valums AJAX file up-loader gave me a very good experience and integrated that into my application. This file up-loader uses XHR for uploading files on the browsers which supports XMLHttpRequest level 2 and falls back to hidden iframe based upload in other browsers. 

My application should run in FF, Chrome and IE. IE9 does not support XHR file uploads and even Valums GitHub has only provided a java example for XHR Level 2 supporting browsers which directly reads the input stream from the request. 

For browsers which do not support XHR Level 2, up-loader send the file to server as 'multipart/form-data'. Therefor, we should write our up-loader java controller class so that it reads multipart form data when request coming from browsers which do not support XHR file upload (like IE9) and directly read the input stream for the requests coming from the browsers which support XHR file uploads (like FF3.6+, Safari4+, Chrome). 

In both type of browsers, we should make sure that the response type as 'text/plain'. My application is running with spring 3 MVC which persuaded me to do some work around when reading multipart form data from the request. In spring 3 MVC environment, 'HttpServletRequest' which has 'multipart/form-data' are wrapped into 'MultipartHttpServletRequest', not like in normal servlet environment. 

Here, I am going to give you an example and basic java code which reads multipart form data with spring 3 MVC environment. If you are not using, spring 3 MVC and using some other controllers like pure servlets or struts 2 action class, you can directly read the multipart form data by using HttpServletRequest. 

However, for Valums file up-loader, we should write our controller class in tow conditional way. One is for XHR file upload supporting browsers and one for 'multipart/form-data' based file uploading browsers.

@RequestMapping(value = "*ajax*", method = RequestMethod.POST)
public @ResponseBody
String uploadFile(HttpServletRequest request, HttpSession session, HttpServletResponse response, Principal principal, Model model, Locale locale) throws IOException, ServletException {

   InputStream is = null;
   String filename = null; 
   String result = null; 
   try {
      
       if (isMultipartContent(request)) { 
            MultipartHttpServletRequest mrequest = (MultipartHttpServletRequest)request;
            Map<String MultipartFile> fileMap = mrequest.getFileMap();           
            for (Map.Entry<String MultipartFile> entry : fileMap.entrySet()) {
               MultipartFile mfile = entry.getValue(); 
               is = mfile.getInputStream();
               filename = mfile.getOriginalFilename();               
               break;
            }
       } else {
           filename = request.getHeader("X-File-Name");
           is = request.getInputStream();
       }
      
       result = "{success:true}";

   } catch (Exception ex) {
       ex.printStackTrace();
       result = "{success:false}";  
   } finally {
       try {
    is.close();
       } catch (IOException ignored) {}
   } 
   return result;
}


private static final boolean isMultipartContent(HttpServletRequest request) {
    String contentType = request.getContentType();
    if (contentType == null) {
     return false;
    }
    if (contentType.toLowerCase().startsWith("multipart/")) {
     return true;
    }
    return false;
}


I hope this will help you. At the beginning, even I thought, Valums ajax file up-loader does not work in IE9. But it works fine in IE as well. If you need any help, feel free to put comment or send a mail to me.
You may also like:

7 comments:

  1. Excellent work Semika. This is exactly what I was looking for. It's beeen one hell of a week trying to find this type of solution.
    I'm just wondering what the jsp counterpart of this controller looks like?
    Again, thank you!

    ReplyDelete
  2. @Mark:
    Thanks mark.What do you mean by "jsp counterpar"?. You mean using pure servlet?

    ReplyDelete
  3. Thanks for solution.Does this work for multiple file uploads also.

    ReplyDelete
  4. Yes. It works for multiple file upload as well. Now it has newer version of it. Better get the latest version which most of the bugs are fixed

    ReplyDelete
  5. Hi Semika,

    I am using Spring MVC + jQuery(Ajax) to upload multiple files. Currently, it works properly on Firefox. However, it is not work on IE 9.
    Could you help to support me the solution how it can work on IE 9.

    My email: cuongdp79@gmail.com

    Many thanks,

    ReplyDelete
  6. hi semika,
    please send the jsp code.i am getting prob in ie versions.but working in other browsers.(java+spring+ajax+formdata)
    function uploadFormData(){
    $('#result').html('');

    var oMyForm = new FormData();
    oMyForm.append("file", file2.files[0]);

    $.ajax({
    url: 'test4.htm',
    data: oMyForm,
    dataType: 'text',
    processData: false,
    contentType: false,
    type: 'POST',
    success: function(data){
    $('#result').html(data);
    }
    });
    }

    ReplyDelete

Share

Widgets