Hi,
Recently I had a situation where I was supposed to upload a binary file to a server side RESTful web service created in Jersey. I faced a lot of trouble in doing so because always one or the other part of the hood was not working properly. The following post gives a step by step process as how to create a RESTful service that accepts uploaded binary files.
Pre-requisites:
1. A running RESTful service based on Jersey.
2. An HTML page with file upload component.
3. Tomcat 7 as web server.
4. Eclipse indigo.
Note: Let us suppose that tomcat is running on same machine on which the HTML client is present. So we will be using the base domain URL as 'http://localhost:8080/'. If your service and client are located on different instances of tomcat then replace the localhost part of the URL with the IP address of the machine on which the REST service is running.
Step 1 (Eclipse setup):
a. Create a 'Dynamic Web Project' in eclipse indigo. Let us say that this project is named as "REST_WS".
b. Download Jersey which is the JAX-RS implementation from location http://maven.java.net/service/local/artifact/maven/redirect?r=releases&g=com.sun.jersey&a=jersey-archive&v=1.14&e=zip
c. Extract the downloaded zip.
d. copy the jar files in the lib folder of extracted zip and paste them under the WebContent/WEB-INF/lib of your project REST_WS.
e. now the structure of WebContent/WEB-INF/lib of REST_WS should look like this:
there will be total 12 jar files as shown in figure.
This is all we need to configure Eclipse indigo to use REST.
Step 2 (Creating a REST service on Eclipse indigo):
a. After configuring the Eclipse as displayed in the step above we need to create a REST web service.
b. We will be using our project REST_WS which we have configured above to create REST web service.
c. Now create a package 'pkg.rest' under 'JavaResources/src' of project REST_WS.
d. Create a class UploadFileService.java under the package pkg.rest. The structure of REST_WS project should look like this.
e. Now add following code to UploadFileService.java
package pkg.rest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import org.apache.tomcat.util.http.fileupload.FileItem;
import org.apache.tomcat.util.http.fileupload.FileItemFactory;
import org.apache.tomcat.util.http.fileupload.FileUploadException;
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
@Path("/file")
public class UploadFileService {
@POST
@Path("/upload")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces("text/plain")
// @Consumes("application/x-www-form-urlencoded")
public String uploadFile(@Context HttpServletRequest request,
@Context HttpHeaders headers) {
System.out.println("upload executed");
String resultStatus = "fileupload error";
String fileRepository = "E:/uploaded/"; //change the location where you need to save your uploaded file.
if (ServletFileUpload.isMultipartContent(request)) {
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
// upload.setSizeMax(1073741824); //Limits the max file size (bytes)
List<FileItem> items = null;
try {
items = upload.parseRequest(request);
// upload.
} catch (FileUploadException e) {
e.printStackTrace();
}
String username = null;
for (FileItem item : items) {
if (item.isFormField()) {
System.out.println(item.getFieldName() + "="
+ item.getString());
}
if (!item.isFormField()) {
try {
// System.out.println(item.getFieldName()+"="+item.getString());
String filename = item.getName();
String dateFormat = "yyyyMMdd_HHmmss";
Calendar cal = Calendar.getInstance();
SimpleDateFormat dateFormatter = new SimpleDateFormat(
dateFormat);
String date = dateFormatter.format(cal.getTime());
item.write(new File(fileRepository + "_" + date + "_"
+ filename));
resultStatus = "fileupload success";
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
return resultStatus;
Update the line highlighted in yellow. It indicates the location where you want to save your uploaded files.
f. That is all we need to create the service. Our service has been created.
g. Now we need to configure the web.xml of REST_WS to tell the web container to use Jersey servlet. To do this we need to add following code to web.xml :
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>REST_WS</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
h. That's all from server side. We have completed the process of creating a RESTful service that accepts files uploaded by a client.
Step 3 (Creating an HTML client):
a. Now we need to create an HTML client that uploads files to the REST service created above.
b. Create any HTML file and let us name it index.html.
c. Save index.html at any location on your system. Lets save it on Desktop.
d. Add following code to index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<h1>Upload File with RESTFul WebService</h1>
<form action="http://localhost:8080/REST_WS/file/upload"
method="post"
enctype="multipart/form-data">
<p>
Choose a file : <input type="file" name="file" />
</p>
<input type="submit" value="Upload" />
</form>
</body>
</html>
Step 4 (Running the project):
a. Run your service project on eclipse as follows:
(i) Right click on your project REST_WS.
(ii) Select RunAs -> Run On Server.
Wait till server is up and running.
b. Run your client as follows:
(i) Open the file you created above (index.html) in a browser.
(ii) Browse and select any file.
(iii) Press 'Upload' button.
That is all you need to do, and your file will be uploaded to the server at the location you specified in the line highlighted in yellow above.
Recently I had a situation where I was supposed to upload a binary file to a server side RESTful web service created in Jersey. I faced a lot of trouble in doing so because always one or the other part of the hood was not working properly. The following post gives a step by step process as how to create a RESTful service that accepts uploaded binary files.
Pre-requisites:
1. A running RESTful service based on Jersey.
2. An HTML page with file upload component.
3. Tomcat 7 as web server.
4. Eclipse indigo.
Note: Let us suppose that tomcat is running on same machine on which the HTML client is present. So we will be using the base domain URL as 'http://localhost:8080/'. If your service and client are located on different instances of tomcat then replace the localhost part of the URL with the IP address of the machine on which the REST service is running.
Step 1 (Eclipse setup):
a. Create a 'Dynamic Web Project' in eclipse indigo. Let us say that this project is named as "REST_WS".
b. Download Jersey which is the JAX-RS implementation from location http://maven.java.net/service/local/artifact/maven/redirect?r=releases&g=com.sun.jersey&a=jersey-archive&v=1.14&e=zip
c. Extract the downloaded zip.
d. copy the jar files in the lib folder of extracted zip and paste them under the WebContent/WEB-INF/lib of your project REST_WS.
e. now the structure of WebContent/WEB-INF/lib of REST_WS should look like this:
there will be total 12 jar files as shown in figure.
This is all we need to configure Eclipse indigo to use REST.
Step 2 (Creating a REST service on Eclipse indigo):
a. After configuring the Eclipse as displayed in the step above we need to create a REST web service.
b. We will be using our project REST_WS which we have configured above to create REST web service.
c. Now create a package 'pkg.rest' under 'JavaResources/src' of project REST_WS.
d. Create a class UploadFileService.java under the package pkg.rest. The structure of REST_WS project should look like this.
e. Now add following code to UploadFileService.java
package pkg.rest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import org.apache.tomcat.util.http.fileupload.FileItem;
import org.apache.tomcat.util.http.fileupload.FileItemFactory;
import org.apache.tomcat.util.http.fileupload.FileUploadException;
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItemFactory;
import org.apache.tomcat.util.http.fileupload.servlet.ServletFileUpload;
@Path("/file")
public class UploadFileService {
@POST
@Path("/upload")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces("text/plain")
// @Consumes("application/x-www-form-urlencoded")
public String uploadFile(@Context HttpServletRequest request,
@Context HttpHeaders headers) {
System.out.println("upload executed");
String resultStatus = "fileupload error";
String fileRepository = "E:/uploaded/"; //change the location where you need to save your uploaded file.
if (ServletFileUpload.isMultipartContent(request)) {
FileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);
// upload.setSizeMax(1073741824); //Limits the max file size (bytes)
List<FileItem> items = null;
try {
items = upload.parseRequest(request);
// upload.
} catch (FileUploadException e) {
e.printStackTrace();
}
String username = null;
for (FileItem item : items) {
if (item.isFormField()) {
System.out.println(item.getFieldName() + "="
+ item.getString());
}
if (!item.isFormField()) {
try {
// System.out.println(item.getFieldName()+"="+item.getString());
String filename = item.getName();
String dateFormat = "yyyyMMdd_HHmmss";
Calendar cal = Calendar.getInstance();
SimpleDateFormat dateFormatter = new SimpleDateFormat(
dateFormat);
String date = dateFormatter.format(cal.getTime());
item.write(new File(fileRepository + "_" + date + "_"
+ filename));
resultStatus = "fileupload success";
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
return resultStatus;
}
}
Update the line highlighted in yellow. It indicates the location where you want to save your uploaded files.
f. That is all we need to create the service. Our service has been created.
g. Now we need to configure the web.xml of REST_WS to tell the web container to use Jersey servlet. To do this we need to add following code to web.xml :
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
<display-name>REST_WS</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>Jersey REST Service</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Jersey REST Service</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
h. That's all from server side. We have completed the process of creating a RESTful service that accepts files uploaded by a client.
Step 3 (Creating an HTML client):
a. Now we need to create an HTML client that uploads files to the REST service created above.
b. Create any HTML file and let us name it index.html.
c. Save index.html at any location on your system. Lets save it on Desktop.
d. Add following code to index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<h1>Upload File with RESTFul WebService</h1>
<form action="http://localhost:8080/REST_WS/file/upload"
method="post"
enctype="multipart/form-data">
<p>
Choose a file : <input type="file" name="file" />
</p>
<input type="submit" value="Upload" />
</form>
</body>
</html>
Step 4 (Running the project):
a. Run your service project on eclipse as follows:
(i) Right click on your project REST_WS.
(ii) Select RunAs -> Run On Server.
Wait till server is up and running.
b. Run your client as follows:
(i) Open the file you created above (index.html) in a browser.
(ii) Browse and select any file.
(iii) Press 'Upload' button.
That is all you need to do, and your file will be uploaded to the server at the location you specified in the line highlighted in yellow above.
Very well put, worked fine with the apache commons libraries.
ReplyDeleteThank you for sharing
@Miguel Aniceto: Thanks for your feedback :)
Deletethank you for that best post
ReplyDeletebut now i want to use Restfull web service to upload file in Spring Mvc
@ait baha smail: I'll be posting a tutorial on Spring soon. Thanks for your feedback.
DeleteGood post rajeev!!
ReplyDelete