response.setContentType("text/html");
Pero el contenido de la respuesta lo podemos cambiar a cualquier otro Mime type:
http://www.webmaster-toolkit.com/mime-types.shtml
Según esto podemos hacer que nuestro servlet devuelva cualquier tipo de fichero.
En el siguiente ejemplo escribo un servlet capaz de enviarnos un fichero zip de cualquier parte del disco del servidor. (Nota. esto hay que manejarlo con cuidado porque puede producir un hueco de seguridad gordisimo)
package org.company.servlet.readfile;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.util.*;
import java.net.*;
/**
*
This class handles Streaming Data Content
**/
public class Readfile extends HttpServlet {
public void init(ServletConfig config) throws ServletException {
super.init(config);
}
/*
* This Method Handles Post
*
* @param HttpServletRequest request
* @param HttpServletResponse response
*/
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
/*
* This Method Handles Get
*
* @param HttpServletRequest request
* @param HttpServletResponse response
*/
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String urlstr = null;
UserBean user = (UserBean) request.getSession().getAttribute("user");
try {
response.reset();
urlstr = request.getParameter("filename");
ServletOutputStream sOutStream = response.getOutputStream();
streamBinaryData(user.getName(), urlstr, sOutStream, response);
} catch (Exception e) {
e.printStackTrace();
}
}
private void streamBinaryData(String username, String file, ServletOutputStream outstr, HttpServletResponse resp) throws IOException{
String ErrorStr = null;
try {
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
String inFile = "/midirectorio/" + file;
int tam = (int) new File(inFile).length();
bis = new BufferedInputStream(new FileInputStream(inFile));
try {
//Asignamos el tipo de fichero zip
resp.setContentType("application/x-zip-compressed"); //Cualquier mime type
//Seteamos el tamaño de la respuesta
resp.setContentLength(tam);
resp.setHeader("Content-Disposition", "attachment;filename=\"" + file + "\"");
bos = new BufferedOutputStream(outstr);
// Bucle para leer de un fichero y escribir en el otro.
byte[] array = new byte[1000];
int leidos = bis.read(array);
while (leidos > 0) {
bos.write(array, 0, leidos);
leidos = bis.read(array);
}
} catch (Exception e) {
e.printStackTrace();
ErrorStr = "Error Streaming the Data";
outstr.print(ErrorStr);
} finally {
if (bis != null) {
bis.close();
}
if (bos != null) {
bos.close();
}
if (outstr != null) {
outstr.flush();
outstr.close();
}
}
} catch (Exception e) {
System.out.println("Fichero no encontrado");
resp.sendRedirect("fileNotFound.jsp");
}
}
}
Con este servlet conseguimos que en el navegador aparezca la típica ventanita de "descargas" al hacer una llamada al servlet, que recibe como parámetro el nombre del fichero. Este es el motivo por el que debemos tener cuidado al usar esto ya que podríamos crear un hueco de seguridad y que el usuario final se pueda descargar cualquier fichero de nuestro servidor.
Lo mejor sería tener un directorio controlado del que sacar los ficheros como en el ejemplo, o que se filtre el filename de entrada para saber que está entre los permitidos, etc ...