2012-03-15 95 views
4

我是GWT新手,正在尝试实现文件上传功能。 通过互联网找到了一些实现帮助,并将其用作参考。 但是有相关的一些问题:GWT FileUpload - Servlet选项和处理响应

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

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

  3. 目前,取回的响应,并使用SubmitCompleteEvent.getResults()之后,我越来越添加到实际反应,如一些HTML标签:

预>图片上传成功/ PRE>。

有没有办法摆脱?

非常感谢!

问候,

阿希什

回答

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

我不记得我是如何解决<pre></pre>标记问题的。您可能必须过滤客户端上的标签。该主题也被编为here