2010-06-10 6 views
14

Potrzebuję wyświetlić pasek postępu użytkownikowi, który żąda pobrania pliku. Używam aplikacji J2EE do generowania pliku. Użytkownik prześle dane formularza, aby pobrać plik. Serwer pobiera wszystkie przesłane dane manipuluje, generuje i wysyła plik PDF z powrotem do Klienta.Wyświetlanie paska postępu podczas pobierania pliku z serwera

Dlatego chcę wyświetlać użytkownikowi pasek postępu, dopóki plik nie dotrze do klienta. Czy jest jakiś sposób to zrobić?

+1

Chciałbym wiedzieć, jak to zrobić –

+0

Ile czasu zajmuje zwykle wygenerowanie pliku? – cherouvim

+0

@cherouvim: Czas nie jest tutaj statyczny. Różni się między plikami. Zajmuje to minimum 1 sekundę do maksymalnie 20-30 minut. –

Odpowiedz

9

Jeśli dobrze cię rozumiem, chcesz pokazać pasek postępu, dopóki serwer nie będzie gotowy do wysłania pliku, a nie po to, aby pokazać postęp pobierania pliku.

Jeśli to prawda, masz do czynienia z trudnym ćwiczeniem. Niezawodny pasek postępu musi dokładnie wiedzieć, co robisz i ile czasu to zajmie. W twoim przypadku istnieje wiele niewiarygodnych czynników (jednym z nich, być może największym, jest sama sieć).

Dlatego większość programistów używa jakiejś "nieskończonej" animacji do wyświetlania "pracy w toku".

aktualizacja

podstawie Twojego komentarza, najprostszym sposobem, aby wyświetlić "Work in progress" animacja będzie wyglądać

$.ajax({ 
    url:  "/myscripts/myserverscript", 
    type:  "POST", 
    data:  { 
     foo: "bar" 
    }, 
    dataType: "text", 
    beforeSend: function(xhr){ 
     // display a progress animation 
    }, 
    complete: function(xhr, status){ 
     // hide the animation 
    } 
    ... 
}); 

W przypadku pojedynczego żądania. Możesz także skonfigurować globalną obsługę zdarzeń ajax dla obu (.ajaxStart() i .ajaxStop()), aby ustawić funkcjonalność show/hide.

Referencje: .ajax(), .ajaxStart(), bar .ajaxStop()

+0

Oba przypadki są ważne. Dobrze będzie wiedzieć, jaki jest postęp pobierania pliku. Lub nadal mam się dobrze z wyświetlaniem paska postępu pracy, dopóki serwer nie będzie gotowy do wysłania pliku. –

+0

Dziękuję za odpowiedź. –

+1

+1 dla prostoty "nieskończonego oczekiwania" – cherouvim

3

postęp generowania plików po stronie serwera:

Zakładamy, że serwer wymaga wiele sekund do wygenerowania tego pliku. To zdarzenie jest wywoływane przez pierwotne żądanie, operację blokowania. Po zakończeniu tego pliku plik zostanie wygenerowany i zostanie wysłany z powrotem do klienta.

W tym samym czasie chcesz, za pośrednictwem innych żądań (ajax), wywoływać serwer i uzyskać procent z powrotem dla pliku, który jest obecnie generowany dla danego użytkownika.

części kleju są tu:

  • gdy oryginalny wniosek jest generowanie pliku potrzebną do przechowywania postęp w krótkich odstępach czasu (czyli co 10%). Przechowywanie tych danych w sesji http będzie działać poprawnie.
  • inne żądania (ajax) po prostu muszą być w stanie wyciągnąć te informacje z sesji http
  • synchronizację (szeregowy dostęp) w sesji http, coś, co niektóre aplikacje internetowe często robią, jest wykluczone, ponieważ inne żądania (ajax) po prostu blokowałyby, dopóki oryginalne żądanie nie zakończyło się
  • po stronie klienta to wszystko html + javascript, aby zapewnić interakcję, której potrzebujesz (animowany pasek postępu). Nawet jeśli interwały są bardzo trudne (skoki z 10% do 20% do 30%), możesz animować pasek za pomocą jQuery. Zrobiłem to raz w przeszłości i wygląda świetnie.

pasek postępu dla plików do pobrania:

to najlepiej zostawić to do rodzimej oknie przeglądarki.

+0

Czy mogę wiedzieć, jak uzyskać informacje o pobieraniu plików ze skryptu html/java? Czy możesz udostępnić więcej informacji na temat ostatniego punktu, co powiedziałeś (po stronie klienta to wszystko ....)? –

+0

Po stronie serwera potrzebny jest adres URL (np. Serwlet Java) dostarczający te informacje (wystarczy wydrukować procent z sesji http). To, czy będzie to zwykły tekst (np. "20%"), czy JSON lub XML, zależy od ciebie i od tego, jak zaimplementujesz stronę klienta. Po stronie klienta wykonasz asynchroniczne żądania na adresie URL za pośrednictwem jQuery, aby uzyskać te informacje i odpowiednio zmodyfikować DOM. Żądania będą musiały być uruchamiane co X sekund (powiedzmy 3 sekundy) za pomocą funkcji javascript setTimeout (..) – cherouvim

+0

Dla tego rodzaju podejścia, naprawdę sugerowałbym coś w rodzaju sposobu COMET, a nie natywne żądania ajaxowe. – jAndy

0

W języku Java po prostu owinąć javax.swing.ProgressMonitorInputStream wokół strumienia wejściowego, ale należy pamiętać, że jeśli serwer nie wysyła w trybie strumieniowym strumieniowania, wyświetlacz nie będzie tak naprawdę oznaczać niczego, ponieważ cała odpowiedź zostanie przeczytana do pamięci, zanim pierwszy bajt zostanie dostarczony do Javy.