SORU
22 ŞUBAT 2012, ÇARŞAMBA


Ne kadar OLUMSUZLUK destek fasulye dosya indirme sağlamak için?

AKSARAY destek fasulye eylem bir yöntem, bir dosya indirme sağlamanın bir yolu var mı? Bir çok şey denedim. Ana sorunum olamaz dosya içeriği yazmak için yanıt OutputStream nasıl şekil. * *5, Bir ile nasıl yapılacağını biliyorum ama bu OLUMSUZLUK bir formdan çağrılan ve yeni bir istek gerektirir.

Nasıl geçerli yanıtı FacesContext OutputStream alabilir miyim?

CEVAP
22 ŞUBAT 2012, ÇARŞAMBA


Giriş

ExternalContext ile her şeyi alabilirsiniz. AKSARAY 1.x, ExternalContext#getResponse() HttpServletResponse raw nesneyi alabilirsiniz. AKSARAY 2'de.x, AKSARAY Maskeler altında HttpServletResponse kapmak için gerek kalmadan ExternalContext#getResponseOutputStream() gibi yeni temsilci yöntemlerin demet kullanabilirsiniz.

Yanıtta, istemci dosya veren bilir ki Content-Type Başlığı ayarlamak gerekir. Ve, istemci karşıdan yükleme ilerleme hesaplamak, böylece Content-Length Başlığı ayarlamanız gerekir, aksi takdirde bilinmeyen olacak. Ve, eğer isterseniz attachment 15 *Başlığı ayarlamak gerekirKaydetiletişim, aksi takdirde istemci satır görüntülemek için çalışacaktır. Sadece yanıt çıktı akımına dosya içeriğini yaz sonunda.

En önemli parçasıdır çağrı FacesContext#responseComplete() bilgi OLUMSUZLUK bu olmamalı gerçekleştirmek navigasyon ve işleme sonra yazdığınız dosyayı yanıtı, yoksa sonun yanıt olacak kirli ile HTML içerik sayfası veya eski sürümleri OLUMSUZLUK, sen-ecek almak bir IllegalStateException ile bir mesaj gibi getoutputstream() has already been called for this response AKSARAY uygulanması çağrıları getWriter() render HTML.

Genel AKSARAY 2.x örnek

public void download() throws IOException {
    FacesContext fc = FacesContext.getCurrentInstance();
    ExternalContext ec = fc.getExternalContext();

    ec.responseReset(); // 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.
    ec.setResponseContentType(contentType); // Check http://www.iana.org/assignments/media-types for all types. Use if necessary ExternalContext#getMimeType() for auto-detection based on filename.
    ec.setResponseContentLength(contentLength); // Set it with the file size. This header is optional. It will work if it's omitted, but the download progress will be unknown.
    ec.setResponseHeader("Content-Disposition", "attachment; filename=\""   fileName   "\""); // The Save As popup magic is done here. You can give it any file name you want, this only won't work in MSIE, it will use current request URL as file name instead.

    OutputStream output = ec.getResponseOutputStream();
    // Now you can write the InputStream of the file to the above OutputStream the usual way.
    // ...

    fc.responseComplete(); // Important! Otherwise JSF will attempt to render the response which obviously will fail since it's already written with a file and closed.
}

Genel AKSARAY 1.x örnek

public void download() throws IOException {
    FacesContext fc = FacesContext.getCurrentInstance();
    HttpServletResponse response = (HttpServletResponse) fc.getExternalContext().getResponse();

    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(contentType); // Check http://www.iana.org/assignments/media-types for all types. Use if necessary ServletContext#getMimeType() for auto-detection based on filename.
    response.setContentLength(contentLength); // Set it with the file size. This header is optional. It will work if it's omitted, but the download progress will be unknown.
    response.setHeader("Content-Disposition", "attachment; filename=\""   fileName   "\""); // The Save As popup magic is done here. You can give it any file name you want, this only won't work in MSIE, it will use current request URL as file name instead.

    OutputStream output = response.getOutputStream();
    // Now you can write the InputStream of the file to the above OutputStream the usual way.
    // ...

    fc.responseComplete(); // Important! Otherwise JSF will attempt to render the response which obviously will fail since it's already written with a file and closed.
}

Ortak yerel dosya örneği

Yerel dosya sisteminden bir dosya akışı için ihtiyaç halinde, kodu aşağıdaki gibi değiştirin:

File file = new File("/path/to/file.ext");
String fileName = file.getName();
String contentType = ec.getMimeType(fileName); // JSF 1.x: ((ServletContext) ec.getContext()).getMimeType(fileName);
int contentLength = (int) file.length();

// ...

Files.copy(file.toPath(), output);

Ajax kapatın!

Sadece eylem yöntem olduğundan emin olundeğil<h:commandLink> <h:commandButton> ile yangın gibi normal bir istek tarafından adlandırılan bir ajax isteği tarafından çağırdı, ama. Ajax istekleri sırayla, güvenlik nedeniyle, bir zorlama imkanı olan JavaScript tarafından yönetilirKaydetajax yanıt içeriği ile diyalog.

Durumda örneğin PrimeFaces <p:commandXxx>, o zaman açıkça kapat ajax="false" ile ajax öznitelik emin olun kullanıyorsun. İCEfaces kullanarak ediyorsanız, o zaman <f:ajax disabled="true" /> komutu bir bileşeni yuva gerekiyor.

Yardımcı program yöntemi

Kullanıyorsanız AKSARAY araç Kütüphanesi OmniFaces, o zaman kullanabileceğiniz bir kullanışlı Faces#sendFile() yöntemler kullanmadan da bir File InputStream byte[], ve belirtmek ister dosya halinde indirilen ek olarak bir (true) veya satır (false).

public void download() throws IOException {
    Faces.sendFile(file, true);
}

Evet, bu kodu olduğu gibi tam değildir. responseComplete() ve başına çağırmak gerek yok. Bu yöntem, düzgün özel IE başlıkları ve UTF-8 dosya ile ilgilidir. source code here bulabilirsiniz.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • El SalvaLobo

    El SalvaLobo

    10 Temmuz 2006
  • FOSDEM

    FOSDEM

    13 Ocak 2009
  • LAHWF

    LAHWF

    5 Kasım 2009