Announcement

Collapse
No announcement yet.

FileOutputstream via FacesContext

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • FileOutputstream via FacesContext

    Hallo zusammen,

    die Benutzer haben in der View mehrere Möglichkeiten sich ein paar Filter zusammenzuklicken um daraus dann einen PDF-Export zu generieren. Ich habe dann ein Byte-Array, dass ich über den ResponseOutputStream an den Browser schicke.

    Mein Problem: Ich bekomme den "speichern unter"-Dialog des Browsers leider immer erst, nachdem das File vollständig vom Browser ins Temp-Verzeichnis runtergeladen wurde. Bei einem 20 MB File und geringem Upload-Speed, dauert das einfach zu lange. Könnt ihr mir sagen, was ich falsch mache?

    Anbei der Donwloadcode:

    Code:
        public static void initiateDownload(String contentType, String filename, byte[] data) throws IOException {
    
            FacesContext facesContext = FacesContext.getCurrentInstance();
            ExternalContext externalContext = facesContext.getExternalContext();
            
            externalContext.setResponseHeader("Content-Disposition", "attachment; filename=\"" + filename +"\"");
            externalContext.setResponseContentLength(data.length);
            externalContext.setResponseContentType(contentType);
            externalContext.setResponseBufferSize(4096);
    
            InputStream in = new ByteArrayInputStream(data);
            int bufferSize = 4096;
            
            byte[] outputByte = new byte[bufferSize];
            
            OutputStream out = externalContext.getResponseOutputStream();
            
            while(in.read(outputByte, 0, bufferSize) != -1) {
                out.write(outputByte, 0, bufferSize);
            }
    
            externalContext.getResponseOutputStream().flush();
            externalContext.getResponseOutputStream().close();
            facesContext.responseComplete();
    
        }
    // Nachtrag:
    Als contentType kommt ein String der meist wie folgt lautet: "application/pdf"
    Ich habe mir schon die W3-Header spezifikationen durchgelesen, konnte mit dem Wissen leider nicht auf meinen Fehler schließen.

    Vielen Dank und viele Grüße,
    Felix

  • #2
    Es liegt am Browser, wann er den Dialog bringt.

    externalContext.setResponseHeader("application/pdf"); -> ist bei dir auch PDF?

    Versuch es mit

    externalContext.setResponseHeader("Expires", "0");

    externalContext.setResponseHeader("Cache-Control","must-revalidate, post-check=0, pre-check=0");

    externalContext.setResponseHeader("Pragma", "public");
    Christian

    Comment


    • #3
      Hallo Christian,

      danke für deine Antwort. Leider hat das nicht geholfen. Folgenden Http-Header bekomme ich, sobald er das File komplett runtergeladen hat und den "Speichern-unter"-Dialog öffnet:

      Code:
      HTTP/1.1 200 OK
      X-Powered-By: Servlet/3.0 JSP/2.2 (GlassFish Server Open Source Edition 3.1.1 Java/Sun Microsystems Inc./1.6), JSF/2.0
      Server: GlassFish Server Open Source Edition 3.1.1
      Content-Disposition: attachment; filename="2011-10-04__uebersicht.pdf"
      Expires: 0
      Cache-Control: must-revalidate, post-check=0, pre-check=0
      Pragma: public
      Content-Type: application/pdf
      Content-Length: 5842312
      Date: Tue, 04 Oct 2011 14:59:36 GMT
      Vielleicht hilft das ja.
      Ja, ich teste gerade nur mit PDF. Mit XLS (natürlich anderem content-type) passiert das selbe.

      Ich rufe den FAcesContext in einer Klasse auf, die nicht als SessionBean, oder ähnlich, annotiert ist. Das sollte aber nichts machen oder?

      Danke und viele Grüße
      Felix

      Comment


      • #4
        Mit ist das zwar noch nie aufgefallen, aber ich denke das liegt dann am Browser.

        EDIT: Hmm bei einem 170 MB download bringt der Firefox erst die Nachfrage und startet dann den Download
        Zuletzt editiert von Christian Marquardt; 04.10.2011, 17:29.
        Christian

        Comment


        • #5
          Probiere andere Methode der Ausgabe wie

          ByteArrayOutputStream baos = new ByteArrayOutputStream();
          baos.write(data[],0,data.length);
          OutputStream os = externalContext.getResponseOutputStream();
          baos.writeTo(os);
          externalContext.getResponseOutputStream().flush();
          externalContext.getResponseOutputStream().close();
          facesContext.responseComplete();
          Christian

          Comment


          • #6
            Dank dir. teste das schnell. Sekunde

            Comment


            • #7
              Geht leider auch nicht. Habe es versucht, ohne und mit Header.
              Die Reihenfolge sollte doch für das setzen des Headers egal sein... oder?

              Vielleicht ist das ein Verhalten des Glassfish-Servers, der erst zu spät den Header absetzt... hmmm
              Der Header, den ich über "Live HTTP headers" absetzte (zum download des files), wird mir erst angezeigt, sobald das "Speichern unter" Fenster kommt...

              Habe gerade noch versucht, erst eine temporäre Datei auf dem Server zu schreiben, und jene dann hochzuladen (ähnlich dem Puffer-Versuch von Dir), leider mit dem selben Resultat. Verstehe das nicht...
              Zuletzt editiert von Christian Marquardt; 04.10.2011, 18:33.

              Comment


              • #8
                Ich habe dann leider auch keine Idee mehr. Ev. könnte es eine Browsereinstellung sein?
                Passiert das mit allen Browsern?
                Christian

                Comment


                • #9
                  Hi Christian,

                  ich habe mir gerade mal die aktuelle Version von google Chrome heruntergeladen. Ebenso habe ich es mit einer alten Version des IE7 versucht. Leider komme ich auf das selbe Ergebnis.
                  Ich bin gerade dabei im Context JSF/Glassfish zu dem Thema was zu suchen.

                  Bin langsam auf mit meinem Latein am Ende. Hmmmm
                  Sobald ich was finde, poste ich es natürlich

                  Comment

                  Working...
                  X