Acquiring a Binary Stream for the Response
Suppose you want to open a binary file in a browser from a servlet. It isn't text so you have to write the file to the servlet's output stream. Let's practice with a PDF document. First, you get the servlet's output stream with:ServletOutputStream out = res.getOutputStream();
Next, you set the file type in the response object using one of the standard MIME (Multipurpose Internet Mail Extension) protocols. Several listings of content type names are available on the Internet including one at ftp://ftp.isi.edu/in-notes/iana/assignments/media-types. Then you use an HTTP response header named content-disposition. This header 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 or go to http://www.alternic.org/rfcs/rfc2100/rfc2183.txt.Sending a binary stream to the client is not easy. Listing 4.10 will help you do it right.Listing 4.10 Servlet That Sends a File to the Client
public class BinaryResponse extends HttpServlet { /**Set global variables*/
public void init(ServletConfig config)
throws ServletException
{
super.init(config);
} /**Process HTTP Post request with doPost*/
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
String fileName = "index.html"; //set file name
String contentType = getContentType(fileName);
//contentType = getType(); //get the content type
// get the file
File file = new File(fileName);
long length = file.length();
if(length > Integer.MAX_VALUE)
{
//handle too large file error
//perhaps log and return error message to client
}
byte[] bytes = new byte[(long)length];
BufferedInputStream in =
new BufferedInputStream(new FileInputStream(file));
// then place it into a byte array
if(length != in.read(bytes))
{
//handle too large file error
//perhaps log and return error message to client
} //get the servlet's output stream
BufferedOutputStream out =
new BufferedOutputStream(response.getOutputStream());
//set the content type of the response
response.setContentType( contentType );
//send the file to the client
out.write( bytes );
}
} /**Clean up resources*/
public void destroy()
{
//If you need to clean up resources.
//Otherwise don't override.
}
String getContentType(String fileName)
{
String extension[] =
{ // File Extensions
"txt", //0 - plain text
"htm", //1 - hypertext
"jpg", //2 - JPEG image
"gif", //3 - gif image
"pdf", //4 - adobe pdf
"doc", //5 - Microsoft Word
}, // you can add more
mimeType[] =
{ // mime types
"text/plain", //0 - plain text
"text/html", //1 - hypertext
"image/jpg", //2 - image
"image/gif", //3 - image
"application/pdf", //4 - Adobe pdf
"application/msword", //5 - Microsoft Word
}, // you can add more
contentType = "text/html"; // default type
// dot + file extension
int dotPosition = fileName.lastIndexOf('.');
// get file extension
String fileExtension =
fileName.substring(dotPosition + 1);
// match mime type to extension
for(int index = 0; index < MT.length; index++)
{
if(fileExtension.equalsIgnoreCase(
extension[index]))
{
contentType = mimeType[index];
break;
}
}
return contentType;
}
}
Suppose you want to open a binary file in a browser from a servlet. It isn't text so you have to write the file to the servlet's output stream. Let's practice with a PDF document. First, you get the servlet's output stream with:ServletOutputStream out = res.getOutputStream();
Next, you set the file type in the response object using one of the standard MIME (Multipurpose Internet Mail Extension) protocols. Several listings of content type names are available on the Internet including one at ftp://ftp.isi.edu/in-notes/iana/assignments/media-types. Then you use an HTTP response header named content-disposition. This header 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 or go to http://www.alternic.org/rfcs/rfc2100/rfc2183.txt.Sending a binary stream to the client is not easy. Listing 4.10 will help you do it right.Listing 4.10 Servlet That Sends a File to the Client
public class BinaryResponse extends HttpServlet { /**Set global variables*/
public void init(ServletConfig config)
throws ServletException
{
super.init(config);
} /**Process HTTP Post request with doPost*/
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
String fileName = "index.html"; //set file name
String contentType = getContentType(fileName);
//contentType = getType(); //get the content type
// get the file
File file = new File(fileName);
long length = file.length();
if(length > Integer.MAX_VALUE)
{
//handle too large file error
//perhaps log and return error message to client
}
byte[] bytes = new byte[(long)length];
BufferedInputStream in =
new BufferedInputStream(new FileInputStream(file));
// then place it into a byte array
if(length != in.read(bytes))
{
//handle too large file error
//perhaps log and return error message to client
} //get the servlet's output stream
BufferedOutputStream out =
new BufferedOutputStream(response.getOutputStream());
//set the content type of the response
response.setContentType( contentType );
//send the file to the client
out.write( bytes );
}
} /**Clean up resources*/
public void destroy()
{
//If you need to clean up resources.
//Otherwise don't override.
}
String getContentType(String fileName)
{
String extension[] =
{ // File Extensions
"txt", //0 - plain text
"htm", //1 - hypertext
"jpg", //2 - JPEG image
"gif", //3 - gif image
"pdf", //4 - adobe pdf
"doc", //5 - Microsoft Word
}, // you can add more
mimeType[] =
{ // mime types
"text/plain", //0 - plain text
"text/html", //1 - hypertext
"image/jpg", //2 - image
"image/gif", //3 - image
"application/pdf", //4 - Adobe pdf
"application/msword", //5 - Microsoft Word
}, // you can add more
contentType = "text/html"; // default type
// dot + file extension
int dotPosition = fileName.lastIndexOf('.');
// get file extension
String fileExtension =
fileName.substring(dotPosition + 1);
// match mime type to extension
for(int index = 0; index < MT.length; index++)
{
if(fileExtension.equalsIgnoreCase(
extension[index]))
{
contentType = mimeType[index];
break;
}
}
return contentType;
}
}
Binary content should be generated by servlets. Servlets that output binary content must set the Content-Type HTTP header to the MIME type of the content being generated. A servlet writes its binary data to an OutputStream acquired from the ServletRequest, as shown in Code Example 4.2.public class JpgWriterServlet extends HttpServlet {
public void service(HttpServletRequest req,
HttpServletResponse rsp) throws... {
rsp.setHeader("Content-type", "image/jpg");
OutputStream os = rsp.getOutputStream();
// ... now write binary data to the OutputStream...
Code Example 4.2 A Servlet that Produces Binary Content A servlet can write to either an OutputStream or a PrintWriter, but not both. JSP pages can't create binary content.