Overview :
Uploading a file from a webpage is a common task encountered in real-life projects, particularly when working with web methods and building utilities. In this tutorial, we will cover each step involved in creating a DSP page, enabling file upload functionality, and capturing the file content in a webMethods flow service.
Prerequisites :
- Basic understanding of flow services.
- Basic knowledge of DSP pages is essential. If you are new to DSP pages, click here to check out our article on DSP.
Create package structure :
- In your designer, create a package named ‘HG_DSPFileUpload‘ and follow the package structure outlined below.
- HG_DSPFileUpload
- v1
- pub
- v1
- HG_DSPFileUpload
Create a DSP page and upload the file using DSP :
- Navigate to your package’s backend folder as follows. Please note that the path below may vary depending on your installation directory.
Ex: C:\SoftwareAG\IntegrationServer\instances\default\packages\HG_DSPFileUpload\pub - Create a file with the name ‘fileUpload.dsp‘ in the pub folder.
- In a DSP page, we need to include HTML content along with DSP syntax to implement file upload functionality and capture the file content.
- In Designer, navigate to the ‘HG_DSPFileUpload‘ package and create a flow service inside the ‘pub‘ folder named ‘getUploadedFileContent‘. This service will be used to extract the file content and process it.
- Edit the ‘fileUpload.dsp‘ file and insert the following HTML code to enable file upload functionality from the user interface.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Upload File Example</title> </head> <body> <h2>Upload a File</h2> <form action="/invoke/HG_DSPFileUpload.v1.pub:getUploadedFileContent" method="POST" enctype="multipart/form-data"> <input type="file" name="fileToUpload" id="fileToUpload"> <br> <input type="submit" value="Upload File" name="submit"> </form> </body> </html>
- In webMethods Integration Server, the /invoke/ prefix is commonly used to denote the invocation of a service. The portion of the URL following /invoke/ represents the full path to the specific service that will be invoked. Therefore, in the provided example, HG_DSPFileUpload.v1.pub:getUploadedFileContent is the full path of the service that will be invoked when the form is submitted.
- method=”POST”: This attribute specifies the HTTP method that will be used when submitting the form data. In this case, it’s set to POST, indicating that the form data will be sent to the server using the HTTP POST method.
- enctype=”multipart/form-data”: This attribute specifies how the form data should be encoded before it is sent to the server. multipart/form-data is used when the form includes file uploads, allowing binary data, such as files, to be included in the form data. This is essential for handling file uploads correctly.
Capture file content in the flow service :
- In Designer, navigate to the ‘getUploadedFileContent‘ flow service located within the ‘pub‘ folder of the HG_DSPFileUpload package.
- Implement a try-catch block inside the getUploadedFileContent service to handle any exception.
- In the input of the service create a variable of type object and name it ‘contentStream‘.
Before proceeding with the actual implementation, it’s important to have a basic understanding of MIME. Refer to below for a basic overview.
MIME :
MIME (Multipurpose Internet Mail Extensions) is a standard for formatting non-text messages in email systems. It was originally developed to allow email messages to include different types of content beyond simple text, such as images, audio, video, and binary data.
- Content Types: MIME defines a set of content types that specify the nature of the data being transmitted. Common content types include text/plain (plain text), text/html (HTML-formatted text), image/jpeg (JPEG image), audio/mpeg (MPEG audio), video/mp4 (MP4 video), application/pdf (PDF document), and many more.
- Multipart Messages: MIME allows messages to contain multiple parts with different content types. This is particularly useful for email messages that include both text and attachments. Multipart messages consist of a boundary string that separates the different parts.
- Headers: MIME headers provide metadata about the content being transmitted. These headers include information such as the content type, character set, content-encoding, and other parameters necessary for proper interpretation of the content.
- Encoding: MIME supports various encoding methods to ensure that binary data and non-ASCII characters can be transmitted safely over email systems. Common encoding methods include Base64 for binary data and quoted-printable for text with special characters.
- Transfer Encodings: MIME defines transfer encodings that specify how data is encoded for transmission over different transport protocols. Common transfer encodings include 7bit, 8bit, binary, and quoted-printable.
- Extensions: Over time, MIME has been extended to support additional features and requirements beyond email, such as HTTP content types and attachments in web applications.
Try block implementation :
- Invoke ‘pub.flow:getTransportInfo‘ to extract the mime header details.
- Invoke the ‘pub.mime:mergeHeaderAndBody‘ service and perform the following mapping. This will reassemble the message into its original form.
- transport/http/requestHdrs ->headerLines.
- contentStream ->body/stream.
- Invoke ‘pub.mime:createMimeData‘ service and perform the below mapping. this will create a MIME object containing the elements (header fields and content) from the MIME message in input.
- stream ->input.
- Invoke ‘pub.mime:getBodyPartContent‘ service and perform the below mapping to retrieve content from a multi-part message using its index.
- mimeData->mimeData.
- index -> In our case it is ‘0’ but if you are collecting multiple from the user interface then you need to put the sequence here, it starts from 0.
- Invoke ‘pub.io:streamToString‘ and follow the below mapping to convert the stream to string.
- content ->inputStream.
- Invoke ‘pub.flow:debugLog‘ and directly map the string to ‘message‘.
- Now, we need to send a response to the user interface. Invoke ‘pub.flow:setResponseHeader‘ and follow the mapping below to set the header. Then, we will set the message.
- fieldName -> hardcode ‘content-disposition‘.
- fieldValue -> hardcode ‘inline;’.
- Invoke ‘pub.flow:setResponse2‘ and follow the below mapping to send the message to UI.
- responseString -> hardcode the message that you want to send to UI.
- contentType ->text/plain.
Catch block implementation :
- Invoke ‘pub.flow:getLastError‘ to catch the exception thrown.
- Invoke ‘pub.flow:setResponseHeader‘ and ‘pub.flow:setResponse2‘, and perform the same kind of implementation as in the try block. However, in the ‘responseString‘ parameter of ‘pub.flow:setResponse2‘, include the error that was thrown.
Testing :
- Navigate to the below URL and upload a text file, you will see the content printed in the server log.
For example, the URL could be http://localhost:5555/HG_DSPFileUpload/fileUpload.dsp, although please note that this URL may vary depending on the server, package name, and the DSP file name.
Download source code from Git Hub.
Hope you have enjoyed this article, Cheers!