File Handling(Upload/Download)

Let us try uploading a file to the server. For this we should write a service which accepts input file sent as part of http request and stores it in the server.

FileUploadService.java

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package com.example.service;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataParam;

/**
 * @author Santosh
 *
 */
@Path("/file")
public class FileUploadService {

 public FileUploadService() {

 }

 @POST
 @Path("/upload")
 @Consumes(MediaType.MULTIPART_FORM_DATA)
 public Response uploadFile(
   @FormDataParam("upload") InputStream uploadedInputStream,
   @FormDataParam("upload") FormDataContentDisposition fileDetail) {

  String uploadedFileLocation = "d://courses/uploaded/"
    + fileDetail.getFileName();

  // save it
  writeToFile(uploadedInputStream, uploadedFileLocation);

  String output = "File uploaded to : " + uploadedFileLocation;

  return Response.status(200).entity(output).build();

 }

 // save uploaded file to new location
 private void writeToFile(InputStream uploadedInputStream,
   String uploadedFileLocation) {

  try {
   OutputStream out = new FileOutputStream(new File(
     uploadedFileLocation));
   int read = 0;
   byte[] bytes = new byte[1024];

   out = new FileOutputStream(new File(uploadedFileLocation));
   while ((read = uploadedInputStream.read(bytes)) != -1) {
    out.write(bytes, 0, read);
   }
   out.flush();
   out.close();
  } catch (IOException e) {

   e.printStackTrace();
  }

 }

}


There are some new things to be noticed. First is @Consumes annotation. File is a kind of media and when we are trying to send a file to the service the service has to say that it can accept. Even the http request also will internally set the encoding type as multipart/form-data.

We want the user to upload a file via browse button. We write this jsp file for that purpose. Place this file directly under WebContent

fileupload.jsp
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<html>
<title>Upload File Demo</title>
<body>
  Upload File Demo<br/><br/>
 <form action="services/file/upload" method="post" enctype="multipart/form-data">
    File : <input type="file" name="upload" size="50" />
   <br/>
     <input type="submit" value="Upload" />
 </form>
 </body>
</html> 

Testing the file upload

Once you select a file and upload the response should like this.

Looking at the service code you will notice that the formdata is being injected into the method parameters. The input stream representing the file data is injected and the file name is also injected. Using these two you create  a new file on the server and name it accordingly.


Lets try downloading an image now. Lets write FileDownloadService.

FileDownloadService.java
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
package com.example.service;

import java.io.File;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;

/**
 * @author Santosh
 *
 */
@Path("/download")
public class FileDownloadService {

 public FileDownloadService() {

 }

 @GET
 @Path("{fileName}")
 @Produces({ "image/jpg", "image/png" })
 public Response downloadFile(@PathParam("fileName") String fileName) {

  File fileToSearch = new File("d://courses/uploaded/" + fileName);
  if (fileToSearch.exists()) {
   ResponseBuilder responseBuilder = Response
     .ok((Object) fileToSearch);
   responseBuilder.header("Content-Disposition",
     "attachment; filename=\"downloadedFile.jpg\"");
   return responseBuilder.build();
  } else {
   ResponseBuilder responseBuilder = Response.noContent();
   return responseBuilder.build();
  }
 }
}

This service is almost similar to any other service we have seen except that the @Produces annotation is set to image/jpg or image/png which means the service invocation can send to jpg or png files. Lets test this now. We will download the file we just uploaded.

The url we should specify the exact filename we uploaded. Else there wont be any result from the server as the file is not there.

No comments:

Post a Comment