Todo funciona bien, pero solo si el archivo es pequeño, alrededor de 1 MB, cuando lo he probado con archivos más grandes, como la de 20MB de mi navegador de pantalla, en lugar de la fuerza para descargar, he intentado muchas cabeceras hasta el momento, ahora mi código es:

PrintWriter out = response.getWriter();
String fileName = request.getParameter("filename");

File f= new File(fileName);

InputStream in = new FileInputStream(f);
BufferedInputStream bin = new BufferedInputStream(in);
DataInputStream din = new DataInputStream(bin);

while(din.available() > 0){
    out.print(din.readLine());
    out.print("\n");
}

response.setContentType("application/force-download");
response.setContentLength((int)f.length());
response.setHeader("Content-Transfer-Encoding", "binary");
response.setHeader("Content-Disposition","attachment; filename=\"" + "xxx\"");//fileName);


in.close();
bin.close();
din.close();
  • Establecer el tipo de contenido debe hacerlo. Que navegador es?
  • Que navegador? Octet-stream debe ser la respuesta correcta, pero las versiones antiguas de IE utiliza para tratar y «oler» el tipo de contenido, independientemente de lo que el servidor web estaba diciendo que
  • chrome, ff 3.6, y todos los demás probablemente…
  • los encabezados de la primera, última, no la otra manera alrededor!
  • Content-Disposition accesorio de hacerlo. Tenga en cuenta que la aplicación/force-download es un tipo específico de hack, no es un estándar, leer esto: media-division.com/…
InformationsquelleAutor dieeying | 2011-06-29

3 Comentarios

  1. 65

    De establecer los encabezados de respuesta después de escribir el contenido del archivo para el flujo de salida. Esto es bastante retraso en la respuesta del ciclo de vida para el establecimiento de los encabezados. La secuencia correcta de las operaciones se deben establecer los encabezados de la primera, y, a continuación, escribir el contenido del archivo a la del servlet outputstream.

    Por lo tanto, su método debe ser escrita de la siguiente manera (esto no va a compilar, ya que es una mera representación):

    response.setContentType("application/force-download");
    response.setContentLength((int)f.length());
            //response.setContentLength(-1);
    response.setHeader("Content-Transfer-Encoding", "binary");
    response.setHeader("Content-Disposition","attachment; filename=\"" + "xxx\"");//fileName);
    ...
    ...
    File f= new File(fileName);
    
    InputStream in = new FileInputStream(f);
    BufferedInputStream bin = new BufferedInputStream(in);
    DataInputStream din = new DataInputStream(bin);
    
    while(din.available() > 0){
        out.print(din.readLine());
        out.print("\n");
    }

    La razón del fracaso es que es posible para el real cabeceras enviadas por el servlet sería diferente de lo que se pretende enviar. Después de todo, si el contenedor de servlets no sabe lo encabezados (que aparecen antes de que el cuerpo de la respuesta HTTP), entonces se puede establecer cabeceras correspondientes para asegurar que la respuesta es válida; establecimiento de los encabezados después de que el archivo ha sido escrito es por lo tanto inútil y redundante, ya que el contenedor puede ya establecer los encabezados. Usted podría confirmar esta mirando en la red de tráfico con Wireshark o un HTTP proxy de depuración como Fiddler o WebScarab.

    Usted también puede referirse a la documentación de la API de Java EE para ServletResponse.setContentType para entender este comportamiento:

    Establece el tipo de contenido de la respuesta se envía al cliente, si la respuesta no se ha comprometido todavía. Determinado tipo de contenido puede incluir una especificación de codificación de caracteres, por ejemplo, text/html;charset=UTF-8. La respuesta de la codificación de caracteres sólo se establece en el tipo de contenido si se llama a este método antes de getWriter se llama.

    Este método puede ser llamado varias veces para cambiar el tipo de contenido y la codificación de caracteres. Este método no tiene ningún efecto si se llama después de la respuesta que se ha cometido.

    • aplicación/force-download es un hack, no un estándar: media-division.com/…
    • sí nadie reivindica como tal. Deja de spam en todas las respuestas aquí.
    • Quiero informar a los otros de MODO que los usuarios acerca de ser un hack y cómo funciona como esto no se menciona en ninguna parte, aquí es una explicación sobre la FORMA: stackoverflow.com/questions/10615797/…
  2. 5

    Establecer el tipo de contenido y otras cabeceras antes de escribir el archivo. Para pequeños archivos que el contenido se almacena en búfer, y que el navegador recibe los encabezados de la primera. Por grandes que los datos vienen primero.

    • Esta es una crítica poco de info – aprendido de la manera difícil 🙂
  3. 4

    Esto es a partir de un script de php que resuelve el problema a la perfección con todos los navegadores que he probado (FF desde 3.5, internet explorer 8+, Chrome)

    header("Content-Disposition: attachment; filename=\"".$fname_local."\"");
    header("Content-Type: application/force-download");
    header("Content-Transfer-Encoding: binary");
    header("Content-Length: ".filesize($fname));

    Así como y como yo lo veo, todo lo que está haciendo correctamente. Has comprobado la configuración de su navegador?

    • Me encanta downvotes sin una explicación…
    • Yo diría que es «todo lo que está haciendo correctamente» a los que quemaban usted. El aceptó respuesta deja en claro lo que era incorrecto.
    • aplicación/force-download es un hack, no un estándar

Dejar respuesta

Please enter your comment!
Please enter your name here