Apache MyFaces Trinidad est la composante <tr:fileDownloadActionListener>
.
Je vais avoir pas de problèmes pour l'utiliser, comme il est décrit dans les docs.
Est-il possible de simuler même comportement que cette balise à partir de la sauvegarde de haricot?
J'ai essayé beaucoup de choses. Principal problème est que je ne peux pas obtenir de l' OutputStream
de réponses (à simuler). J'ai créé Servlet
qui créent même fichier en <tr:fileDownloadActionListener>
mais ce servlet nécessite une nouvelle demande. Comment obtenir de l' OutputStream
de courant en FacesContext
?
Réponses
Trop de publicités?Vous pouvez obtenir tout par ExternalContext
. Dans JSF 1.x, vous pouvez obtenir le raw HttpServletResponse
objet en ExternalContext#getResponse()
. Dans JSF 2.x, vous pouvez utiliser le bouquet de nouveau délégué méthodes comme ExternalContext#getResponseOutputStream()
sans avoir besoin de saisir l' HttpServletResponse
sous le JSF hottes. Le plus important est de s'appellent FacesContext#responseComplete()
d'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.
Voici quelques éléments de base de lancement pour les exemples de la diffusion d'un fichier de demande de téléchargement.
JSF 1.x:
public void download() throws IOException {
FacesContext fc = FacesContext.getCurrentInstance();
HttpServletResponse response = (HttpServletResponse) fc.getExternalContext().getResponse();
response.reset(); // Some JSF component library or some Filter might have set some headers in the buffer beforehand. We want to get rid of them, else it may collide.
response.setContentType(contentType); // Check http://www.w3schools.com/media/media_mimeref.asp for all types. Use if necessary ServletContext#getMimeType() for auto-detection based on filename.
response.setContentLength(contentLength); // Set it with the file size. This header is optional. It will work if it's omitted, but the download progress will be unknown.
response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\""); // The Save As popup magic is done here. You can give it any file name you want, this only won't work in MSIE, it will use current request URL as file name instead.
OutputStream output = response.getOutputStream();
// Now you can write the InputStream of the file to the above OutputStream the usual way.
// ...
fc.responseComplete(); // Important! Otherwise JSF will attempt to render the response which obviously will fail since it's already written with a file and closed.
}
JSF 2.x:
public void download() throws IOException {
FacesContext fc = FacesContext.getCurrentInstance();
ExternalContext ec = fc.getExternalContext();
ec.responseReset(); // Some JSF component library or some Filter might have set some headers in the buffer beforehand. We want to get rid of them, else it may collide.
ec.setResponseContentType(contentType); // Check http://www.iana.org/assignments/media-types for all types. Use if necessary ExternalContext#getMimeType() for auto-detection based on filename.
ec.setResponseContentLength(contentLength); // Set it with the file size. This header is optional. It will work if it's omitted, but the download progress will be unknown.
ec.setResponseHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\""); // The Save As popup magic is done here. You can give it any file name you want, this only won't work in MSIE, it will use current request URL as file name instead.
OutputStream output = ec.getResponseOutputStream();
// Now you can write the InputStream of the file to the above OutputStream the usual way.
// ...
fc.responseComplete(); // Important! Otherwise JSF will attempt to render the response which obviously will fail since it's already written with a file and closed.
}
Vous avez seulement besoin de s'assurer que l'action de la méthode n'est pas appelée par une requête ajax, mais qu'il est appelé par une requête normale comme vous le feu avec de l' <h:commandLink>
et <h:commandButton>
. Les requêtes Ajax sont traitées par JavaScript qui à son tour a, pour des raisons de sécurité, pas d'installations pour forcer l' Enregistrer Comme un dialogue avec le contenu de la réponse ajax.
Si vous êtes en utilisant JSF bibliothèque utilitaire OmniFaces, alors vous pouvez utiliser l'un des trois commode Faces#sendFile()
méthodes.
public void download() throws IOException {
Faces.sendFile(file, true);
}
voici l'extrait de code complet http://bharatonjava.wordpress.com/2013/02/01/downloading-file-in-jsf-2/
@ManagedBean(name = "formBean")
@SessionScoped
public class FormBean implements Serializable
{
private static final long serialVersionUID = 1L;
/**
* Download file.
*/
public void downloadFile() throws IOException
{
File file = new File("C:\\docs\\instructions.txt");
InputStream fis = new FileInputStream(file);
byte[] buf = new byte[1024];
int offset = 0;
int numRead = 0;
while ((offset < buf.length) && ((numRead = fis.read(buf, offset, buf.length -offset)) >= 0))
{
offset += numRead;
}
fis.close();
HttpServletResponse response =
(HttpServletResponse) FacesContext.getCurrentInstance()
.getExternalContext().getResponse();
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=instructions.txt");
response.getOutputStream().write(buf);
response.getOutputStream().flush();
response.getOutputStream().close();
FacesContext.getCurrentInstance().responseComplete();
}
}
Vous pouvez modifier la logique de lecture du fichier si vous souhaitez que le fichier soit généré au moment de l'exécution.