This 'How To' entry will show how to handle uploading files for the common scenario of uploading and displaying images. You should be able to use the details provided below, and in the attached files to achieve any upload requirements.
The Scenario
This entry will discuss how to allow the user to upload their own image file, which will then be displayed on a page within the application.
One of the first things to consider when dealing with file uploads is how the file data will be stored and manipulated. In this example, the image data will be base64 encoded, and then inserted into the XML message along with all the other form data.
Your xml data will need to contain an XML element such as: <image type="" filename="">... your image data encoded as base64 ....</image>. This should ensure the data is captured correctly when you send it from the form. Note: The element name can be changed, but the java code would need alteration if the attribute names need to be changed
To achieve the required functionality, a number of elements need to be correctly configured:
1. Jars within the Runtime Environment
The first step is to ensure the necessary jars are available in your runtime webapps "lib" directory. The following jar files are required: APACHE: commons-io-1.3.2.jar , commons-fileupload-1.2.jar , HYFINITY: xgate_custom_plugin-fileupload.jar (if you customize the provided java code, then you would replace this jar with your customizations.)
The file are attached to this entry. It is possible the first two jars are already present in your MVC deployment. Alternatively the most up to date jars can be obtained from the Apache website.
http://commons.apache.org/
2. Configuration Settings for the Runtime Web Application
The next stage is to configure the web application configuration settings to enable the server-side processing to be invoked to handle the necessary processing.
Within the runtime platform, the servlet that handles the incoming requests is called XGate. To ensure this correctly processes the file upload (multipart) requests between the Browser and the Server, we need to add two components. The first is a "ServletFilter" that intercepts the Browser requests, and formats them if necessary (eg if it is a multipart request) so that XGate can process them correctly. In order for this to be picked up, it needs to be referenced from your webapps\....\WEB-INF\web.xml as shown in the example file attached.
Copy the <filter> and <filter-mapping> elements. You will need to change the <servlet-name> value to match the name you already have in your web.xml for your web application.
The second configuration item is to define that the XGate custom plugin which processes the files and inserts them into the XML data is activated. Note: An example is provided in the FileUploadTestPlugin.java file if you wish to extend it. In order for this to be recognized, it needs to be declared in the xgate.xml file within your runtime webapps "doc" directory, as shown in the included example file. Copy the <custom_plugins> element.
3. Setting up the Skin Details
Now it is time to setup the necessary details in the FormMaker Studio to enable the File Upload plugin to be used within your Web Application.
The custom_plugin code provided handles each request on the way in to the platform (to check for any files contained within it) and also on the way out to the browser (to check if any file information needs to be saved out). In order for this second part to work correctly, the encoded file information needs to be maintained through the page rendering transform so that the plugin has access to it.
The example plugin provided is looking for this information under a <files> element within the HTML tag. To enable this to be present you could add some processing to the skin file or into the actual page. This will largely depend on how generic you want to make the processing.
The example xsl fragment below is checking for any <image> elements in the XML data and then places them within a <files> element under the HTML tag. The plugin will ensure that the contents of any matches are base64 decoded and saved out to the provided @filename relative URL within the webapps directory.
The skin file can be selected from the advanced options on the Application Map screen in FormMaker and then edited to insert the fragment below. It is recommended that this fragment is inserted below the </body> element in the skin.
Note: Please ensure that you add any namespace prefixes that are needed to identify where the XML element will be located in your XML data. The XPaths above will look for any xml element called image and perform the necessary processing.
Once the skin has been prepared the final step is to add the necessary form controls to the Form/Page.
4. Setting up the Form Field Controls
Within FormMaker you need to add the file upload control to the page. This is done by adding a Custom Field on the Page Structure tab in FormMaker. When you have added the custom field in the correct location on your page, you can use the Field Details screen to define its contents.
You will want to enter the following type of content:
This creates the file input control (called myfile in this case), sets the correct encoding on the form, and sets up the file contents to be bound to the image element within the contact xml structure in this case. Note: You can change the myfile name to any value you want to use. You will also need to change the XPath value to the location of the element in the XML data that is sent from your web page when the XHTML is submitted to the server. This is used to perform the necessary server-side data binding.
To correctly display the image, you now need to add an image field to your page structure. The Image field will need to have the dynamic URL option selected. On the Data Bindings page, you now need to ensure this image picks up the correct relative URL value to display. This is done by pointing the Field Value binding for this field to the appropriate filename attribute.
Our skin changes above have already ensured that the file content will be saved out to this temporary location so that it can be correctly accessed.
This should provide you with all the steps to get the File Upload capability to work on a Form/Page.
Further Customisation options
This example shows how to get a basic file upload and display scenario working. The example code can however be customized as needed to achieve the required functionality.
For example, the provided code provided makes use of the Apache Commons FileUpload package (http://commons.apache.org/fileupload/). This provides control over how the uploads are actually handled and allows setting of max file sizes, etc. which can be changed in FileUploadRequestWrapper.java as needed.
This example will insert the data into the required XML data structure as specified by the binding XPath added within the Custom field hidden INPUT element. This can be altered to bind the data to a different location. Alternatively, if you wish to save the files out to a directory for example, the code in the FileUploadTestPlugin.java can be altered as required.
Update 10 August 2016: The code in the attached zip file has been updated to resolve an issue where multi select type controls would not submit all selected values when a file was also being uploaded.
The Scenario
This entry will discuss how to allow the user to upload their own image file, which will then be displayed on a page within the application.
One of the first things to consider when dealing with file uploads is how the file data will be stored and manipulated. In this example, the image data will be base64 encoded, and then inserted into the XML message along with all the other form data.
Your xml data will need to contain an XML element such as: <image type="" filename="">... your image data encoded as base64 ....</image>. This should ensure the data is captured correctly when you send it from the form. Note: The element name can be changed, but the java code would need alteration if the attribute names need to be changed
To achieve the required functionality, a number of elements need to be correctly configured:
- Jars within the Runtime Environment
[/*][*] Configuration settings for the Runtime Web Application
[/*][*] Setting up the Skin Details
[/*][*] Setting up the Form Field Controls [/*]
1. Jars within the Runtime Environment
The first step is to ensure the necessary jars are available in your runtime webapps "lib" directory. The following jar files are required: APACHE: commons-io-1.3.2.jar , commons-fileupload-1.2.jar , HYFINITY: xgate_custom_plugin-fileupload.jar (if you customize the provided java code, then you would replace this jar with your customizations.)
The file are attached to this entry. It is possible the first two jars are already present in your MVC deployment. Alternatively the most up to date jars can be obtained from the Apache website.
http://commons.apache.org/
2. Configuration Settings for the Runtime Web Application
The next stage is to configure the web application configuration settings to enable the server-side processing to be invoked to handle the necessary processing.
Within the runtime platform, the servlet that handles the incoming requests is called XGate. To ensure this correctly processes the file upload (multipart) requests between the Browser and the Server, we need to add two components. The first is a "ServletFilter" that intercepts the Browser requests, and formats them if necessary (eg if it is a multipart request) so that XGate can process them correctly. In order for this to be picked up, it needs to be referenced from your webapps\....\WEB-INF\web.xml as shown in the example file attached.
Copy the <filter> and <filter-mapping> elements. You will need to change the <servlet-name> value to match the name you already have in your web.xml for your web application.
The second configuration item is to define that the XGate custom plugin which processes the files and inserts them into the XML data is activated. Note: An example is provided in the FileUploadTestPlugin.java file if you wish to extend it. In order for this to be recognized, it needs to be declared in the xgate.xml file within your runtime webapps "doc" directory, as shown in the included example file. Copy the <custom_plugins> element.
3. Setting up the Skin Details
Now it is time to setup the necessary details in the FormMaker Studio to enable the File Upload plugin to be used within your Web Application.
The custom_plugin code provided handles each request on the way in to the platform (to check for any files contained within it) and also on the way out to the browser (to check if any file information needs to be saved out). In order for this second part to work correctly, the encoded file information needs to be maintained through the page rendering transform so that the plugin has access to it.
The example plugin provided is looking for this information under a <files> element within the HTML tag. To enable this to be present you could add some processing to the skin file or into the actual page. This will largely depend on how generic you want to make the processing.
The example xsl fragment below is checking for any <image> elements in the XML data and then places them within a <files> element under the HTML tag. The plugin will ensure that the contents of any matches are base64 decoded and saved out to the provided @filename relative URL within the webapps directory.
The skin file can be selected from the advanced options on the Application Map screen in FormMaker and then edited to insert the fragment below. It is recommended that this fragment is inserted below the </body> element in the skin.
<xsl:if test="/mvc:eForm/mvc :D ata//ns1:image" xmlns:ns1=...yourNamespaceValue...">
<files xmlns="">
<xsl:for-each select="/mvc:eForm/mvc :D ata//ns1:image">
<xsl:copy-of select="."/>
</xsl:for-each>
</files>
</xsl:if>
Note: Please ensure that you add any namespace prefixes that are needed to identify where the XML element will be located in your XML data. The XPaths above will look for any xml element called image and perform the necessary processing.
Once the skin has been prepared the final step is to add the necessary form controls to the Form/Page.
4. Setting up the Form Field Controls
Within FormMaker you need to add the file upload control to the page. This is done by adding a Custom Field on the Page Structure tab in FormMaker. When you have added the custom field in the correct location on your page, you can use the Field Details screen to define its contents.
You will want to enter the following type of content:
<input name="myfile" id="myfile" type="file"/>
<script type="text/javascript">document.getElementById('myfile').form.encoding= 'multipart/form-data' </script>
<input name="myfile_xpath" type="hidden" value="/ns1:contact/ns1:image"/>
This creates the file input control (called myfile in this case), sets the correct encoding on the form, and sets up the file contents to be bound to the image element within the contact xml structure in this case. Note: You can change the myfile name to any value you want to use. You will also need to change the XPath value to the location of the element in the XML data that is sent from your web page when the XHTML is submitted to the server. This is used to perform the necessary server-side data binding.
To correctly display the image, you now need to add an image field to your page structure. The Image field will need to have the dynamic URL option selected. On the Data Bindings page, you now need to ensure this image picks up the correct relative URL value to display. This is done by pointing the Field Value binding for this field to the appropriate filename attribute.
Our skin changes above have already ensured that the file content will be saved out to this temporary location so that it can be correctly accessed.
This should provide you with all the steps to get the File Upload capability to work on a Form/Page.
Further Customisation options
This example shows how to get a basic file upload and display scenario working. The example code can however be customized as needed to achieve the required functionality.
For example, the provided code provided makes use of the Apache Commons FileUpload package (http://commons.apache.org/fileupload/). This provides control over how the uploads are actually handled and allows setting of max file sizes, etc. which can be changed in FileUploadRequestWrapper.java as needed.
This example will insert the data into the required XML data structure as specified by the binding XPath added within the Custom field hidden INPUT element. This can be altered to bind the data to a different location. Alternatively, if you wish to save the files out to a directory for example, the code in the FileUploadTestPlugin.java can be altered as required.
Update 10 August 2016: The code in the attached zip file has been updated to resolve an issue where multi select type controls would not submit all selected values when a file was also being uploaded.
Attachment
RE: Add a File Upload Control to a Form / Page
We have a working ReST service to accept a CSV file for populating a database table. We also have a WebMaker project that will call the service, but having problems getting the file content to the service.
I've been prototyping a WebMaker form with a file input element as suggested in this forum thread, but without the custom plugin. I'm not seeing the file content bound to the xpath upon form submission. For instance, I was thinking that I could use
<input name="myfile_xpath" type="hidden" value="/mvc:eForm/mvc :D ata/file_obj"/>
and invoke the ReST service with a reference to this xpath.
Is this a do-able approach? Any suggestions would be most helpful.
Thank you,
mike
RE: Add a File Upload Control to a Form / Page
I have made some progress with coding and configuring my application with a filter and it is grabbing file content properly from the POST-ed request. I'd like to be able to use the file upload in an AJAX Submission, but the AJAX Submission action doesn't appear to be posting the data as the Form Submission action does. Is file upload with an AJAX Submission possible?
Thank you,
Mike