Uniface 9.6.04 web dropzone integration

Author: jtsagara@logisoft.gr (jtsagara)

Nowadays we develop a small application for uploading files from web. Of course as already you know the “theoretical” approach with Uniface was straight forward, so we choose a nice good looking component like this dropzone.js (http://www.dropzonejs.com/) and then tried to embed this in Uniface web development. To be honest this was quite easy with only one exception regarding the file size of the uploaded files. First of all we build the routine that attach the drop zone in Uniface : ;-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ;Init DropZone @ InitObject ;-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- WebOperation InitDropZone ;-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Scope Input Output EndScope ;-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ;Only Java Script In Web Operations Dear javascript //;Init DropZone $("<dzDivName>").dropzone({ url: "<dzUrlPost>", method: "put", paramName: '<dzCallBack>', clickable: true, maxFilesize: <dzMaxFS>, parallelUploads: 1, //; Init Function init: function() { //;Create Event added File this.on("addedfile", function(file) { //; Create the remove button var removeButton = Dropzone.createElement("<button style='width: 100%;margin-top: 5px;'><dzRemButLab></button>"); //; Capture the Dropzone instance as closure. var _this = this; //; Listen to the click event removeButton.addEventListener("click", function(e) { //; Make sure the button click doesn't submit the form e.preventDefault(); e.stopPropagation(); //; Remove the file preview. _this.removeFile(file); //; Delete The File From Uniface uniface.getInstance("<ThisDSP>").activate("remupload" , file.name); }); //; Add the button to the file preview element. file.previewElement.appendChild(removeButton); }); //; Create Event Send File this.on("sending", function(file, xhr, formData) { //; Will send the md5 Path along with the file as POST data formData.append("md5", uniface.getInstance("<ThisDSP>").getEntity("<dzPathEnt>").getOccurrence(0).getField("<dzPathFld>").getValue()); }); } }); endjavascript ;-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- End ;Of WebOperation InitDropZone ;-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- As you can see we choose the jquery way to attach the dropzone in a division like this: <!-- New File Selection Zone --> <div class="container" style="padding-top: 5px;"> <div class="col-xs-12 col-sm-12 col-md-12 center-block"> <form target="" action="" enctype="multipart/form-data" method="post" name="filename" id="editdropzone" class="dropzone center-block"> <input type="hidden" name="md5" value=""> <h1 class="blue dz-message"><span id="ufld:WT00039.WEBLAB.DUM_MODEL">Static Text</span></h1> </form> </div> </div> For portability reasons we use heavily the #define : ;------------------------------------------------------------------------------------------------------------------------------------------------------------------ ;Drop Zone Defines ;------------------------------------------------------------------------------------------------------------------------------------------------------------------ #define dzDivName = #editdropzone #define dzUrlPost = ./WD004003.upload #define dzCallBack = filename #define dzMaxFS = 50 #define dzPathEnt = WEBDUM.DUM_MODEL #define dzPathFld = TEMPDIR #define dzRemButLab = Remove File ;------------------------------------------------------------------------------------------------------------------------------------------------------------------ Then we build the callback function for the multipart/form-data which is defined as Uniface operation called from the dropzone.js paramName: '<dzCallBack>' : ;-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ;Upload A File Stream To The Server ;-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Operation Upload ;-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Public Web Scope Input output EndScope ;-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- Variables String vsTempDir Any vaFileBinData EndVariables ;-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ;Get Input From Stream ( File Stream Must Implemented ) filename.webdum = $item("filename",$webinfo("input")) ;Load Bytes Array From <InputFile> Html To Ram Use $1 FileLoad/web "filename",vaFileBinData ;Check Existance Of Temporary Directory Of Upload vsTempDir = $item("md5",$webinfo("input")) If ( vsTempDir != "" & $LFileExists(vsTempDir) = 2 ) ;Dump To Disk Lfiledump/raw vaFileBinData , "%%vsTempDir%%FileName.webdum" EndIf ;Empty Buffer vaFileBinData ="" Return (0) ;-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- End ;Operation Upload ;-------------------------------------------------------------------------------------------------------------------------------------------------------------------------- As you can see we use also the hidden parameter from the multipart/form-data MD5 to pass extra information. It works like a charm for small file, even the functionality of creates thumbnails, but when we tried to upload files around 100mb a big issue appeared, it seems that the part of wrd.js that handles binary exchange of multipart forms it uses memory buffers in java instead of file buffers this resulted to heap java errors (memory allocation error) on tomcat. So the question is , why wrd.js tries to use memory for upload binary and even worse why this data are converted to binary arrays (byte[]) and occupy all the java heap pool. Is there any way to trick Uniface wrd not to use internal conversions but dump directly to tomcat temporary area and from userver to read the contents directly ? From my point of view it very easy to understand when a post/put sends a binary file , after this wrd.js must disable all the routines for char conversions ( encodings etc) and put the file in a file stream to avoid heavy memory load.

3 Comments

  1. Any ideas about this?Frown


    Author: jtsagara (jtsagara@logisoft.gr)
  2. Hi, you may pass through the wrd servlet by implementing your own upload servlet in the WEB-INF/web.xml file. For example

      <servlet>
        <servlet-name>UploadServlet</servlet-name>
        <servlet-class>servlets.UploadServlet</servlet-class>
      </servlet> 
    
      <servlet-mapping>
        <servlet-name>UploadServlet</servlet-name>
        <url-pattern>/servlets/upload</url-pattern>
      </servlet-mapping>

      put the UploadServlet.class file in WEB-INF/classes/servlets directory. and redifine the post url : #define dzUrlPost = ../servlets/upload Philippe


    Author: Philippe (philippe.grangeray@agfa.com)
  3. Hello Philippe, Yes this is a work around but considering this as function out of Uniface will result to a security hole because before upload i must check a dozen of variables in the uniface environment. From the other hand i can always send them in the request to the uploader, but if i'am starting to build java servlets what is the point to use uniface? I will write this as a wish, maybe they can implement this at Uniface 10   Thanks anyway


    Author: jtsagara (jtsagara@logisoft.gr)