2010-08-28 2 views

Odpowiedz

49

W metodzie akcji można uzyskać odpowiedź HTTP serwletu pod okapami JSF przez ExternalContext#getResponse(). Następnie trzeba ustawić co najmniej nagłówek HTTP Content-Type do application/pdf i HTTP Content-Disposition nagłówek attachment (jeśli chcesz pop zapisać jako dialogu) lub inline (gdy chcesz pozwolić webbrowser obsłużyć sam wyświetlacz). Na koniec, musisz się upewnić, że zadzwonisz później pod numer FacesContext#responseComplete(), aby uniknąć latania w okolicach IllegalStateException.

Kickoff przykład:

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

Mimo to, jeśli masz możliwość, aby uzyskać zawartość PDF jako InputStream zamiast byte[], polecam użyć że zamiast zapisać webapp z wieprzy pamięci. Po prostu zapisz go w znanej pętli InputStream - OutputStream zwykłym sposobem Java IO.

+0

Wielkie dzięki :), jednak nie mogę głosować w górę (reputacja). – marioosh

+0

Dziękuję za ten wpis. –

+0

Po prostu znalazłem to, co potrzebne. Dziękuję Ci. – user

5

Musisz tylko ustawić typ mime na application/x-pdf w odpowiedzi. Możesz użyć metody setContentType(String contentType), aby zrobić to w przypadku serwletu.
W JSF/JSP można to wykorzystać, zanim pisania odpowiedzi:

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

i response.write(yourPDFDataAsBytes()); napisać swoje dane.
Ale naprawdę radzę korzystać z serwletów w tym przypadku. JSF służy do renderowania widoków HTML, a nie plików PDF lub binarnych.

Z serwlety można użyć to:

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

Zasoby:

+0

Z niewielkich przeglądarek korzystających z aplikacji/pdf lepiej niż application/x-pdf. –

1

Wysyłając nieprzetworzone dane do przeglądarki przy użyciu JSF, należy wyodrębnić HttpServletResponse z FacesContext.

Korzystając z HttpServletResponse, możesz wysyłać nieprzetworzone dane do przeglądarki przy użyciu standardowego interfejsu API IO.

Oto przykładowy kod:

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

A oto kilka innych rzeczy, które warto rozważyć:

  • Ustaw typ zawartości w HttpServletResponse poinformować przeglądarkę jesteś wysyłanie danych PDF: response.setContentType ("application/pdf");
  • Poinformuj FaceContext o wysłanych danych bezpośrednio do użytkownika za pomocą metody context.responseComplete(). Zapobiega to przeprowadzaniu przez JSF dodatkowego przetwarzania, które nie jest konieczne.