Comment diffuser un fichier à télécharger et afficher un JSF visages message?
Nous sommes de la diffusion d'un fichier binaire à nos utilisateurs, à la suite de la procédure élaborée dans la question Comment offrir le téléchargement d'un fichier à partir d'un JSF backing bean?
En général, le flux de travail fonctionne comme prévu, mais lors de la génération du fichier d'exportation recouvrable des erreurs peuvent se produire et l'on veut afficher ces comme un avertissement à l'utilisateur. Le fichier lui-même doit toujours être généré dans ce cas. Nous voulons donc que l'exportation de continuer et afficher les faces des messages.
Juste à mettre l'accent sur ce: Oui, il y a quelque chose de pas OK avec les données, mais nos utilisateurs veulent l'exportation de poursuivre et de les recevoir imparfait fichier de toute façon. Ensuite, ils veulent avoir un oeil au fichier, contacter leur fournisseur et de lui envoyer un message au sujet de la faille.
J'ai donc besoin de l'exportation pour terminer, en tout cas.
Mais il ne fonctionne pas comme nous le souhaitons. J'ai créé un exemple simplifié pour illustrer notre approche.
Comme alternative, nous envisageons un Haricot qui se déroulera les messages et de les afficher après l'exportation. Mais il y a probablement un moyen avec la JSF mis en place des mécanismes pour y parvenir.
Contrôleur
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.OutputStream;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import org.apache.tomcat.util.http.fileupload.util.Streams;
@ManagedBean
@RequestScoped
public class ExportController {
public void export() {
FacesContext fc = FacesContext.getCurrentInstance();
ExternalContext ec = fc.getExternalContext();
byte[] exportContent = "Hy Buddys, thanks for the help!".getBytes();
//here something bad happens that the user should know about
//but this message does not go out to the user
fc.addMessage(null, new FacesMessage("record 2 was flawed"));
ec.responseReset();
ec.setResponseContentType("text/plain");
ec.setResponseContentLength(exportContent.length);
String attachmentName = "attachment; filename=\"export.txt\"";
ec.setResponseHeader("Content-Disposition", attachmentName);
try {
OutputStream output = ec.getResponseOutputStream();
Streams.copy(new ByteArrayInputStream(exportContent), output, false);
} catch (IOException ex) {
ex.printStackTrace();
}
fc.responseComplete();
}
}
JSF Page
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui">
<f:view contentType="text/html">
<h:body>
<h:form prependId="false">
<h:messages id="messages" />
<h:commandButton id="download" value="Download"
actionListener="#{exportController.export()}" />
</h:form>
</h:body>
</f:view>
</html>
org.apache.tomcat.util.http.fileupload.util.Streams
est spécifique à Tomcat.
OriginalL'auteur cheffe | 2014-09-05
Vous devez vous connecter pour publier un commentaire.
Puisque vous êtes en fait effectuer le téléchargement d'un fichier de réponse et pas un JSF, il n'est pas possible pour votre message afin d'être ajouté lorsque la même demande qui se passe. Le plus propre pour moi, la solution, en évitant hacky requêtes asynchrones est d'utiliser un
@ViewScoped
de haricots et de faire de votre tâche en deux étapes. Donc, pour avoir un bouton pour la préparation de votre fichier, la notification de l'utilisateur plus tard et qui lui permet de télécharger quand c'est prêt:Remarque cette solution pourrait être valable pour les petits fichiers (la totalité de leur contenu est stocké dans la mémoire pendant que l'utilisateur conserve le même point de vue). Toutefois, si vous allez l'utiliser avec des fichiers de grande taille (ou un grand nombre d'utilisateurs) de votre mieux est de stocker son contenu dans un fichier temporaire et afficher un lien à la place d'un bouton de téléchargement. C'est ce que @BalusC suggère dans la référence ci-dessous.
Voir aussi:
il serait très agréable de voir votre JS solution. Pouvez-vous poster un lien?
OriginalL'auteur Xtreme Biker
Vous pouvez essayer ceci :
Pour primefaces, vous pouvez utiliser la commande à distance au lieu de la commande link, et de l'appeler par son nom, onsuccess. Sinon, de donner un widget var à la commandlink et appeler sa méthode de clic.
OriginalL'auteur Suphi Çeviker