Comment offrir le téléchargement d'un fichier à partir d'un JSF backing bean?
Est-il possible d'offrir le téléchargement d'un fichier à partir d'un JSF backing bean méthode d'action?
J'ai essayé beaucoup de choses. Principal problème est que je ne peux pas comprendre comment obtenir le OutputStream
de la réponse, afin d'écrire le contenu du fichier pour. Je sais comment le faire avec un Servlet
, mais cela ne peut pas être invoqué à partir d'un formulaire JSF et nécessite une nouvelle demande.
Comment puis-je obtenir le OutputStream
de la réponse de l'actuel FacesContext
?
Vous devez vous connecter pour publier un commentaire.
Introduction
Vous pouvez obtenir tout ce à travers
ExternalContext
. Dans JSF 1.x, vous pouvez obtenir le rawHttpServletResponse
objet parExternalContext#getResponse()
. Dans JSF 2.x, vous pouvez utiliser le bouquet de nouveau délégué méthodes commeExternalContext#getResponseOutputStream()
sans avoir besoin de saisir de laHttpServletResponse
sous le JSF hottes.Sur la réponse, vous devez définir la
Content-Type
en-tête de sorte que le client sait que l'application à associer avec le fichier. Et, vous devez définir laContent-Length
en-tête de sorte que le client peut calculer la progression du téléchargement, sinon il sera inconnu. Et, vous devez définir laContent-Disposition
en-tête deattachment
si vous voulez un Enregistrer sous dialogue, sinon le client va tenter de les afficher en ligne. Enfin, il suffit d'écrire le contenu du fichier pour la réponse flux de sortie.Plus important, c'est d'appeler
FacesContext#responseComplete()
pour informer JSF qu'il ne devrait pas effectuer de navigation et le rendu après que vous avez écrit sur le fichier pour la réponse, sinon la fin de la réponse va être polluée par le contenu HTML de la page, ou dans les anciennes JSF versions, vous obtiendrez unIllegalStateException
avec un message commegetoutputstream() has already been called for this response
lorsque le JSF mise en œuvre des appelsgetWriter()
rendu HTML.Désactiver ajax /n'utilisez pas la commande à distance!
Vous avez seulement besoin de s'assurer que la méthode d'action est pas appelé par une requête ajax, mais qu'il est appelé par une requête normale comme vous le feu avec
<h:commandLink>
et<h:commandButton>
. Les requêtes Ajax et des commandes à distance sont traitées par JavaScript qui à son tour a, pour des raisons de sécurité, pas d'installations pour forcer un Enregistrer sous dialogue avec le contenu de la réponse ajax.Dans le cas où vous êtes en utilisant par exemple PrimeFaces
<p:commandXxx>
, alors vous devez vous assurer que vous avez explicitement désactiver ajax viaajax="false"
attribut. Dans le cas où vous êtes à l'aide de ICEfaces, alors vous avez besoin d'imbriquer une<f:ajax disabled="true" />
dans la commande de composants.Générique JSF 2.x exemple
Générique JSF 1.x exemple
Commune de fichier statique exemple
Dans le cas où vous avez besoin de flux d'un fichier statique à partir du disque local du système de fichiers, remplacer le code comme ci-dessous:
Dynamique commune exemple de fichier
Dans le cas où vous avez besoin de flux généré dynamiquement, un fichier, au format PDF ou XLS, il suffit ensuite de fournir
output
là où l'API utilisée s'attend à uneOutputStream
.E. g. iText PDF:
E. g. Apache POI HSSF:
Notez que vous ne pouvez pas définir la longueur du contenu ici. Si vous devez supprimer la ligne pour définir le contenu de la réponse de la longueur. Ce n'est techniquement pas de problème, le seul inconvénient est que l'utilisateur final sera présenté un inconnu de la progression du téléchargement. Dans le cas où c'est important, alors vous avez vraiment besoin d'écrire dans un local (temporaire) du premier fichier, et ensuite fournir comme indiqué dans le chapitre précédent.
Méthode utilitaire
Si vous êtes en utilisant JSF bibliothèque utilitaire OmniFaces, alors vous pouvez utiliser l'un des trois commode
Visages#sendFile()
méthodes de prendre soit unFile
, ou unInputStream
, ou unbyte[]
, et en précisant si le fichier doit être téléchargé sous forme de pièce jointe (true
) ou en ligne (false
).Oui, ce code est complet est. Vous n'avez pas besoin d'invoquer
responseComplete()
et donc sur vous-même. De plus, cette méthode traite correctement avec IE-en-têtes spécifiques et UTF-8 dans les noms de fichiers. Vous pouvez trouver le code source ici.InputStream
infrastructure pourp:fileDownload
, et je n'ai pas réussi, comment convertirOutputStream
àInputStream
. Maintenant, c'est clair que même une action auditeur peut changer le contenu de la réponse et la réponse sera respecté comme un téléchargement de fichier à l'utilisateur-agent de côté de toute façon. Merci!!!!preRenderView
auditeur dans une markupless vue. Même question pour le téléchargement (bien, service) JSON est la réponse ici: stackoverflow.com/questions/8358006/...C'est ce qui a fonctionné pour moi:
voici le code complet extrait de http://bharatonjava.wordpress.com/2013/02/01/downloading-file-in-jsf-2/
Vous pouvez modifier le fichier de lecture logique dans le cas où vous voulez le fichier généré lors de l'exécution.