->File Open/Accessing from Java Web Application(JSP/Servlet)

Basically this thread shows you how to open a file from your physical storage (outside of web container), in general, a client can access files from within your container but can not access from within your physical storage by a relative URI.

This post is is to create a Servlet  which loads a file from a path outside of the web container and then streams the file to the HttpServletResponse. The client should get a ‘Save as’ popup dialogue. You can pass the file name or the file ID as a part of the request URI. You can also consider to pass it as a request parameter, but that would cause problems with getting the filename right during saving in certain web browsers (Internet Explorer and so on).

In this post, this.filePath=”/pics/lates”, given a path to get images from the “/pics/lates” path.

In Windows environment if the application server is running in C: drive, the above path is exactly same as “C:\pics\lates”.

In UNIX/LINUX, it is just straight forward “/pics/lates”.

If you stored files in WebContent of a war, for ex: “/WEB-INF/pics/latest” folder, then you can retrieve the absolute path with

this.filePath=getServletContext().getRealPath(“/WEB-INF/pics/latest”);

Here is a basic example of a FileOpenServlet which serves a file from a path outside of the web container.

package ex;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLDecoder;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * The File servlet for serving from absolute path.
 * @author Sumant
 *
 */
public class FileOpenServlet extends HttpServlet {

    private static final int DEFAULT_BUFFER_SIZE = 10240; // 10KB.
    private String filePath;
    public void init() throws ServletException {
        this.filePath = "/pics/latest";
    }

   /**
     * Do your thing if the file is not supplied to the request URI.
     * Throw an exception, or send 404, or show default/warning page, or just ignore it.
     */

protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException
{
String requestedFile = request.getPathInfo();
if (requestedFile == null) {
response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
return;
}

// Decode the file name (might contain spaces and on) and prepare file object.
File file = new File(filePath, URLDecoder.decode(requestedFile, "UTF-8"));

// Check if file actually exists in filesystem.
if (!file.exists()) {
response.sendError(HttpServletResponse.SC_NOT_FOUND); // 404.
return;
}

// Get content type by filename.
String contentType = getServletContext().getMimeType(file.getName());
// If content type is unknown, then set the default value.
if (contentType == null) {
contentType = "application/octet-stream";
}

// Init servlet response.
response.reset();
response.setBufferSize(DEFAULT_BUFFER_SIZE);
response.setContentType(contentType);
response.setHeader("Content-Length", String.valueOf(file.length()));
response.setHeader("Content-Disposition", "attachment; filename=\"" + file.getName() + "\"");

// Prepare streams.
BufferedInputStream input = null;
BufferedOutputStream output = null;

try {
input = new BufferedInputStream(new FileInputStream(file), DEFAULT_BUFFER_SIZE);
output = new BufferedOutputStream(response.getOutputStream(), DEFAULT_BUFFER_SIZE);

// Write file contents to response.
byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
int length;
while ((length = input.read(buffer)) > 0) {
output.write(buffer, 0, length);
}
} finally {
close(output);
close(input);
}
}

private static void close(Closeable resource) {
if (resource != null) {
try {
resource.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

}

In order to get the FileOpenServlet to work, add the following entries to the Web Deployment Descriptor web.xml:
<servlet>
     <servlet-name>fileOpenServlet</servlet-name>
     <servlet-class>ex.FileOpenServlet</servlet-class>
</servlet>
<servlet-mapping>
     <servlet-name>fileOpenServlet</servlet-name>
     <url-pattern>/pics/latest/*</url-pattern>
</servlet-mapping>

Note:- You can change the <url-patter> as you like.
A simple JSP body to get files:
<a href="pics/latest/DSC0001.jpg">download DSC0001.jpg</a>
<a href="pics/latest/bar.jpg">download bar.jpg</a>
Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: