Using REST Services to manage download and upload of files

User Rating: 4 / 5

Star ActiveStar ActiveStar ActiveStar ActiveStar Inactive
 

This tutorial is a quick guide for handling files upload and download using REST Services. We will demonstrate how to upload a file using a Client API which will be received by a REST Service. In the second part of it we will show to download a file from a REST Service.

Uploading a file using a REST Service

In order to upload, we will be using some RESTEasy and Apache IO Utility classes. The core WS method is named "/upload" and consumes a multipart/form-data. Within this method we collect the File which will be named as "attachment" on the upload client. two utility methods are included:

  • getFileName: extracts the file name from the Header
  • writeFile: writes the file to disk
public class RestFilesDemo  {
    @POST
    @Path("/upload")
    @Consumes("multipart/form-data")
    public Response uploadFile(MultipartFormDataInput input) throws IOException {
         
        Map<String, List<InputPart>> uploadForm = input.getFormDataMap();

        // Get file data to save
        List<InputPart> inputParts = uploadForm.get("attachment");

        for (InputPart inputPart : inputParts) {
            try {

                MultivaluedMap<String, String> header = inputPart.getHeaders();
                String fileName = getFileName(header);
  
                // convert the uploaded file to inputstream
                InputStream inputStream = inputPart.getBody(InputStream.class,
                        null);

                byte[] bytes = IOUtils.toByteArray(inputStream);
                // constructs upload file path
                fileName = "/home/user/Downloads/" + fileName;
                writeFile(bytes, fileName);

                 
                return Response.status(200).entity("Uploaded file name : " + fileName)
                        .build();

            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    private String getFileName(MultivaluedMap<String, String> header) {

        String[] contentDisposition = header.getFirst("Content-Disposition").split(";");

        for (String filename : contentDisposition) {
            if ((filename.trim().startsWith("filename"))) {

                String[] name = filename.split("=");

                String finalFileName = name[1].trim().replaceAll("\"", "");
                return finalFileName;
            }
        }
        return "unknown";
    }

    // Utility method
    private void writeFile(byte[] content, String filename) throws IOException {
        File file = new File(filename);
        if (!file.exists()) {
            System.out.println("not exist> " + file.getAbsolutePath());
            file.createNewFile();
        }
        FileOutputStream fop = new FileOutputStream(file);
        fop.write(content);
        fop.flush();
        fop.close();
    }
}	

 And now the client side: at first we will use a simple HTML form with a file component in it:

<form method="post" action="http://localhost:8080/RESTDemo/rest/upload" enctype="multipart/form-data">
	<input type="hidden" name="action" value="upload" />
	<label>Load your file:</label>
	<input type="file" name="attachment" />
	<br />
	<input type="submit" value="Upload file" />
</form>

Please note that the file component name ("attachment") needs to match with the information extracted from the REST Service.

Now another example which uses Apache http utils package to send the file using a POST request:

package client;

import java.io.File;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.impl.client.DefaultHttpClient;

public class RESTClient {
    
    public static void main(String args[]) throws Exception {
        File f = new File("/home/jboss/myfile.txt");
        sendFile(f);
    }
    public static void sendFile(File file) throws Exception 
    {
	String BASE_URL="http://localhost:8080/RESTDemo/rest/upload";
        HttpClient client = new DefaultHttpClient() ;
        HttpPost postRequest = new HttpPost (BASE_URL) ;
        try
        {
        	
            //Set various attributes 
            MultipartEntity multiPartEntity = new MultipartEntity () ;
           
           // multiPartEntity.addPart("fileName", new StringBody(file.getName() != null ? file.getName() : file.getName())) ;
  
            FileBody fileBody = new FileBody(file, "application/octect-stream") ;
            //Prepare payload
            multiPartEntity.addPart("attachment", fileBody) ;
  
            //Set to request body
            postRequest.setEntity(multiPartEntity) ;
             
            //Send request
            HttpResponse response = client.execute(postRequest) ;
             
            //Verify response if any
            if (response != null)
            {
                System.out.println(response.getStatusLine().getStatusCode());
            }
        }
        catch (Exception ex)
        {
            ex.printStackTrace() ;
        }
    }
}

Downloading a file using a REST Service

You can use REST Service as downloading mechanism as well. In this case, we will just require to wrap a file with the Response object and Producing the correct Stream for the client. Since we return a JAR file, it will be an APPLICATION_OCTET_STREAM:

@GET
@Path("/jar")
@Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response downloadFile() {
	File file = new File("/home/user/Downloads/classes.jar");
	ResponseBuilder response = Response.ok((Object) file);
	response.header("Content-Disposition", "attachment;filename=classes.jar");
	return response.build();
}

Downloading the file from the Client side can be done with a variety of options. Here is my download client which I use to download a JAR class file:

public static void downloadUpdate() {
	String BASE_URL="http://localhost:8080/RESTDemo/rest/jar";

	Client client = ClientBuilder.newClient();

	
	try {
		URL website = new URL(BASE_URL);
		ReadableByteChannel rbc = Channels.newChannel(website.openStream());
		FileOutputStream fos = new FileOutputStream("classes.jar");
		fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);

	} catch ( Exception ex) {
	ex.printStackTrace();
	}  
	 
}

Follow us on Twitter