Téléchargement de fichier à l'aide de RichFaces

On m'a déjà travailler:

  1. Utilisateur peut télécharger un fichier (c'est à dire une archive compressée)
  2. Utilisateur peut décompresser le fichier sur le serveur
  3. Utilisateur peut exécuter des trucs sur ces fichiers, ce qui donne plus de fichiers à créer

Maintenant, j'ai besoin d'obtenir de l'étape 4 à l'œuvre:

  • L'utilisateur peut télécharger les fichiers sur son propre ordinateur à nouveau

Quelqu'un peut me donner un indice? J'ai essayé de comprendre les trucs que j'ai trouvé sur Google, mais il ne fonctionne pas tout à fait comme prévu. Dois-je définir un type de contenu? Lorsque j'ai mis en application/octet stream uniquement les fichiers csv et txt affiche correctement (dans le navigateur, ne pas télécharger de pop-up que je voulais) d'autres fichiers de travail...

JSP:

<a4j:commandLink value="Download" action="#{appController.downloadFile}" rendered="#{!file.directory}">
   <f:param name="file" value="#{file.absoluteFilename}" />
</a4j:commandLink>

appController:

public String downloadFile() {
    String filename = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get("file");
    File file = new File(filename);
    HttpServletResponse response = (HttpServletResponse) FacesContext.getCurrentInstance().getExternalContext().getResponse();  

    writeOutContent(response, file, file.getName());

    FacesContext.getCurrentInstance().responseComplete();
    return null;
}

private void writeOutContent(final HttpServletResponse res, final File content, final String theFilename) {
    if (content == null) {
        return;
    }
    try {
        res.setHeader("Pragma", "no-cache");
        res.setDateHeader("Expires", 0);
        res.setHeader("Content-disposition", "attachment; filename=" + theFilename);
        FileInputStream fis = new FileInputStream(content);
        ServletOutputStream os = res.getOutputStream();
        int bt = fis.read();
        while (bt != -1) {
            os.write(bt);
            bt = fis.read();
        }
        os.flush();
        fis.close();
        os.close();
    } catch (final IOException ex) {
        Logger.getLogger(ApplicationController.class.getName()).log(Level.SEVERE, null, ex);
    }
}