2009-07-10 2 views
44

Я пытаюсь выяснить, как загрузить один файл с помощью виджета GWTs FileUpload. Я использую GWT и Google AppEngine с Java, но я хотел бы загрузить файл на свой собственный Linux-сервер. У меня есть следующий код, но уже сейчас я не могу понять, как представить свой файл на сервер Google 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 и как я пишу мой сервлет, так что я могу хранить файл и вернуть 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. ОП выбрал ваш ответ как лучший ответ, поэтому я думаю, что это помогло ему в его вопросе, но я не знаю, где разместить класс FileUpload, находится ли он в GAE вместе с другими файлами проекта? Как насчет сервера Linux? Как он получит файлы? А где указан адрес? И имя файла? Я смущен этой частью кода. –

+3

Не 10 MiB "10 * 1024 * 1024" не "10 * (1024 * 2)", или это "megs" альтернативное имя для 2 KiB? –

+2

10 * (1024 * 2) - 20Kb, но не 10Mb – Antonio

5

В GWT вы можете отправить файл на сервер с помощью методов http-форм, и вы должны использовать предоставленный HttpServlet для приема и сохранения данных в виде двоичных блогов в Appengine BigTable.

Затем вам понадобится второй HttpServlet для чтения файла из большой таблицы, установите тип MIME в HTTP HEADER {и параметры кеширования}, а затем передайте файл пользователю.

Хотя RPC НЕОБХОДИМО НЕОБХОДИМО, вы должны сообщить клиенту, что сгенерированный fileId, чтобы он мог получить к нему доступ {если вы не хотите, чтобы пользователь поставлял идентификатор и заставлял их беспокоиться об переопределении имен .... ..ick}. Либо вы можете использовать rpc для запроса списка/single id {например, «самый новый идентификатор файла пользователем»}, или вы можете вернуть этот идентификатор в теле ответа UploadServlet ... но тогда вы должны убедиться, что ваша целевая аудитория это in-page iframe, опрос, чтобы убедиться, что iframe имеет тело между событием отправки и фактическим ответом сервера, а затем проанализировать и использовать этот id в gwt для создания тега img или object, который использует этот файл.

Ключевая часть имеет один сервлет для загрузки, а другой - для загрузки. Помните, BigTable просто хранит двоичные капли, поэтому вам также нужен ваш объект данных, чтобы иметь тип mime/content, который можно прочитать из входного файла {никогда не полагайтесь на расширения файлов!}. Кроме того, в BigTable есть 1 МБ на сущность, а для бесплатных учетных записей - 10 МБ. Вы можете захотеть, чтобы ваш объект данных содержал список из 1-10 блоков, каждый из которых не более 1024 байтов.

Как правило, лучше всего найти рабочую бесплатную копию, такую ​​как Служба файлов Google, и расширить ее, чтобы узнать, как работает система.

Если вы хотите, я отправлю свою собственную версию обработки файлов с открытым исходным кодом, как только закончу виджеты управления gwt и могу считать все достаточно стабильным, чтобы быть полезным для всех. Электронная почта x AT aiyx DOT информация, если вы хотите, чтобы я пришлю вам банку бета-кода.

11

Я бы предложил использовать GWTUpload, потому что он мертв, прост в использовании и расширяется. Вы можете добавить его в свой проект менее чем за 10 минут, и он поддерживает GAE прямо из коробки (используя GWTUpload-GAE). См. examples для некоторых распространенных сценариев использования.

+2

Примечание: GWTUpload требует сеансов –

+1

Каковы преимущества/недостатки использования GWTUpload решение, предлагаемое @KevMo – kroiz

+2

GWTUpload позволяет асинхронные загрузки с обновлениями состояния, многофайловыми загрузками и т. д. Кажется, это полная замена обычных альтернатив Flash. – rluba

2

Если вы уже используете другие фреймворки, я бы настоятельно предложил использовать простой ванильный GWT и его собственные компоненты. Если вы используете другие фреймворки, вы можете значительно увеличить размер своего приложения.

Использование родных компонентов может быть сделано в 3 этапа:

  1. Создание сервлета загрузки файла
  2. Изменить web.xml
  3. Сделать GWT Загрузить форму

Интересно, что часть GWT является самой простой. Вы можете скопировать мой код по адресу GWT Upload in 3 easy steps, если хотите. Счастливая загрузка!

+0

В принципе, я не вижу разницы в http://stackoverflow.com/a/1111606/787660, таким образом, downvote, потому что я думаю, что ответ в основном похож, а другой не связан где-то еще ... – Chris

Смежные вопросы