Dans la méthode d'action (JSF), j'ai quelque chose comme ci-dessous:
public String getFile() {
byte[] pdfData = ...
// how to return byte[] as file to web browser user ?
}
Comment envoyer l'octet [] en pdf au navigateur?
Dans la méthode d'action, vous pouvez obtenir la réponse du servlet HTTP sous les hottes JSF par ExternalContext#getResponse()
. Ensuite, vous devez définir au moins l'en-tête HTTP Content-Type
Sur application/pdf
Et l'en-tête HTTP Content-Disposition
Sur attachment
(lorsque vous souhaitez insérer un Enregistrer sous dialogue) ou dans inline
(lorsque vous souhaitez laisser le navigateur Web gérer l'affichage lui-même). Enfin, vous devez vous assurer d'appeler FacesContext#responseComplete()
par la suite pour éviter que IllegalStateException
s ne vole autour.
Exemple de lancement:
public void download() throws IOException {
// Prepare.
byte[] pdfData = getItSomehow();
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext externalContext = facesContext.getExternalContext();
HttpServletResponse response = (HttpServletResponse) externalContext.getResponse();
// Initialize response.
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("application/pdf"); // Check http://www.iana.org/assignments/media-types for all types. Use if necessary ServletContext#getMimeType() for auto-detection based on filename.
response.setHeader("Content-disposition", "attachment; filename=\"name.pdf\""); // The Save As popup magic is done here. You can give it any filename you want, this only won't work in MSIE, it will use current request URL as filename instead.
// Write file to response.
OutputStream output = response.getOutputStream();
output.write(pdfData);
output.close();
// Inform JSF to not take the response in hands.
facesContext.responseComplete(); // Important! Else JSF will attempt to render the response which obviously will fail since it's already written with a file and closed.
}
Cela dit, si vous avez la possibilité d'obtenir le contenu PDF en tant que InputStream
plutôt que byte[]
, Je recommanderais de l'utiliser à la place pour enregistrer le webapp à partir de porcs mémoire. Il vous suffit ensuite de l'écrire dans la boucle InputStream
-OutputStream
habituelle Java IO = chemin.
Il vous suffit de définir le type mime sur application/x-pdf
Dans votre réponse. Vous pouvez utiliser la méthode setContentType (String contentType) pour ce faire dans le cas du servlet.
Dans JSF/JSP, vous pouvez l'utiliser avant d'écrire votre réponse:
<%@ page contentType="application/x-pdf" %>
et response.write(yourPDFDataAsBytes());
pour écrire vos données.
Mais je vous conseille vraiment d'utiliser des servlets dans ce cas. JSF est utilisé pour rendre les vues HTML, pas PDF ou fichiers binaires.
Avec les servlets, vous pouvez utiliser ceci:
public MyPdfServlet extends HttpServlet {
protected doGet(HttpServletRequest req, HttpServletResponse resp){
OutputStream os = resp.getOutputStream();
resp.setContentType("Application/x-pdf");
os.write(yourMethodToGetPdfAsByteArray());
}
}
Ressources:
Lors de l'envoi de données brutes au navigateur à l'aide de JSF, vous devez extraire le HttpServletResponse
du FacesContext
.
À l'aide de HttpServletResponse
, vous pouvez envoyer des données brutes au navigateur à l'aide de l'API standard IO.
Voici un exemple de code:
public String getFile() {
byte[] pdfData = ...
FacesContext context = FacesContext.getCurrentInstance();
HttpServletResponse response = (HttpServletResponse) context.getExternalContext().getResponse();
OutputStream out = response.getOutputStream();
// Send data to out (ie, out.write(pdfData)).
}
En outre, voici d'autres éléments que vous voudrez peut-être envisager: