Domanda

Sto riscontrando un problema nel tentativo di pubblicare un file zip in un JSP.

Il file zip è sempre corrotto al termine del download. Ho provato alcuni metodi diversi per leggere e scrivere, e nessuno di loro sembra fare il trucco.

Immagino che probabilmente aggiungerà caratteri ASCII da qualche parte poiché il file si aprirà e visualizzerà tutti i nomi dei file, ma non riesco a estrarre alcun file.

Ecco il mio ultimo codice:

<%@ page import= "java.io.*" %>

<% 
    BufferedReader bufferedReader = null;

    String zipLocation = "C:\\zipfile.zip"; 

    try
    {
        bufferedReader = new BufferedReader(new FileReader(zipLocation));
        response.setContentType("application/zip");
        response.setHeader( "Content-Disposition", "attachment; filename=zipfile.zip" );

        int anInt = 0;
        while((anInt = bufferedReader.read()) != -1)
        {
            out.write(anInt);
        }
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
%>

EDIT: Ho spostato il codice su un servlet e ancora non ha funzionato. Ho cambiato molte altre cose in giro, quindi ecco l'ultimo codice non funzionante:

public void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException
{
    try
    {
        String templateLocation = Config.getInstance().getString("Site.templateDirectory");

        response.setContentType("application/zip");
        response.setHeader("Content-Disposition", "attachment; filename=output.zip;");

        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        BufferedOutputStream bos = new BufferedOutputStream(baos);
        FileInputStream fis = new FileInputStream(templateLocation);

        int len;
        byte[] buf = new byte[1024];

        while ((len = fis.read(buf)) > 0)
        {
            bos.write(buf, 0, len);
        }

        bos.close();
        PrintWriter pr = response.getWriter();
        pr.write(baos.toString());
        pr.close();
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}

EDIT2:

Questo è il codice servlet che lavoro effettivamente. Grazie a tutti!

public void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException
{
    try
    {
        String templateLocation = Config.getInstance().getString("Site.templateDirectory");

        response.setContentType("application/zip");
        response.setHeader("Content-Disposition", "attachment; filename=output.zip;");

        BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());
        FileInputStream fis = new FileInputStream(templateLocation);

        int len;
        byte[] buf = new byte[1024];

        while ((len = fis.read(buf)) > 0)
        {
            bos.write(buf, 0, len);
        }

        bos.close();
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}
È stato utile?

Soluzione

Le zip sono file binari e quindi non sono adatti per essere trasferiti come dati carattere. Anche il testo esterno al codice potrebbe corrompere il file.

Utilizzare un servlet semplice e vaniglia anziché JSP.

Altri suggerimenti

Il JSP aggiunge spazi bianchi all'output. Ti suggerisco di spostarlo su un servlet.

In alternativa, puoi dare un'occhiata a Rimuovi spazi bianchi dall'output jsp , ma Non sono sicuro che ciò non influirebbe sull'output ZIP stesso.

Il problema in questo frammento esatto è nella seconda riga: hai una riga vuota all'esterno dei tag JSP, che viene inviata al browser come HTML (ovvero una riga vuota nell'origine HTML).

Fai molta attenzione a rimuovere tutto ciò che non è in <%% > ;, in particolare gli spazi bianchi (anche una nuova riga terminale!), oppure segui i consigli altrove e usa un servlet:)

Il tuo codice servlet non funziona perché stai trasmettendo il tuo stream a response.getWriter(), che come altri hanno sottolineato è per dati carattere . Cito il Javadoc:

  

PrintWriter getWriter() throws IOException
  Restituisce un oggetto PrintWriter che può inviare testo di caratteri al client. PrintWriter utilizza la codifica dei caratteri restituita da getCharacterEncoding ()

Non solo, ma non stai nemmeno scrivendo l'array di byte in Writer, stai scrivendo i risultati di ByteArrayOutputStream.toString(), che esegue anche una conversione di caratteri ~

Vuoi usare response.getOutputStream (), qualcosa del tipo:

BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream());

E quindi scrivi il contenuto in byte del tuo file.

I lettori sono in genere per flussi di caratteri se ricordo bene - potresti provare qualcosa di più sulla falsariga di un ByteArrayOutputStream? Inoltre, il JSP potrebbe effettivamente danneggiare l'output, come altri hanno commentato.

bufferedReader = new BufferedReader(new FileReader(zipLocation));

A parte il problema Servlet / JSP, questa linea sta corrompendo i tuoi dati con certezza al 100%. Tenterà di interpretare i dati binari come testo utilizzando la codifica della piattaforma predefinita, il che significa che circa la metà dei byte nel file vengono sostituiti con & Quot; carattere sconosciuto & Quot ;.

I byte e le stringhe non sono la stessa cosa!

Vorrei anche suggerire di usare un semplice servlet e prenderei in considerazione La risposta di Robert Munteanu come giusto, ma potresti farlo anche nel tuo JSP. Il problema non è lo spazio bianco aggiunto, ma che la variabile implicita & Quot; out & Quot; è un'istanza di JSPWriter e Writer è per i caratteri, non per i byte. Prova a utilizzare response.getOutputStream () e proprio su di esso, dovrebbe funzionare. Otterrai un'eccezione dicendo che qualcun altro ha già ottenuto OutputStream, ma puoi ignorarlo.

Ma come ho detto, l'uso di un Servlet sarebbe molto più pulito.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top