miércoles, 4 de abril de 2012

Ajax + JQuery + HTML5 ProgressBar + Spring



So, this post will not treat about how to configure Spring or how to include JQuery or etc. I will think that you have enough JS and Java knowledge or that you are able to find a post that can help you with that, what you will find is some code and explanation to insert in your project. I will consider this a on going process so if you have questions that can improve the content of this post or if you have any recommendation, write it down.

Then lets start with the html:
 
 

In order to sent file data to the server you must contain the file input type inside a form that can handle "multipar/form-data" because a regular form can not get the bytes of the file in it.

You will get something like:











For the Ajax request to the server the JS will look like:

$yourDomElement.find(':button').click(function(){
     $yourDomElement.find('progress').attr({value:0,max:100});
        //create a FormData Object that will be sent
      var formData = new FormData($yourDomElement.find('form')[0]);
      $.ajax({
       url: 'multiPartFileSingle',  //server script to process data
       type: 'POST',
       xhr: function() {  // custom xhr
        myXhr = $.ajaxSettings.xhr();
        if(myXhr.upload){ // check if upload property exists
         myXhr.upload.addEventListener('progress',function (evt){
          if(evt.lengthComputable){
           $yourDomElement.find('progress').attr({value:evt.loaded,max:evt.total});
            }
         }, false); // for handling the progress of the upload
        }
        return myXhr;
       },
       //Ajax events
       //beforeSend: beforeSendHandler,
       success:  function(data) {
       if (data.successMessage){//
        //set progress to 100%
        $yourDomElement.find('progress').attr({value:100,max:100});
       }
       if (data.errorMessage){
        console.log("error uploading file");
       }
      },
       data: formData,
       cache: false,
       contentType: false,
       processData: false
      });

    });


With the comments in the code you should be able to kind of understand what is going on, for more information go to the JQuery documentation. $yourDomElement is the container of the form and progress bar. multiPartFileSingle is the URL in the server that attend this ajax request. The server servlet is returning "successMessage" if the server was able to get the file else "errorMessage" is returned.

The server code:


 @RequestMapping(value = "multiPartFileSingle", method = RequestMethod.POST)
 public void uploadFile(HttpServletResponse response, @RequestParam(value="file") MultipartFile file){
  
  String back  = "";
  try{
   if (!file.isEmpty()) {

    file.getBytes()
    back = "{successMessage : 'successMessage'}";
   } else {
    back = "{errorMessage : 'errorMessage'}";
         }
  }catch(Exception e){
   e.printStackTrace();
   back = "{errorMessage : 'errorMessage'}";
  }

  response.setHeader("Pragma", "no-cache");
  response.setHeader("Cache-Control", "no-cache");
  response.setDateHeader("Expires", 0);
  
  try {//Changing to ISO, because standard AJAX response is in ISO and our string is in UTF-8
   back = new String(back.getBytes("UTF-8"), "ISO8859_1");
  } catch (UnsupportedEncodingException e) {
   e.printStackTrace();
  }
  
  // Write Json string in Json format
  AbstractHttpMessageConverter stringHttpMessageConverter = new StringHttpMessageConverter();
  MediaType jsonMimeType = MediaType.APPLICATION_JSON;
  if (stringHttpMessageConverter.canWrite(String.class, jsonMimeType)) {
   try {
    stringHttpMessageConverter.write(back, jsonMimeType, new ServletServerHttpResponse(response));
   } catch (IOException m_Ioe) {
    m_Ioe.printStackTrace();
   } catch (HttpMessageNotWritableException p_Nwe) {
    p_Nwe.printStackTrace();
   }
  }
 }

Doubts, commentaries or recommendations are welcome.
Cheers.

4 comentarios:

  1. Thank you very much for the post, this was really helpful

    ResponderEliminar
  2. You are welcome Alex, I will soon post something about how to make an iPad - iPhone offline app with HTML5 manifest + jQuery + Spring MVC.

    ResponderEliminar
  3. Thank you very much for the post!!

    ResponderEliminar
  4. thank you very much, excelent! just copy and paste and "get out with potatos". (Guille)

    ResponderEliminar