Create multipart/form-data service
A multipart/form-data service can accept input from HTML form tag. It’s generally a POST call from HTML page but the payload will consist of form elements which are defined in HTML form tag. Elements are mainly of type – text or file. lets see how we can Create multipart/form-data service.
Below we have example of HTML form upload
<!DOCTYPE html> <html> <body> <p>Different type of input types:</p> <form action="http://form-upload-sample.us-e2.cloudhub.io/upload" method="post" enctype="multipart/form-data"> <label for="fname">checkbox: </label><input type="checkbox" name="checkbox"><br> <label for="fname">password: </label><input type="password" name="password"><br><br> <label for="fname">text: </label><input type="text" name="text"><br><br> <label for="fname">file: </label><input type="file" id="myfile" name="myfile"><br><br> <label for="fname">submit: </label><input type="submit" name="fileContent"><br><br> </form> </body> </html>
Here we can see different type of Forms element but all can be categorized either in Text of File type.
HTML form will act as client for our mule multipart/form-data service
Create mule application which accept request from HTML form
So in HTML form action we can put http://localhost:8081/upload as value
Mule application receive the request in parts and if we convert the payload.parts to application/json then we can understand how MuleSoft handle the request and we can target the different elements accordingly – example
{ "parts": { "checkbox": { "headers": { "Content-Disposition": { "name": "checkbox", "subtype": "form-data" } }, "content": "on" }, "password": { "headers": { "Content-Disposition": { "name": "password", "subtype": "form-data" } }, "content": "asdasd" }, "text": { "headers": { "Content-Disposition": { "name": "text", "subtype": "form-data" } }, "content": "xcvxcvxc" }, "myfile": { "headers": { "Content-Disposition": { "name": "myfile", "myfile": "Mulesy.txt", "subtype": "form-data" }, "Content-Type": "text/plain" }, "content": "\ufffdPNG" }, "fileContent": { "headers": { "Content-Disposition": { "name": "fileContent", "subtype": "form-data" } }, "content": "Submit" } } }
Accordingly if we have to capture any element value we can use –
payload.parts.<<form element name>>.content
Or by position
payload.parts[0].content
Now we will capture the checkbox and password value in our mule flow
Checkbox – where checkbox is name of HTML form element
Logger – #[“checkbox value – ” ++ payload.parts.checkbox.content]
Variable – #[ payload.parts.checkbox.content]
Password
Logger – #[“checkbox value – ” ++ payload.parts. password.content]
Variable – #[ payload.parts. password.content ]
Similarly we will add routes in Scatter Gather for different elements
As we already know, we have two type of form input – text and file. Text we already handle and now we will see how to handle File
When we receive file input three things are important – file name, file content and Content Type based on which you can process the incoming file
To understand this better we upload a PNG Image file
To capture the different values –
- File content – payload.parts.myfile.content
- File name – payload.parts.myfile.headers.”Content-Disposition”.filename
- Content Type – payload.parts.myfile.headers.”Content-Type”
we can see the captured values
Now we will write the incoming file to our location
To write – we have to write in binary only – application/octet-stream as the incoming content type is image/png otherwise we can use the same incoming content type to write a file.
payload.parts.myfile.content write “application/octet-stream”
Now if we run the application we can see the picture.png in target folder
Sample application – form-upload-sample
Form upload html – form_upload
Form upload zip – form_upload
Known issue – Most of the time we can see below error while accessing different elements in parts element. This error come more because we tried to access and convert object value to something other than MultiPart
org.mule.runtime.core.api.expression.ExpressionRuntimeException: "Expecting type is { preamble?: String, parts: { _*: { headers: Object, content: Any } } } but got String, while writing MultiPart. Trace: at main (Unknown)" evaluating expression: "payload.parts.myfile.headers."Content-Type"".
To Access this properly we can use payload.parts.myfile.headers.”Content-Type” write “application/java” to convert the Multipart value to Java.
Is it possible to create jks file in mule?
Great Content! Wonderful blog
Is it possible to upload a .zip file like this?