View source | View content page | Page history | Printable version   

Projects:Process File upload Reference/Specs

Contents

Overview

Screenshot from 2021-11-26 13-16-57.png

This project adds a new Reference in Openbravo core that let us upload files in Process Definitions and receive them in the server to process them.

Usage

File upload fields can be added to Process Definitions by creating a new parameter using the Process File Upload Reference.

Bulbgraph.png   Process File Upload Reference is meant to be used only in Process Definitions. If you try to set this reference to a Standard Window field, it will show an error message.

When a Process contain file upload widgets, form data will be sent using a multipart/form-data request. Server's ActionHandler is aware of that and will parse the request parameters properly. For each file field sent, server will expose a parameters in the parameters map provided in doExecute(parameters, content) function containing a map with the file content as a steam an additional information.

For example, for a Process File Upload field named 'myfile', a parameter will be exposed as a Map with the following info:

myfile: {
  content: <java.io.InputStream>, // the file content as a stream
  fileName: <String>, // the file name
  size: <long> // file size in bytes
}
 

File size limitation

The maximum file size users are allowed to upload are limited by default to 10MB. This is set in the preference Maximum Process File Upload size (MB). This file size check is performed both on the client and in the server side.

Implementation

Client side

Our file upload form field isc.OBProcessFileUpload inherits from Smartclient's isc.FileItem that wraps the <input type="file"> element within a multipart/form-data form that will contain the uploaded file's info. Smartclient's DynamicForm refers to this form using the following call:

view.theForm.getFileItemForm();

This can be used to determine whether it is a normal Process call or it may contain a file to upload. In the latter case we need to set the Process request type to multipart/form-data in order to be able to embed the uploaded file and the original file name. This logic is handled by ob-parameter-window-view.js in the actionHandlerCall function:

  const hasFileItems = view.theForm.getFileItemForm();
  if (hasFileItems) {
    // Create a new FormData object that contains the Process parameters and 
    // the file info in those fields that are FileItems
    // Then make the multipart request using fetch
    fetch(actionHandler, { method: 'POST', body: formData}).then(...)
  }
  else {
   // Has no files to upload. Handle as a normal Process
   OB.RemoteCallManager.call(...);
  }
Bulbgraph.png   Note that fetch() is used to send the multipart request. This function is not supported by Internet Explorer 11. caniuse.com/fetch

Server side

As mentioned before, in order to send files to the server, we should switch from a content-type=application/json request that does not support file upload to use a content-type=multipart/form-data request.

This implies that the request sent by the client changes from:

<server_url>/org.openbravo.client.kernel?processId=X&reportId=null&windowId=null&_action=Y

{
  "_buttonValue": "DONE",
  "_params": {
    "text": "value"
  }
}

To this in multiform/form-data:

<server_url>/org.openbravo.client.kernel?_action=Y

myfile: (binary)
processId: X
reportId: null
windowId: null
paramValues: {
    "_buttonValue":"DONE", 
    "_params":{
        "text":"value", 
        "myfile":"C:\\fakepath\\file.png"
    }
}

As you can see we can move processId, reportId and windowId to the multipart payload, and what was the JSON content of the request, it is now contained in the parameter paramValues. That change requires an extension to the server ActionHandler to support this new type of request.

To do that in the most flexible way, we refactored BaseActionHandler.java execute method to split its logic in individual methods that can be extended by children classes:

  public void execute() {
    //This method first extract the parameters from the Request object
    Map<String, Object> parameters = this.extractParametersFromRequest(request);
    //Also extract the request content as an String
    String content = this.extractRequestContent(request, parameterMap);
    // Call the execute method passing the parsed parameters and content
    JSONObject result = this.execute(parameters, content);
    // Finally write the response object
    this.writeResponse(parameterMap, result, request, response); 
  }

These individual calls are extended in BaseProcessActionHandler.java to change their implementation depending on whether the request is multipart or not. This can be determined using the following call:

boolean isMultipart = ServletFileUpload.isMultipartContent(request);

Retrieved from "http://wiki.openbravo.com/wiki/Projects:Process_File_upload_Reference/Specs"

This page has been accessed 256 times. This page was last modified on 10 January 2022, at 07:52. Content is available under Creative Commons Attribution-ShareAlike 2.5 Spain License.