You start by getting the servlet's output stream:
ServletOutputStream out = res.getOutputStream();
The Internet community uses the MIME (multipurpose Internet mail extension) protocol to send multipart, multimedia, and binary data over the Internet. It is important to set the MIME type of the file you want to open in the servlet's response object. For this example, I will open a PDF document.
Web browsers use MIME types to identify non-HTML files and to determine how to present the data contained in them. Plug-ins can be associated with a MIME type or types, so that when the Web browser downloads a file with that MIME type, the browser also launches the plug-in that handles the file. Other MIME types can be associated with external programs. When the browser downloads files of those MIME types, it launches the appropriate program to view the downloaded file.
MIME types are useful because they allow Web browsers to handle various file types without having the built-in knowledge. Java servlets can use MIME types to send non-HTML files such as Adobe PDF and Microsoft Word to browsers. Using the proper MIME type helps to ensure that the file gets displayed by the proper plug-in or external viewer. The Resources section provides links to a list of defined MIME types and additional articles on MIME types.
The MIME type for a PDF file is "application/pdf". To open a PDF file in a servlet, you set the content type in the response header to "application/pdf":
// MIME type for pdf doc
res.setContentType( "application/pdf" );
To open an Microsoft Word document, you would set the response object's content type to "application/msword" instead of "application/pdf":
// MIME type for MSWord doc
res.setContentType( "application/msword" );
For an Excel document, use the MIME type "application/vnd.ms-excel". In that MIME type, vnd refers to application vendor that must be included to open the file.
In some cases, the browser doesn't recognize the file's MIME type. That often happens when the required plug-in hasn't been installed for a certain file type. In those cases, the browser will pop up a dialog box, asking the user whether he or she wants to open the file or save it to disk.
An HTTP response header named content-disposition allows the servlet to specify information about the file's presentation. Using that header, you can indicate that the content should be opened separately (not actually in the browser) and that it should not be displayed automatically but rather upon some further action by the user. You can also suggest the filename to be used if the content is to be saved to a file. That filename would be the name of the file that appears in the Save As dialog box. If you don't specify the filename, you are likely to get the name of your servlet in that box. To find out more about the content-disposition header, check out Resources.
In the servlet, you want to set that header as follows:
res.setHeader("Content-disposition",
"attachment; filename=" +
"Example.pdf" );
// attachment - since we don't want to open
// it in the browser, but
// with Adobe Acrobat, and set the
// default file name to use.
If you were opening an Microsoft Word file, you would choose:
res.setHeader("Content-disposition",
"attachment; filename" +
"Example.doc" );
The rest is pretty simple. You need to create a java.net.URL object based on the name of the file you want to open. The string that is passed into the URL constructor should be a fully
qualified URL to the file's location. In this example, I open Adobe's employment application form:
String fileURL = "http://www.adobe.com/aboutadobe/careeropp/pdfs/adobeapp.pdf;"
Your URL string could be something like http://www.gr.com/pub/somefile.doc or http://www.gr.com/pub/somefile.xls, but make sure the file you're opening is consistent with the MIME type that was previously set in the HTTP response object.
URL url = new URL ( fileURL );
If your browser needs to go through a firewall, the last thing you need to worry about is making your URL connection. For that you need to find out some information about your proxy server, such as the host name and port number to establish a firewall connection. More information about establishing connections through a firewall can be found in the Resources section below.
If you are using Java 2, you should create a URLConnection object from the URL object and set the following system properties:
URLConnection conn = url.openConnection();
// Use the username and password you use to
// connect to the outside world
// if your proxy server requires authentication.
String authentication = "Basic " + new
sun.misc.BASE64Encoder().encode("username:password".getBytes());
System.getProperties().put("proxySet", "true");
System.getProperties().put("proxyHost", PROXY_HOST); // your proxy host
System.getProperties().put("proxyPort", PROXY_PORT); // your proxy port
conn.setRequestProperty("Proxy-Authorization", authentication);
If you are using JDK 1.1, you may not be able to set the system properties. In that case, you should create the java.net.URL object with your proxy server information:
url = new URL("http", PROXY_HOST,
Integer.parseInt(PROXY_PORT),
fileURL );
// assumes authentication is not required
To start reading your file, you need to obtain the InputStream from the URLConnection (or URL) object. In this example, you wrap the InputStream with a BufferedInputStream.
If you are using the URLConnection, follow this code:
BufferedInputStream bis = new
BufferedInputStream(conn.getInputStream());
If you are using the URL, follow this code:
BufferedInputStream bis = new
BufferedInputStream(url.openStream());
Once you have done that, you simply write each byte from the InputStream to the servlet's OutputStream:
BufferedOutputStream bos = new
BufferedOutputStream(out);
byte[] buff = new byte[2048];
int bytesRead;
// Simple read/write loop.
while(-1 != (bytesRead = bis.read(buff, 0, buff.length))) {
bos.write(buff, 0, bytesRead);
}
Lastly, you close the streams in a final block.
file names with spacesBy Anonymous on November 18, 2009, 9:46 pmIf I use a pdf file name without spaces, it works fine. But if there is a space, I get: java.io.IOException: Server returned HTTP response code: 505 for URL: http://localhost:8080/PDFs/Michigan...
Reply | Read entire comment
Getting error while using this code in JSF framework for PortletBy Anonymous on September 11, 2009, 3:44 amHi, I am using the above mentioned code in JSF Framework for JSR 268 portlet. But I am getting error at bos.close();. Error is: EJPPG1122E: An error occurred during...
Reply | Read entire comment
HelpfulBy Anonymous on July 21, 2009, 1:38 pmVery helpful. Solved a problem for me.
Reply | Read entire comment
thanks, that is just what I want...By Anonymous on July 17, 2009, 10:27 amthanks, that is just what I want.
Reply | Read entire comment
How to open MS word document in IE from servlet setting MIME type as msword.By Anonymous on December 18, 2008, 5:38 amI have set MIME type in my servlet as msword and response.setContentType("application/vnd.msword"); response.setHeader("Content-Disposition", "attachment;" +...
Reply | Read entire comment
View all comments