Servlet: Transfer File to Desktop App
Feb 13, 2015
This article shows a Java Servlet program transfer a binary data file to a Java desktop client application.
An application with a desktop and web components has a data transfer requirement. The data is to be transferred from the web app to the client app. The web app prepares the data as a binary file and parks it at a staging area.
The client app initiates the data transfer. The client connects to the web server and invokes the servlet program. The servlet writes the file bytes to the output stream and the client reads the bytes as an input stream and creates a file.
After the file is completely transferred, the client prints a success status message. Further, the client program processes the file as needed.
The article has the sections describing the following:
- The Servlet
- The Client
- The Transfer Process Status
NOTE: The example assumes that the transfer file is a small file of 25 MB size. The application is tested in Java SE 7 and Apache Tomcat 6 environment.
1. The Servlet
The servlet program reads the supplied input file as an input stream and writes to the output stream.
Path transferFilePath = Paths.get(transferDir, "transferfile_server");
InputStream in = Files.newInputStream(transferFilePath);
The input stream's bytes are written to the servlet output stream. The output stream is for writing the binary data in the response.
ServletOutputStream out = resp.getOutputStream(); // resp is the HttpServletResponse
int i = 0;
while ((i = in.read()) != -1) { // -1 indicates end of input stream
out.write(i);
}
Writing to stream is done. Close both the streams.
1.1. The Code
The following snippet shows the servlet program's code:
public class FileTransferServlet extends HttpServlet {
private static final String TRANSFER_FILE =
"X:\\File_Transfer_Example\\transferfile_server";
@Override
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws IOException, ServletException {
boolean transferStatusOk = true;
InputStream in = null;
ServletOutputStream out = null;
Path transferFilePath = Paths.get(TRANSFER_FILE);
try {
in = Files.newInputStream(transferFilePath);
out = resp.getOutputStream();
int i = 0;
while ((i = in.read()) != -1) {
out.write(i);
}
out.flush();
}
catch (IOException e) {
transferStatusOk = false;
e.printStackTrace();
throw new ServletException(e);
}
finally {
if (in != null) {
try {
in.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
if (out != null) {
try {
out.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
} // try
// File transfer complete
if (transferStatusOk) {
// do something to the successfully transferred file
// show transfer success status in the web app
}
} // doPost()
}
2. The Client
The file data transfer is initiated from the client. The client program runs from the command prompt. The client program communicates with the webserver and the servlet using a HttpURLConnection
. This connection is used to read from the resource referenced by the servlet's URL.
URL url = new URL(servletUrl); // servletUrl is the connection URL to the servlet program
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
// specify the servlet's service method; default is GET
connection.setRequestMethod("POST");
connection.connect(); // this establishes the actual network connection
The client reads the file bytes which the servlet writes to the output stream. First, get the input stream from the connection object.
InputStream in = connection.getInputStream();
Copy all the input stream bytes to a file.
Path transferFilePath = Paths.get(transferDir, "transferfile_client");
long fileSize = Files.copy(in, transferFilePath, StandardCopyOption.REPLACE_EXISTING);
Transfer is complete. Close stream. Process file data.
2.1. The Code
The following snippet shows the client program's code:
public class FileTransferClient {
private static final String SERVLET_URL =
"http://localhost:8080/FileTransferServlet/go";
private static final String TRANSFER_FILE =
"X:\\File_Transfer_Example\\transferfile_client";
public static void main (String [] args)
throws Exception {
boolean status = true;
HttpURLConnection connection = null;
Path transferFilePath = null;
try {
connection = getConnection();
}
catch (IOException e) {
String msg =
"Error connecting to the web server application. " +
"Check if net connectivity is there. " + "Try later.";
System.out.println(msg);
e.printStackTrace();
status = false;
}
if ((status == true) && (connection != null)) {
try {
transferFilePath = getTransferFile(connection);
}
catch (IOException e) {
String msg =
"Error writing server data to the local file";
System.out.println(msg);
e.printStackTrace();
status = false;
}
}
if (connection != null) {
try {
int code = connection.getResponseCode();
String msg = connection.getResponseMessage();
msg= "Server status code: " + code + " - " + msg ;
System.out.println(msg);
}
catch (IOException e) {
e.printStackTrace();
String msg = "Error reading response status";
System.out.println(msg);
}
connection.disconnect();
}
if (status == true) {
// process transfer file
// check file size and read the file...
}
} // main()
private static HttpURLConnection getConnection()
throws IOException {
URL url = new URL(SERVLET_URL);
HttpURLConnection connection =
(HttpURLConnection) url.openConnection();
connection.setDoInput(true); // this is default
connection.setRequestMethod("POST");
connection.connect(); // establish the actual network connection
return connection;
}
private static Path getTransferFile(HttpURLConnection connection)
throws IOException {
InputStream in = connection.getInputStream();
Path transferFilePath = Paths.get(TRANSFER_FILE);
long fileSize = Files.copy(in, transferFilePath,
StandardCopyOption.REPLACE_EXISTING);
return transferFilePath;
}
}
3. The Transfer Process Status
From the start of the client program's invocation of the transfer process to the end, the status of the process is tracked. There are possibilities that something might go wrong on either client or server side. There is also a success status.
The status tracking includes using the exception handling and servlet response codes on the servlet and the client programs.
Here are some process scenarios. The client starts the process:
- The file transfer is successful.
- The server (or network connection) is not available.
- The servlet runs, but the input transfer file on server is missing.
- The server is up but the transfer servlet is missing.
There is a case when the transfer file is partially transferred. In this example, a partial file is of no use. A solution is that the transfer input file may be transferred again from the beginning.
3.1. The File Transfer is Successful
3.1.1. The Client
The following is the output at the command prompt.
*** Transfer process begin. ***
Connecting to the server
Connected to the server
Writing transfer file from server to local storage
Writing complete. Number of bytes written: 471
Server status code: 200 - OK
*** Closing transfer process ***
Note the servlet response code 200 indicating the ok status. The HttpURLConnection
's getResponseCode()
and getResponseMessage()
methods retrieve the code and its message description. These status code descriptions are listed in the HttpServletResponse
API and in the HttpURLConnection
API javadoc.
The main steps of the client program are: getting the connection, getting an input stream and writing to a file. Note that the client program throws one exception for all the APIs used - IOException
or its sub-classes.
3.1.2. The Server
The following output can be viewed on the web server console or in the log files.
*** Transfer process begin. ***
Getting input stream
Getting output stream
File transfer complete.
*** Closing transfer process ***
The main steps of the servlet are: get an input stream for the transfer file and write to the servlet output stream. These two operations throw IOException
.
The servlet sets an OK status on the response, by default automatically (this need not be specified unless the programmer intends to set a code or the when there are exceptional cases the system/webserver sets appropriate codes). Note that the status is set before the output is written.
3.2. Server (or Network Connection) is Not Available
The client starts the process, and the server (or network connection) is not available.
3.2.1. The Client
The following is the output at the command prompt.
*** Transfer process begin. ***
Connecting to the server
Error connecting to the web server application.
Check if net connectivity is there. Try later.
java.net.ConnectException: Connection refused: connect
...
at sun.net.www.protocol.http.HttpURLConnection.connect
(HttpURLConnection.java:849)
at FileTransferClient.getConnection(FileTransferClient.java:97)
at FileTransferClient.main(FileTransferClient.java:30)
*** Closing transfer process ***
From the Java API's javadoc: java.net.ConnectException
is a subclass of java.net.SocketException
and java.io.IOException
. This signals that an error occurred while attempting to connect a socket to a remote address and port. Typically, the connection was refused remotely (e.g., no process is listening on the remote address/port).
3.2.2. The Server
There is no server error possible in this scenario.
3.3. No File on Server
The client starts the process and the servlet runs, but the input transfer file on server is missing.
3.3.1. The Client
The following is the output at the command prompt.
*** Transfer process begin. ***
Connecting to the server
Connected to the server
Error writing server data to the local file
java.io.IOException: Server returned HTTP response code: 500 for URL:
http://localhost:8080/FileTransferServlet/go
at sun.net.www.protocol.http.HttpURLConnection.getInputStream
(HttpURLConnection.java:1625)
at FileTransferClient.getTransferFile(FileTransferClient.java:111)
at FileTransferClient.main(FileTransferClient.java:48)
Server status code: 500 - Internal Server Error
*** Closing transfer process ***
Note the server status code 500.
- From the
HttpURLConnection
API's javadoc the variable HTTP_INTERNAL_ERROR: HTTP Status-Code 500: Internal Server Error. - From the
javax.servlet.http.HttpServletResponse
API's javadoc the variable SC_INTERNAL_SERVER_ERROR: Status code (500) indicating an error inside the HTTP server which prevented it from fulfilling the request.
3.3.2. The Server
The following output can be viewed on the web server console or in the log files.
SEVERE: Servlet.service() for servlet FileTransferServlet threw exception
java.nio.file.NoSuchFileException:
X:\File_Transfer_Example\transferfile_server
...
at app.FileTransferServlet.doPost(FileTransferServlet.java:36)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
Note the exception java.nio.file.NoSuchFileException
; this indicates that the input file on server is missing.
3.4. The Servlet is Missing
The client starts the process and the web server is up and connected to, but the transfer servlet is missing (or not deployed).
3.4.1. The Client
The following is the output at the command prompt.
*** Transfer process begin. ***
Connecting to the server
Connected to the server
Error writing server data to the local file
java.io.FileNotFoundException:
http://localhost:8080/FileTransferServlet/go
at sun.net.www.protocol.http.HttpURLConnection.getInputStream
(HttpURLConnection.java:1623)
at FileTransferClient.getTransferFile(FileTransferClient.java:107)
at FileTransferClient.main(FileTransferClient.java:45)
Server status code: 404 - Not Found
*** Closing transfer process ***
The java.io.FileNotFoundException
indicates the failure to get the input stream. Note the server status code 404.
- From the
HttpURLConnection
API's javadoc the variable HTTP_NOT_FOUND: HTTP Status-Code 404: Not Found. - From the
javax.servlet.http.HttpServletResponse
API's javadoc the variable SC_NOT_FOUND: Status code (404) indicating that the requested resource is not available.
3.4.2. The Server
There is no server error in this scenario.
4. Useful Links
- Java EE 6 API: http://docs.oracle.com/javaee/6/api/
- java.net package: http://docs.oracle.com/javase/7/docs/api/java/net/package-summary.html
- java.io package: http://docs.oracle.com/javase/7/docs/api/java/io/package-summary.html
- java.nio.file package: http://docs.oracle.com/javase/7/docs/api/java/nio/file/package-summary.html
5. Download
Download source code here: FileTransferServletExample.zip
Return to top