2010-08-28 13 views

risposta

49

Nel metodo di azione è possibile ottenere la risposta della servlet HTTP da sotto i cappucci JSF da ExternalContext#getResponse(). Poi è necessario impostare almeno l'intestazione HTTP Content-Type al application/pdf e HTTP Content-Disposition intestazione per attachment (quando si desidera pop un Salva con nome dialogo) o per inline (quando si vuole sia eseguita dal browser web il display stesso). Infine, è necessario assicurarsi di chiamare FacesContext#responseComplete() in seguito per evitare IllegalStateException s volare in giro.

Kickoff esempio:

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. 
} 

Detto questo, se avete la possibilità di ottenere il contenuto PDF come InputStream piuttosto che un byte[], mi sento di raccomandare di utilizzare che invece di salvare la webapp da maiali di memoria. È quindi sufficiente scriverlo nel noto ciclo InputStream - OutputStream con il solito modo IO di Java.

+0

Grazie mille :), tuttavia non posso votare (reputazione). – marioosh

+0

Grazie per questo post. –

+0

Appena trovato ciò che è necessario. Grazie. – user

5

Devi solo impostare il tipo mime su application/x-pdf nella tua risposta. È possibile utilizzare il metodo setContentType(String contentType) per eseguire questa operazione nel caso servlet.
In JSF/JSP si potrebbe usare questo, prima di scrivere la risposta:

<%@ page contentType="application/x-pdf" %> 

e response.write(yourPDFDataAsBytes()); di scrivere i dati.
Ma in realtà vi consiglio di utilizzare i servlet in questo caso. JSF è utilizzato per il rendering di viste HTML, non di file PDF o binari.

Con servlet è possibile utilizzare questo:

public MyPdfServlet extends HttpServlet { 
    protected doGet(HttpServletRequest req, HttpServletResponse resp){ 
     OutputStream os = resp.getOutputStream(); 
     resp.setContentType("Application/x-pdf"); 
     os.write(yourMethodToGetPdfAsByteArray()); 
    } 
} 

risorse:

+0

Da una piccola esperienza i browser gestiscono l'applicazione/pdf meglio dell'applicazione/x-pdf. –

1

Quando si inviano dati grezzi al browser utilizzando JSF, è necessario estrarre lo HttpServletResponse dallo FacesContext.

Utilizzando lo HttpServletResponse, è possibile inviare dati grezzi al browser utilizzando l'API IO standard.

Ecco un esempio di codice:

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)). 
} 

Inoltre, qui ci sono alcune altre cose che si potrebbe prendere in considerazione:

  • impostare il tipo di contenuto del HttpServletResponse di informare il browser che sei invio di dati PDF: response.setContentType ("application/pdf");
  • Informa FacesContext che hai inviato i dati direttamente all'utente, utilizzando il metodo context.responseComplete(). Ciò impedisce a JSF di eseguire un'ulteriore elaborazione che non è necessaria.
Problemi correlati