2013-04-12 3 views
6

Ich verwende PrimefacesWie gestreamte Inhalt mit p verwenden: Filedownload-Datei Non Classpath

p zum Download: Filedownload

zum Herunterladen einer Datei, die nicht in Klassenpfad.
So passiere ich FileInputStream als Parameter zu DefaultStreamedContent.
Alles funktioniert gut, wenn meine Bohne bei @SessionScoped ..., gehalten wird
Aber

java.io.NotSerializableException: java.io.FileInputStream

ausgelöst wird, wenn ich behalte meine Bohne in @Viewscoped.

Mein Code:

DownloadBean.java

@ManagedBean 
@ViewScoped 
public class DownloadBean implements Serializable { 

    private StreamedContent dFile; 

    public StreamedContent getdFile() { 
     return dFile; 
    } 

    public void setdFile(StreamedContent dFile) { 
     this.dFile = dFile; 
    } 

    /** 
    * This Method will be called when download link is clicked 
    */ 
    public void downloadAction() 
    { 
     File tempFile = new File("C:/temp.txt"); 
     try { 
      dFile = new DefaultStreamedContent(new FileInputStream(tempFile), new MimetypesFileTypeMap().getContentType(tempFile)); 
     } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
     } 
    } 

} 

index.xhtml

<h:form> 
    <h:commandLink action="#{downloadBean.downloadAction}"> 
     Download 
     <p:fileDownload value="#{downloadBean.dFile}"/> 
    </h:commandLink> 
</h:form> 

Gibt es keine Methode, um es funktioniert?

Antwort

11

Die NotSerializableException wird ausgelöst, da der Ansichtsbereich durch den JSF-Ansichtszustand dargestellt wird, der im Falle einer serverseitigen Statusspeicherung oder eines HTML-ausgeblendeten Eingabefelds im Fall des clientseitigen Statusspeicherns zur HTTP-Sitzung serialisiert werden kann. Die FileInputStream kann in keiner serialisierten Form dargestellt werden.

Wenn Sie den Bean-View-Bereich unbedingt beibehalten müssen, sollten Sie StreamedContent nicht als Instanzvariable deklarieren, sondern stattdessen in der Getter-Methode neu erstellen. Richtig, Geschäftslogik in einer Getter-Methode ist normalerweise verpönt, aber die StreamedContent ist ein ziemlich spezieller Fall. In der Aktionsmethode sollten Sie dann nur serialisierbare Variablen vorbereiten, die später während der Konstruktion DefaultStreamedContent verwendet werden sollen.

@ManagedBean 
@ViewScoped 
public class DownloadBean implements Serializable { 

    private String path; 
    private String contentType; 

    public void downloadAction() { 
     path = "C:/temp.txt"; 
     contentType = FacesContext.getCurrentInstance().getExternalContext().getMimeType(path); 
    } 

    public StreamedContent getdFile() throws IOException { 
     return new DefaultStreamedContent(new FileInputStream(path), contentType); 
    } 

} 

(beachten Sie, dass ich festen Weg auch den Inhaltstyp zu bekommen, Sie auf diese Weise viel mehr Freiheit zu Mime-Typen über <mime-mapping> Einträge in web.xml konfigurieren)

Die <p:graphicImage> hat übrigens genau das gleiche Problem mit StreamedContent. Siehe auch unter anderem Display dynamic image from database with p:graphicImage and StreamedContent.

+0

Vielen Dank BelusC. Es hat wie ein Zauber funktioniert. Ich habe die Regel über Instanzvariablen und Serialisierung vergessen. –

Verwandte Themen