2010-05-12 9 views
9

Ho una pagina GWT in cui l'utente immette i dati (data di inizio, data di fine, ecc.), Quindi questi dati vengono inviati al server tramite chiamata RPC. Sul server voglio generare un report Excel con POI e lasciare che l'utente salvi quel file sul proprio computer locale.Scarica file dinamico con GWT

Questo è il mio codice di prova per lo streaming di file indietro al client, ma per qualche motivo penso che non sa come per lo streaming di file al client quando sto usando RPC:

public class ReportsServiceImpl extends RemoteServiceServlet implements ReportsService { 
    public String myMethod(String s) { 

     File f = new File("/excelTestFile.xls"); 

     String filename = f.getName(); 

     int length = 0; 

     try { 
      HttpServletResponse resp = getThreadLocalResponse(); 
      ServletOutputStream op = resp.getOutputStream(); 
      ServletContext context = getServletConfig().getServletContext(); 
      resp.setContentType("application/octet-stream"); 
      resp.setContentLength((int) f.length()); 
      resp.setHeader("Content-Disposition", "attachment; filename*=\"utf-8''" + filename + ""); 

      byte[] bbuf = new byte[1024]; 
      DataInputStream in = new DataInputStream(new FileInputStream(f)); 

      while ((in != null) && ((length = in.read(bbuf)) != -1)) { 
       op.write(bbuf, 0, length); 
      } 

      in.close(); 
      op.flush(); 
      op.close(); 

     } 
     catch (Exception ex) { 
      ex.printStackTrace(); 
     } 

     return "Server says: " + filename; 
    } 
} 

ho leggere da qualche parte su internet che non si può fare file stream con RPC e devo usare Servlet per questo. C'è qualche esempio su come usare Servlet e come chiamare quel servlet da ReportsServiceImpl. Devo davvero creare un servlet o è possibile eseguire lo streaming con il mio RPC?

+0

Si prega di elaborare il problema in modo più dettagliato. "non sa" non è realmente descrittivo. Cosa succede esattamente? Cosa succede esattamente no? – BalusC

+1

La risposta di @sri ha senso. Ora è il mio turno di postare alcuni commenti: 1) 'DataInputStream' è superfluo. Basta usare direttamente 'FileInputStream'. Dopotutto * solo * serve il metodo 'read()' definito nella classe 'InputStream'. 2) Il controllo 'in! = Null' è anche superfluo dato che è ** mai ** null (ne hai creato uno nuovo usando' new', che non può mai essere nullo). 3) L'intestazione 'Content-Disposition' sembra malformata nella parte' filename'. Per avere qualche idea su come utilizzare il file * basic * che serve, potresti trovare [questo articolo] (http://balusc.blogspot.com/2007/07/fileservlet.html) utile. In bocca al lupo. – BalusC

risposta

14

È necessario creare un servlet regolare, è impossibile dati binari di streaming da ReportsServiceImpl. Inoltre, non è possibile chiamare il servlet da ReportsServiceImpl: il codice client deve richiamare direttamente il servlet.

Sul lato client, è necessario creare un normale collegamento di ancoraggio con i parametri passati tramite la stringa di query. Qualcosa come <a href="http://myserver.com/myservlet?parm1=value1&.."</a>.

Sul lato server, spostare il codice su un servlet standard, che NON eredita da RemoteServiceServlet. Leggere i parametri dall'oggetto richiesta, creare l'Excel e inviarlo al client. Il browser aprirà automaticamente la finestra di dialogo di download del file.

+1

Sì, questo ha senso. Grazie per il tuo suggerimento! – Maksim

0

È possibile ottenere i dati binari che si desidera recuperare attraverso il canale RPC in vari modi ... uuencode, ad esempio. Tuttavia, dovresti comunque avere il browser per gestire il file come download.

E, in base al codice, sembra che si stia tentando di attivare il meccanismo browser standard per gestire il tipo mime specificato modificando la risposta nel server in modo che il browser lo riconosca come download ... una finestra di salvataggio, ad esempio. Per fare ciò, è necessario ottenere il browser per effettuare la richiesta per te e hai bisogno del servlet lì per gestire la richiesta. Può essere fatto con gli url di riposo, ma alla fine avrai bisogno di un servi per fare anche quello.

È necessario, in effetti, impostare un URL della finestra del browser sull'URL che restituisce l'oggetto risposta modificato.

Quindi questa domanda (sullo streaming) non è realmente compatibile con il codice di esempio. È necessario adeguare l'uno o l'altro approccio (protocolli di comunicazione o oggetto di risposta modificato dal server).

Il più semplice da regolare è il metodo di comunicazione.

+0

oh scusa basta leggere la data – Rondo

2

è possibile farlo semplicemente usando GWT RPC e Data URIs:

  1. Nel tuo esempio, rendere il vostro myMethod restituire il file di contenuto.
  2. Sul lato client, formattare uno Data URI con il contenuto del file ricevuto.
  3. Utilizzare Window.open per aprire una finestra di dialogo di salvataggio file che passa il formato DataURI.

Date un'occhiata a questo riferimento, per capire l'utilizzo Data URI:

Export to csv in jQuery

+1

Bisogna considerare che gli URI DATI non sono supportati su IE 6 e 7. IE8 ha comunque un supporto parziale. – codingscientist