In this post, you’ll learn how to provide support for file uploads by using a multipart form with Servlet 3.0. Then, we’ll use Tomcat 7’s new alias feature to provide access to our statically-hosted content outside of your WAR file.
Step 1: Sign up for OpenShift Online
If you don’t already have an OpenShift account, head on over to openshift.com and create an account. Red Hat’s OpenShift Online service offers a free application hosting tier, providing each user with three Gears or application containers. At the time of this writing, the combined resources allocated for each user is 1.5 GB of memory and 3 GB of disk space.
Step 2: Install the client tools on your machine
The OpenShift rhc (Red Hat Cloud) command-line tools are written in Ruby, and are installable via RubyGems. With OSX 10.6 or later and most Linux distributions, ruby and RubyGems are available by default, so installing the rhc client tool is a snap:
sudo gem install rhc
Step 3 : Configure your development environment
Run rhc setup to link your local development environment to your OpenShift Online account, setup your ssh keys, and select your applications namespace. The namespace is a unique name per user which becomes part of your application url. For example, if your namespace is t20 and application name is tomcat7 then url of the application will be http://tomcat7–t20.rhcloud.com/. The command is shown below.
rhc setup -l openshift_login
Step 4 : Creating Tomcat 7 Application
Now you’ll be able to create a Tomcat 7 application by executing the command shown below. OpenShift provides Apache Tomcat 7 support via JBoss EWS 2.0 cartridge.
rhc app create tomcat7app tomcat-7
This will allocate our gear (or application container), and set up all of the required SELinux policies and cgroup configurations. OpenShift will also setup a private git repository for your project, and clone the repository to your local system. Finally, OpenShift will propagate the DNS to outside world.
Step 4: Writing a File Upload Servlet
The template project created by OpenShift is a very simple web application with some JSP files and pom.xml. We will start by deleting the default files generated by OpenShift in src/main/webapps folder. This includes web.xmlas well, since it’s optional with Servlet 3.0.
Next, we’ll update pom.xml to contain Servlet-3.0 spec API jar, and update Maven war plugin to create a war file even without web.xml.
Replace the pom.xml content with the one shown below. As you can see, javax.servlet-api is automatically available in your current scope, as provided by Tomcat 7. Another thing to note is the failOnMissingWebXmlconfiguration parameter in the Maven WAR plugin is set to true so that the plugin can assemble the WAR file without a web.xml.
The @MultipartConfig is used to indicate that the servlet expects requests with multipart/form-data MIME type which is required for file upload.
You can specify directory location where files will be stored using location attribute of @MultipartConfig. You’ll need to update this value for your application.
Replace the UUID 12592ddfd6824bd88a45a3dd111b2ced with UUID of your application. You can get the UUID for your application using the rhc app show command. @MultipartConfig allows you to use the request.getPartsAPI to get the parts of the request. A part is an item received within a multipart/form-dataPOST request.
The servlet shown above exposes both the GET and POST method. The GET method is used to render a form to upload the file. Create a form.jsp in your application’s src/main/webapp/WEB-INF directory:
To see this in action, commit your changes, and push them to OpenShift:
git add .
git commit -am "Adding support for uploading files with Servet 3.0 and Tomcat 7"
After git push successfully completes, open the browser and go to “https://tomcat7-$namespace.rhcloud.com/upload”, replacing $namespace with your own application namespace. This will open render a form to upload a file as shown below.
Choose a file to upload and press the “Upload File” button. After the upload is complete you will see some debug output on the screen.
<h2> Total parts : 1</h2><p>Name : file1<br>Content Type : image/gif<br>Size : 39722<br>content-type : image/gif<br>content-disposition : form-data; name="file1"; filename="OpenShift_USB.gif"<br></p>
To make sure that data was uploaded to OpenShift, you can ssh into your application gear and check to see if the file has been written:
[tomcat7-t20.rhcloud.com ~]\> cd $OPENSHIFT_DATA_DIR
[tomcat7app-t20.rhcloud.com data]\> ls
Step 5 : Using aliases to access content outside of your WAR file
Your FileUploadServlet writes data to your app’s $OPENSHIFT_DATA_DIR which is outside of the WAR file. Tomcat 7 has introduced a new concept called aliases, which will allow you to provide access to this content. This new attribute in the context element can point to a folder of static resources. OpenShift allows developers to update these tomcat configuration files. Update context.xml in the .openshift/config folder. All the Tomcat 7 configuration files exist under this folder.
<Context path="/" aliases="/static=/var/lib/openshift/12592ddfd6824bd88a45a3dd111b2ced/app-root/data"><!--Default set of monitored resources --><WatchedResource>WEB-INF/web.xml</WatchedResource><!-- Uncomment this to disable session persistence across Tomcat restarts --><!--<Manager pathname=""/>--><!-- Uncomment this to enable Comet connection tacking (provides events
on session expiration as well as webapp lifecycle)--><!--<Valve className="org.apache.catalina.valves.CometConnectionManagerValve"/>--></Context>
Assuming that the /var/lib/openshift/12592ddfd6824bd88a45a3dd111b2ced/app-root/data folder contains an image openshift.png and the context.xml file has been configured as shown above. Then you can easily access the image as https://tomcat7-t20.rhcloud.com/static/shekhar_gulati.jpg
Note : Please make sure to update the UUID 12592ddfd6824bd88a45a3dd111b2ced with your application’s UUID. You can get this information from rhc app show command.
Finally, commit the code and deploy your updates:
git add .openshift/config/context.xml
git commit -am "Providing access to statically hosted files with a Tomcat 7 alias"