GWT 文件上传 - Servlet 选项和处理响应

4

我是GWT的新手,正在尝试实现文件上传功能。在互联网上找到了一些实现帮助,并将其作为参考。但我有一些相关问题:

  1. 实际的上传或将文件内容写入服务器(或磁盘)将由一个servlet完成。 这个servlet(比如MyFileUploadServlet)是否必须扩展HttpServlet?还是我可以使用RemoteServiceServlet或实现任何其他接口?如果可以,我需要实现/覆盖哪个方法?

  2. 在我的servlet中,完成所有操作后,我需要将响应返回给客户端。 我认为可以使用form.addSubmitCompleteHandler()来实现。从servlet中,我可以返回text/html(或String类型对象),然后使用SubmitCompleteEvent.getResults()获取结果。 问题是,我是否可以使用自定义对象代替String(比如说MyFileUploadResult),将结果填充到其中,然后将其传递回客户端? 或者我可以得到JSON对象吗?

  3. 当前,在获取响应并使用SubmitCompleteEvent.getResults()之后,我会获得一些HTML标记添加到实际响应中,例如:

pre> Image upload successfully /pre>。

有没有办法摆脱它?

非常感谢!

问候, Ashish

1个回答

2
上传文件时,我过去曾扩展HttpServlet。我与Commons-FileUpload一起使用它。
我制作了一个通用的基于表单的上传小部件。这是为了适应不同文件类型(纯文本和Base64)的上传。如果您只需要上传纯文本文件,则可以将以下两个类合并为一个。
public class UploadFile extends Composite {

  @UiField FormPanel uploadForm;
  @UiField FileUpload fileUpload;
  @UiField Button uploadButton;

  interface Binder extends UiBinder<Widget, UploadFile> {}

  public UploadFile() {
    initWidget(GWT.<Binder> create(Binder.class).createAndBindUi(this));

    fileUpload.setName("fileUpload");

    uploadForm.setEncoding(FormPanel.ENCODING_MULTIPART);
    uploadForm.setMethod(FormPanel.METHOD_POST);

    uploadForm.addSubmitHandler(new SubmitHandler() {
      @Override
      public void onSubmit(SubmitEvent event) {
        if ("".equals(fileUpload.getFilename())) {
          Window.alert("No file selected");
          event.cancel();
        }
      }
    });

    uploadButton.addClickHandler(new ClickHandler() {
      @Override
      public void onClick(ClickEvent event) {
        uploadForm.submit();
      }
    });
  }

  public HandlerRegistration addCompletedCallback(
      final AsyncCallback<String> callback) {
    return uploadForm.addSubmitCompleteHandler(new SubmitCompleteHandler() {
        @Override
        public void onSubmitComplete(SubmitCompleteEvent event) {
          callback.onSuccess(event.getResults());
        }
    });
  }
}

UiBinder 部分非常简单。
<g:HTMLPanel>
  <g:HorizontalPanel>
    <g:FormPanel ui:field="uploadForm">
      <g:FileUpload ui:field="fileUpload"></g:FileUpload>
    </g:FormPanel>
    <g:Button ui:field="uploadButton">Upload File</g:Button>
  </g:HorizontalPanel>
</g:HTMLPanel>

现在您可以扩展此类,以用于纯文本文件。只需确保您的web.xml将HttpServlet服务于/textupload端点即可。
public class UploadFileAsText extends UploadFile {

  public UploadFileAsText() {
    uploadForm.setAction(GWT.getModuleBaseURL() + "textupload");
  }
}

纯文本文件的Servlet位于服务器端。它将上传文件的内容返回给客户端。请确保在类路径上的某个位置安装了Apache Commons的FileUpload jar包。
public class TextFileUploadServiceImpl extends HttpServlet {

  private static final long serialVersionUID = 1L;

  @Override
  protected void doPost(HttpServletRequest request,
      HttpServletResponse response) throws ServletException, IOException {

    if (! ServletFileUpload.isMultipartContent(request)) {
      response.sendError(HttpServletResponse.SC_BAD_REQUEST,
          "Not a multipart request"); 
      return;
    }

    ServletFileUpload upload = new ServletFileUpload(); // from Commons

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

      if (iter.hasNext()) {
        FileItemStream fileItem = iter.next();

//      String name = fileItem.getFieldName(); // file name, if you need it

        ServletOutputStream out = response.getOutputStream();
        response.setBufferSize(32768);
        int bufSize = response.getBufferSize(); 
        byte[] buffer = new byte[bufSize];

        InputStream in = fileItem.openStream();
        BufferedInputStream bis = new BufferedInputStream(in, bufSize);

        long length = 0;

        int bytes; 
        while ((bytes = bis.read(buffer, 0, bufSize)) >= 0) {
          out.write(buffer, 0, bytes);
          length += bytes;
        }

        response.setContentType("text/html");
        response.setContentLength(
            (length > 0 && length <= Integer.MAX_VALUE) ? (int) length : 0);

        bis.close();
        in.close();
        out.flush();
        out.close();
      }
    } catch(Exception caught) {
      throw new RuntimeException(caught);
    }
  } 
}

我不记得我是如何解决
标签的问题的。你可能需要在客户端过滤标签。这个话题也在这里进行了讨论。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接