GWT中的基本文件上传

48

我正在尝试找出如何使用GWT的FileUpload小部件上传一个文件。 我正在使用GWT和Google AppEngine与Java,但我想将文件上传到自己的Linux服务器。 我已经有了下面的代码,但是现在我不知道如何将我的文件提交到Google AppServer服务器并保存到另一台服务器:

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(如果可能)

4个回答

62

以下是来自我的应用程序的代码:

1)我创建了一个类来接受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 Web服务器。OP选择了你的答案作为最佳答案,所以我猜它对他的问题有所帮助,但是我不知道应该把FileUpload类放在哪里,是和其他项目文件一起放在GAE上吗?那Linux服务器呢?它如何接收文件?地址在哪里指定?文件名又在哪里?这段代码让我感到困惑。 - Leo Jweda
3
10 MiB不是"10*(10242)",而是"101024*1024","megs"是否是2 KiB的替代名称? - Stein G. Strindhaug
2
10*(1024*2) 是20Kb,而不是10Mb。 - Anthony
3
+1,但我希望你添加导入项,这样我就不必逐个在谷歌上搜索。它们是:import java.io.InputStream; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; org.apache.commons.fileupload.FileItemIterator; org.apache.commons.fileupload.FileItemStream; org.apache.commons.fileupload.servlet.ServletFileUpload; org.apache.commons.fileupload.FileUploadException; - mgiuca
5
我认为你忘记说这个JAR文件应该被包含在类路径中:http://commons.apache.org/fileupload/download_fileupload.cgi - Erel Segal-Halevi
显示剩余2条评论

11

我建议使用GWTUpload,因为它非常容易使用和扩展。您可以在不到10分钟的时间内将其添加到您的项目中,并且它直接支持GAE(使用GWTUpload-GAE)。请参阅示例以获取一些常见的使用场景。


2
注意:GWTUpload 需要会话。 - Riley Lark
1
使用GWTUpload相比@KevMo提供的解决方案有哪些优缺点? - kroiz
2
GWTUpload 允许异步上传,具有状态更新、多文件上传等功能。它似乎是常见 Flash 替代品的完整替代品。 - rluba

5
在 GWT 中,您可以使用 HTTP 表单方法将文件上传到服务器,并且必须使用提供的 HttpServlet 将数据保存为二进制博客文件在 Appengine BigTable 中。
然后,您需要第二个 HttpServlet 从 BigTable 中读取文件,设置HTTP头中的 MIME 类型(以及缓存选项),然后将文件流式传输给用户。
虽然不一定需要使用 RPC,但必须让客户端知道生成的文件Id,以便他们可以访问它(除非您想让用户提供ID并强制他们担心名称覆盖...). 你可以使用Rpc来请求列表/单个ID(例如“用户的最新文件ID”),或者你可以将该ID返回到UploadServlet响应的正文中...但是然后,您必须确保您的帖子目标是一个页面内iframe,在提交事件和实际服务器响应之间轮询以确保iframe有正文,然后在gwt中解析和使用该id创建使用该文件的图像或对象标记。
关键部分在于有一个用于上传的servlet,另一个用于下载。请记住,BigTable只存储二进制Blob,因此您还需要使数据实体具有可从输入文件读取的MIME /内容类型(永远不要依赖文件扩展名!)。此外,BigTable中每个实体的限制为1MB,免费帐户的请求限制为10MB。您可能希望使数据实体包含1-10个Blob的列表,每个Blob的最大大小为1024字节。
基本上,您最好找到一个可用的免费副本,如Google文件服务,并进行扩展以了解系统如何工作。
如果您愿意,我将发布自己的开源版本的文件处理,一旦我完成gwt控件小部件并认为这一切足够稳定,以便于任何人使用。如果您想让我向您发送一份betalicious代码JAR,请发送电子邮件至x@aiyx.info。

1

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