【问题标题】:GWT FileUpload - Servlet options and handling responseGWT FileUpload - Servlet 选项和处理响应
【发布时间】:2012-03-31 12:38:35
【问题描述】:

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

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

  2. 在我的 servlet 中,一切都完成后,我需要将响应返回给客户端。 我认为 form.addSubmitCompleteHandler() 可以用来实现这一点。从 servlet,我可以返回 text/html(或 String 类型对象),然后使用 SubmitCompleteEvent.getResults() 来获取结果。 问题是我可以使用我的自定义对象而不是字符串(比如说 MyFileUploadResult),在其中填充结果然后将其传递回客户端吗? 或者我可以取回 JSON 对象吗?

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

pre> 图片上传成功 /pre> .

有没有办法摆脱它?

提前非常感谢!

问候,

阿什

【问题讨论】:

    标签: gwt servlets file-upload form-submit


    【解决方案1】:

    为了上传文件,我过去扩展了 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/textupload 的 HttpServlet 提供服务。

    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);
        }
      } 
    }
    

    我不记得我是如何解决&lt;pre&gt;&lt;/pre&gt; 标签问题的。您可能必须过滤客户端上的标签。该主题也解决了here

    【讨论】:

      猜你喜欢
      • 2012-11-05
      • 2016-06-23
      • 1970-01-01
      • 2021-04-05
      • 2012-01-29
      • 1970-01-01
      • 1970-01-01
      • 2011-07-13
      • 1970-01-01
      相关资源
      最近更新 更多