Virgo Homepage


This guide is inspired by "Getting Started - Uploading Files" from the Spring Guides.

Multi-part file uploads

The original guide uses Spring Boot to bootstrap the demo application. This guide walks through the necessary additional steps/configuration to get "Uploading Files" up and running on Virgo.

Shopping list

Only Virgo Server for Apache Tomcat and Virgo Jetty Server are supported by the Virgo Tooling.



Install the Virgo server let’s say into VIRGO_HOME. Start your Spring Tool Suite™ and add the Virgo Tooling to your IDE.

For the impatient: This is the update site URL:

"Define a new server" within the IDE and choose the directory of the previously chosen Virgo installation VIRGO_HOME.

Clone the code from Sample Applications with Git.

git clone git://

Afterwards "Import (Existing Maven Projects)" living inside the folder guide-uploading-files into your IDE.

Before you can drag’n’drop the project onto your freshly created Virgo Server you have to Virgo → Add OSGi Project Bundle Nature (via a right click on the project) within your IDE.


Virgo has no support for Springs @EnableAutoConfiguration. Thus you have to be explicit where Spring Boot configures the embedded Tomcat with reasonable defaults on your behalf. Last but not least Virgo is an OSGi runtime and every bundle needs to be explicit about its needs in the META-INF/MANIFEST.MF.

This is mostly about specifying necessary Import-Package and the Web-ContextPath the file upload application wants to be published.

Import-Bundle: org.springframework.beans,
Web-ContextPath: /upload-guide[]

You can mix and match the Virgo specific header Import-Bundle and OSGi standard header Import-Package within the MANIFEST.MF. In the sample the fine-tuning of the MANIFEST.MF is done within the Maven pom.xml.

If you intend to run your bundles in different OSGi containers you have to limit yourself to the OSGi standard headers.

Next step is to configuring the servlet container via WEB-INF/web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="" xmlns:xsi=""
	xsi:schemaLocation="" version="2.4">

    <!-- The definition of the Root Spring Container shared by all Servlets and Filters -->


    <!-- Creates the Spring Container shared by all Servlets and Filters -->

    <!-- Processes application requests -->


Most important the contextClass which is not the default from the Spring Framework, but

Finally the Spring web application context. Nothing Virgo specific here:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns=""
	xmlns:xsi="" xmlns:beans=""

	<!-- Enables the Spring MVC @Controller programming model -->
	<annotation-driven />

	<context:component-scan base-package="org.eclipse.virgo.guides.uploading" />

	<beans:bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
		<beans:property name="messageConverters">
				<beans:bean id="byteArrayMessageConverter" class="org.springframework.http.converter.ByteArrayHttpMessageConverter" />

	<!-- Configure the multipart resolver -->
	<beans:bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
		<!-- one of the properties available; the maximum file size in bytes -->
		<beans:property name="maxUploadSize" value="50000000" />


Let’s taste

For easy client-side consumption of the file upload you can use the FileUploader.

package org.eclipse.virgo.guides.uploading.internal;


import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

public class FileUploader {

    public static void main(String[] args) throws FileNotFoundException {
        if (args.length == 0) {
            System.out.println("Usage: Requires the name of a file to upload.");

        RestTemplate template = new RestTemplate();
        MultiValueMap<String, Object> parts = new LinkedMultiValueMap<String, Object>();
        parts.add("name", args[0]);
        parts.add("file", new FileSystemResource(args[0]));
        String response = template.postForObject("http://localhost:8080/upload-guide/upload",
        			parts, String.class);
Please see the original guide "Getting Started - Uploading Files" for more background information about this client.

There is an easy way to use the FileUploader with Maven:

$ mvn package exec:java

Or if you are more used to curl and the command line simply run the following command within the project’s directory.

$ curl -F "name=sample.txt" -F "file=@sample.txt" http://localhost:8080/upload-guide/upload

Either way you should see the following output independent of your choice:

You successfully uploaded sample.txt into sample.txt-uploaded !