2010-06-16 61 views
0

我已經實現RPCService,RPCServiceAsync & RPCServieImpl。在點擊一個按鈕時,服務器端的服務將被調用,它將從數據庫獲取數據並創建文件。一旦文件被創建,然後我需要在客戶端打開該文件,並需要提示一個對話框打開/保存選項。 我該如何實現這個打開文件的一部分。請提供一種方法來實現t ..回覆請提前致謝....在smartGWT中打開/保存文件

@漢姆:我還有一個更多的澄清!..如何調用這個doGet方法在另一個servlet,即在我的onmodule負載我有很多獨立佈局的小部件,一個這樣的小部件是BUTTON? onclicking這個按鈕服務RPCServiceImpl被調用並且所有的操作都完成並且文件被創建在一個serperate函數中(public int GenerateFile(String name)())。如何使該函數調用doGet方法?因爲doGet需要請求,響應參數要與它一起傳遞?請告訴我一種調用該方法的方法。在此先感謝

+0

你需要將它保存在客戶端,還是可以將它保存在服務器端?客戶端的問題是讓瀏覽器的沙箱允許你操縱本地文件系統。 – 2010-06-16 14:02:29

回答

5

GWT的RPC服務只能將java對象發送回客戶端。要將文件發送回用戶,您需要使用非GWT Java servlet。以下是我之前用於從存儲庫提供jpeg圖像的代碼。

public class ImageServlet extends HttpServlet { 
    private final String repository = "/var/images/"; 

    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
     throws ServletException, IOException { 
     String filename = request.getParameter("file"); 

     // Security: '..' in the filename will let sneaky users access files 
     // not in your repository. 
     filename = filename.replace("..", ""); 

     File file = new File(repository + filename); 
     if (!file.exists()) 
      throw new FileNotFoundException(file.getAbsolutePath()); 

     response.setHeader("Content-Type", "image/jpeg"); 
     response.setHeader("Content-Length", String.valueOf(file.length())); 
     response.setHeader("Content-disposition", "attachment;filename=\"" + filename + "\""); 

     BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file)); 
     BufferedOutputStream bos = new BufferedOutputStream(response.getOutputStream()); 
     byte[] buf = new byte[1024]; 
     while (true) { 
      int length = bis.read(buf); 
      if (length == -1) 
       break; 

      bos.write(buf, 0, length); 
     } 
     bos.flush(); 
     bos.close(); 
     bis.close(); 
    } 
} 

「內容處置:附件」應引起大多數瀏覽器下載,而不是顯示它的文件中,文件名默認爲任何你提供。你使用這個servlet的方式是讓用戶調用你已有的RPCService,它將文件保存到存儲庫文件夾中。然後,您將它們鏈接或重定向到此servlet,並使用url,例如http://your.domain.com/fileServlet?file=myFile.jpg。顯然,使用此設置時,如果用戶可以猜測文件名,用戶可以下載其他人的文件,則存在安全風險。

您可能想要做的是將RPC服務中的數據庫代碼合併到此servlet中。不需要將文件保存在服務器上的任何位置,您可以將數據庫結果寫入response.getOutputStream()或response.getWriter(),其方式與將文件寫入文件的方式完全相同,只是結果不同直接給用戶。只要您正確設置了內容標題,用戶就不會注意到其中的差異。

您不能從另一個servlet調用此方法,使瀏覽器將其作爲文件下載的唯一方法是通過正常的HTTP請求訪問它。首先聲明這個servlet中像使用GWT RPC服務web.xml文件:

<servlet> 
    <servlet-name>ImageServlet</servlet-name> 
    <servlet-class> 
     com.package.ImageServlet 
    </servlet-class> 
</servlet> 
<servlet-mapping> 
    <servlet-name>ImageServlet</servlet-name> 
    <url-pattern>/imageServlet</url-pattern> 
</servlet-mapping> 

現在,任何HTTP GET請求要http://your.tomcat.server/webapp/imageServlet將ImageServlet.doGet得到回升()。然後在客戶端,你可以做一個普通的HTML文件鏈接:

new HTML("<a href='" + GWT.getHostPageBaseURL() + "imageServlet?file=" + filename + "'>download</a>"); 

...或者,你應該能夠把這個在clickHandler事件(我沒有測試):

Window.Location.assign(GWT.getHostPageBaseURL() + "imageServlet?file=" + filename); 
+0

非常感謝hambend ..我仍然有一個更多的澄清!請清除它..如何在另一個servlet中調用此doGet方法?在我的onmodule加載類中,我有很多獨立佈局的小部件,一個這樣的小部件是BUTTON?如何觸發onclick按鈕項來調用這個方法? – Karthikeyan 2010-06-17 04:27:24

+0

我編輯了我的答案,以闡明如何使用servlet。 – dslh 2010-06-17 05:51:08

+0

非常感謝....我得到了它的工作....謝謝.. – Karthikeyan 2010-06-17 12:43:37

0

如果文件是文本,那麼您總是會用一個字符串數組反回一個對象。
如果二進制,那麼只需在該類中的一個字節[]。