Question

Je ne parviens pas à gérer un fichier zip dans un fichier JSP.

Le fichier zip est toujours corrompu une fois le téléchargement terminé. J'ai essayé différentes méthodes de lecture et d'écriture et aucune d'elles ne semble faire l'affaire.

Je suppose qu'il ajoute probablement des caractères ascii quelque part, car le fichier s'ouvre et affiche tous les noms de fichiers, mais je ne peux en extraire aucun.

Voici mon dernier code:

<%@ 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: J'ai déplacé le code dans une servlet et cela ne fonctionnait toujours pas. J'ai changé un tas de choses, alors voici le dernier code qui ne fonctionne pas:

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:

C'est le code de servlet que je travaille réellement. Merci à tous!

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();
    }
}
Était-ce utile?

La solution

Les fichiers zip sont des fichiers binaires et ne peuvent donc pas être transférés en tant que données de type caractère. De même, du texte en dehors du code peut corrompre le fichier.

Utilisez une servlet simple et vanille au lieu du fichier JSP.

Autres conseils

La JSP ajoute des espaces à la sortie. Je vous suggère de déplacer ceci vers une servlet.

Vous pouvez également consulter Supprimer les blancs de la sortie jsp , mais Je ne suis pas sûr que cela n’affectera pas la sortie ZIP elle-même.

Le problème dans cet extrait de code exact se trouve sur la deuxième ligne. Vous avez une ligne vierge à l'extérieur des balises JSP, qui est envoyée au navigateur au format HTML (c'est-à-dire une ligne vierge dans la source HTML).

Faites très attention à supprimer tout ce qui ne se trouve pas dans <%% > ;, particulièrement les espaces (même une nouvelle ligne de terminal!), ou suivez les conseils ailleurs et utilisez une servlet:)

Votre code de servlet ne fonctionne pas car vous exportez votre flux vers response.getWriter(), ce qui, comme d'autres l'ont souligné, concerne les données de caractère . Je cite le Javadoc:

  

PrintWriter getWriter() throws IOException
  Renvoie un objet PrintWriter pouvant envoyer du texte au caractère du client. PrintWriter utilise le codage de caractères renvoyé par getCharacterEncoding ()

Non seulement cela, mais vous n'écrivez même pas le tableau d'octets dans Writer, vous écrivez les résultats de ByteArrayOutputStream.toString(), ce qui entraîne également une conversion de caractère ~

Vous souhaitez utiliser response.getOutputStream (), par exemple:

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

Ensuite, écrivez le contenu en octets de votre fichier.

Si je me souviens bien, les lecteurs sont généralement destinés aux flux de caractères - vous pourriez essayer quelque chose de plus semblable à un ByteArrayOutputStream? En outre, le JSP pourrait en effet corrompre la sortie, comme d'autres l'ont commenté.

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

Hormis le problème Servlet / JSP, cette ligne altère vos données avec une certitude totale. Il essaiera d'interpréter les données binaires en tant que texte à l'aide du codage par défaut de la plate-forme, ce qui signifie qu'environ la moitié des octets du fichier sont remplacés par & "Caractère inconnu &";.

.

Les octets et les chaînes ne sont pas la même chose!

Je suggérerais également d'utiliser une servlet simple et envisagerais La réponse de Robert Munteanu est correcte, mais vous pouvez également le faire dans votre JSP. Le problème n’est pas l’espace ajouté, mais la variable implicite & Quot; out & Quot; est une instance de JSPWriter et un enregistreur est destiné aux caractères, pas aux octets. Essayez d’utiliser response.getOutputStream () et cela devrait fonctionner. Vous obtiendrez une exception disant que quelqu'un d'autre a déjà reçu le flux de sortie, mais vous pouvez l'ignorer.

Mais comme je l'ai dit, utiliser un Servlet serait beaucoup plus propre.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top