2009-07-10 92 views
44

我想弄清楚如何使用GWTs FileUpload小部件上傳一個文件。我使用GWT和谷歌AppEngine與Java,但我想上傳文件到我自己的Linux服務器。 我有以下的代碼已經但是現在我無法弄清楚如何我的文件提交給谷歌服務器的AppServer並將其保存到另一臺服務器:GWT基本文件上傳

public class FileUploader{ 

    private ControlPanel cp; 
    private FormPanel form = new FormPanel(); 
    private FileUpload fu = new FileUpload(); 

    public FileUploader(ControlPanel cp) { 
     this.cp = cp; 
     this.cp.setPrimaryArea(getFileUploaderWidget()); 
    } 

    @SuppressWarnings("deprecation") 
    public Widget getFileUploaderWidget() { 
     form.setEncoding(FormPanel.ENCODING_MULTIPART); 
     form.setMethod(FormPanel.METHOD_POST); 
     // form.setAction(/* WHAT SHOULD I PUT HERE */); 

     VerticalPanel holder = new VerticalPanel(); 

     fu.setName("upload"); 
     holder.add(fu); 
     holder.add(new Button("Submit", new ClickHandler() { 
      public void onClick(ClickEvent event) { 
       GWT.log("You selected: " + fu.getFilename(), null); 
       form.submit(); 
      } 
     })); 

     form.addSubmitHandler(new FormPanel.SubmitHandler() { 
      public void onSubmit(SubmitEvent event) { 
       if (!"".equalsIgnoreCase(fu.getFilename())) { 
        GWT.log("UPLOADING FILE????", null); 
             // NOW WHAT???? 
       } 
       else{ 
        event.cancel(); // cancel the event 
       } 

      } 
     }); 

     form.addSubmitCompleteHandler(new FormPanel.SubmitCompleteHandler() { 
      public void onSubmitComplete(SubmitCompleteEvent event) { 
       Window.alert(event.getResults()); 
      } 
     }); 

     form.add(holder); 

     return form; 
    } 
} 

現在,我下一步需要做什麼?我需要什麼就擺在web.xml和我怎麼寫我的servlet,所以我可以存儲文件,並返回該對象的URL(如果可能)

回答

57

下面是從我的應用程序的代碼:

1)I創建一個類來接受http請求:

import java.io.ByteArrayOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 

import javax.servlet.ServletException; 
import javax.servlet.http.HttpServlet; 
import javax.servlet.http.HttpServletRequest; 
import javax.servlet.http.HttpServletResponse; 
import org.apache.commons.fileupload.FileItemIterator; 
import org.apache.commons.fileupload.FileItemStream; 
import org.apache.commons.fileupload.servlet.ServletFileUpload; 

public class FileUpload extends HttpServlet{ 
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
     ServletFileUpload upload = new ServletFileUpload(); 

     try{ 
      FileItemIterator iter = upload.getItemIterator(request); 

      while (iter.hasNext()) { 
       FileItemStream item = iter.next(); 

       String name = item.getFieldName(); 
       InputStream stream = item.openStream(); 


       // Process the input stream 
       ByteArrayOutputStream out = new ByteArrayOutputStream(); 
       int len; 
       byte[] buffer = new byte[8192]; 
       while ((len = stream.read(buffer, 0, buffer.length)) != -1) { 
        out.write(buffer, 0, len); 
       } 

       int maxFileSize = 10*(1024*1024); //10 megs max 
       if (out.size() > maxFileSize) { 
        throw new RuntimeException("File is > than " + maxFileSize); 
       } 
      } 
     } 
     catch(Exception e){ 
      throw new RuntimeException(e); 
     } 

    } 
} 

2)然後在我的web.xml我添加了這些行:

<servlet> 
    <servlet-name>fileUploaderServlet</servlet-name> 
    <servlet-class>com.testapp.server.FileUpload</servlet-class> 
</servlet> 
<servlet-mapping> 
    <servlet-name>fileUploaderServlet</servlet-name> 
    <url-pattern>/testapp/fileupload</url-pattern> 
</servlet-mapping> 

3)和form.action這樣做:

form.setAction(GWT.getModuleBaseURL()+"fileupload"); 
+1

我有確切的OP:該項目在GAE主辦,我要上傳該文件到我自己的Linux網絡服務器。 OP確實選擇了你的答案作爲最佳答案,所以我猜它確實幫助了他的問題,但我不知道把FileUpload類放在哪裏,它是否與其他項目文件一起放在GAE中?那麼Linux服務器呢?它將如何收到這些文件?指定的地址在哪裏?和文件名?我對這段代碼感到困惑。 – 2010-02-07 18:48:59

+3

是不是10 MiB「10 * 1024 * 1024」而不是「10 *(1024 * 2)」,或者是「megs」是2 KiB的替代名稱? – 2011-02-16 14:36:42

+2

10 *(1024 * 2)是20Kb,但不是10Mb – Antonio 2011-05-01 08:30:49

5

在GWT中,您可以使用http表單方法將文件發佈到服務器,並且您必須使用提供的HttpServlet接受並將數據作爲二進制博客存儲在Appengine BigTable中。

然後,您需要第二個HttpServlet從bigtable中讀取文件,在HTTP頭文件中設置MIME類型{和緩存選項},然後將文件傳輸給用戶。

儘管RPC不是必需的,但您必須讓客戶端知道生成的fileId是什麼,以便他們可以訪問它{除非您想讓用戶提供id並強制他們擔心名稱覆蓋...。 ..ick}。要麼你可以使用rpc來請求一個/ single id列表{就像「用戶最新的文件ID」},或者你可以在UploadServlet的響應正文中返回該id ...但是你必須確保你的post目標是一個頁內iframe,通過輪詢來確保iframe在提交事件和實際服務器響應之間有一個主體,然後解析並在gwt中使用該id來創建使用該文件的img或object標記。

關鍵部分是有一個servlet用於上傳,另一個用於下載。請記住,BigTable只存儲二進制blob,所以您還需要您的數據實體具有可以從輸入文件讀取的mime/content類型{從不依賴於文件擴展名}。此外,BigTable中的每個實體都有1MB的空間,並且免費帳戶有10MB的請求限制。您可能希望讓您的數據實體包含1-10個斑點的列表,每個斑點的最大數量爲1024字節。

基本上,您最好的選擇是找到一個免費的工作副本,例如Google File Service,並將其擴展以瞭解該系統的工作原理。

如果你願意,我會發布我自己的開源版本的文件處理,一旦我完成了gwt控件的部件,並且可以認爲它足夠穩定,足以對任何人都有用。電子郵件x AT aiyx DOT如果您希望我向您發送一串好玩的代碼,

11

我建議使用GWTUpload,因爲它很簡單,使用和擴展。您可以在不到10分鐘的時間內將其添加到您的項目中,並立即支持GAE(使用GWTUpload-GAE)。有關一些常見的使用場景,請參閱examples

2

除非你已經在使用其他框架,否則我強烈建議使用普通的vanilla GWT,它是本地組件。如果您使用其他框架,則可以大大提高應用程序的大小。

使用原有成分可以在3個步驟來完成:

  1. 創建一個文件上傳的servlet
  2. 修改web.xml中
  3. 做一個GWT上傳表單

有趣的是, GWT部分是最簡單的。如果您願意,您可以在GWT Upload in 3 easy steps處複製我的代碼。快樂上傳!