【问题标题】:Uploading file GWT using servlet使用 servlet 上传文件 GWT
【发布时间】:2013-04-10 17:07:46
【问题描述】:

我正在使用 GWT 开发应用程序,并尝试将文件上传到服务器(或目录)。我正在使用表单通过 FileUpload 小部件提交所选文件。我用于上传文件的 servlet 有问题:

package com.asso.server;

import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FilenameUtils;

/**
 * servlet to handle file upload requests
 * 
 * @author hturksoy
 * 
 */
public class FileUploadServlet extends HttpServlet {

        private static final String UPLOAD_DIRECTORY = "c:\\uploaded\\";
        private static final String DEFAULT_TEMP_DIR = ".";

        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp)
                        throws ServletException, IOException {
                // TODO Auto-generated method stub
                super.doGet(req, resp);
        }

        @Override
        protected void doPost(HttpServletRequest req, HttpServletResponse resp)
                        throws ServletException, IOException {

                // process only multipart requests
                if (ServletFileUpload.isMultipartContent(req)) {

                        File tempDir = getTempDir();
                        if (!tempDir.exists()) {
                                tempDir.mkdirs();
                        }

                        // Create a factory for disk-based file items
                        FileItemFactory factory = new DiskFileItemFactory();

                        // Create a new file upload handler
                        ServletFileUpload upload = new ServletFileUpload(factory);

                        // Parse the request
                        try {
                                List<FileItem> items = upload.parseRequest(req);
                                for (FileItem fileItem : items) {
                                        // process only file upload
                                        if (fileItem.isFormField()) continue;

                                        String fileName = fileItem.getName();
                                        // get only the file name not whole path
                                        if (fileName != null) {
                                        fileName = FilenameUtils. getName(fileName);
                                    }

                                        File uploadedFile = new File(UPLOAD_DIRECTORY, fileName);
                                        if (uploadedFile.createNewFile()) {
                                                fileItem.write(uploadedFile);
                                                resp.setStatus(HttpServletResponse.SC_CREATED);
                                                resp.getWriter().print("The file was created successfully.");
                                                resp.flushBuffer();
                                        } else
                                                throw new IOException("The file already exists in repository.");
                                }
                        } catch (Exception e) {
                                resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
                                                "An error occurred while creating the file : " + e.getMessage());
                        }

                } else {
                        resp.sendError(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE,
                                                        "Request contents type is not supported by the servlet.");
                }
        }

        private File getTempDir() {
                return new File(DEFAULT_TEMP_DIR);
        }

}

我得到这个错误:

java.lang.NoClassDefFoundError: org/apache/commons/fileupload/FileItemFactory
    at java.lang.Class.getDeclaredConstructors0(Native Method)
    at java.lang.Class.privateGetDeclaredConstructors(Unknown Source)
    at java.lang.Class.getConstructor0(Unknown Source)
    at java.lang.Class.newInstance0(Unknown Source)
    at java.lang.Class.newInstance(Unknown Source)
    at org.mortbay.jetty.servlet.Holder.newInstance(Holder.java:153)
    at org.mortbay.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:428)
    at org.mortbay.jetty.servlet.ServletHolder.getServlet(ServletHolder.java:339)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:487)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
    at com.google.appengine.api.socket.dev.DevSocketFilter.doFilter(DevSocketFilter.java:74)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.tools.development.ResponseRewriterFilter.doFilter(ResponseRewriterFilter.java:123)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:34)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:61)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:125)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.tools.development.DevAppServerServersFilter.doFilter(DevAppServerServersFilter.java:106)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
    at com.google.appengine.tools.development.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:94)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:421)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:326)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
    at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:938)
    at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:755)
    at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
    at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
    at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.fileupload.FileItemFactory
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at com.google.appengine.tools.development.IsolatedAppClassLoader.loadClass(IsolatedAppClassLoader.java:214)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    ... 41 more

我看到了这个主题,它说我应该添加commons-fileupload-1.3.jarcommons-io-2.4.jar,我已经完成了。 How to solve this java.lang.NoClassDefFoundError: org/apache/commons/io/output/DeferredFileOutputStream? 有什么解决办法吗? 编辑: 将 JAR 直接添加到我的 WEB-INF/lib 后,出现此错误

java.lang.NoClassDefFoundError: `java.io.FileOutputStream is a restricted class. Please see the Google  App Engine developer's guide for more details.
    at com.google.appengine.tools.development.agent.runtime.Runtime.reject(Runtime.java:51)
    at org.apache.commons.io.output.DeferredFileOutputStream.thresholdReached(DeferredFileOutputStream.java:178)
    at org.apache.commons.io.output.ThresholdingOutputStream.checkThreshold(ThresholdingOutputStream.java:224)
    at org.apache.commons.io.output.ThresholdingOutputStream.write(ThresholdingOutputStream.java:128)
    at org.apache.commons.fileupload.util.Streams.copy(Streams.java:108)
    at org.apache.commons.fileupload.util.Streams.copy(Streams.java:70)
    at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:347)
    at org.apache.commons.fileupload.servlet.ServletFileUpload.parseRequest(ServletFileUpload.java:115)
    at com.asso.server.FileUploadServlet.doPost(FileUploadServlet.java:56)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
    at com.google.appengine.api.socket.dev.DevSocketFilter.doFilter(DevSocketFilter.java:74)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.tools.development.ResponseRewriterFilter.doFilter(ResponseRewriterFilter.java:123)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.tools.development.HeaderVerificationFilter.doFilter(HeaderVerificationFilter.java:34)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.api.blobstore.dev.ServeBlobFilter.doFilter(ServeBlobFilter.java:61)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.tools.development.StaticFileFilter.doFilter(StaticFileFilter.java:125)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.appengine.tools.development.DevAppServerServersFilter.doFilter(DevAppServerServersFilter.java:106)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
    at com.google.appengine.tools.development.DevAppEngineWebAppContext.handle(DevAppEngineWebAppContext.java:94)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at com.google.appengine.tools.development.JettyContainerService$ApiProxyHandler.handle(JettyContainerService.java:421)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:326)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
    at org.mortbay.jetty.HttpConnection$RequestHandler.content(HttpConnection.java:938)
    at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:755)
    at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:218)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
    at org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:409)
    at org.mortbay.thread.QueuedThreadPool$PoolThread.run(QueuedThreadPool.java:582)`

【问题讨论】:

  • 你重启服务器了吗? (关闭开发模式并重新启动而不是重新启动按钮)
  • 是的,我做过很多次!
  • 您是在使用 maven 还是将 apache jar 复制到 WEB-INF/lib 中?是 Dev 模式还是 Prod 模式的错误?

标签: java gwt servlets file-upload


【解决方案1】:

确保您没有错过将文件 commons-fileupload-1.3.jar 和 commons-io-2.4.jar 复制到您的 WEB-INF/lib 中。您还应该检查您的启动类路径是否有 devmode。

示例 - 我已将示例 jar 添加到我的库中,并且可以通过我的启动配置看到相同的内容。

更新 - 如果您使用的是 GAE,请仔细阅读

  1. GWT - image upload and GAE
  2. How to upload and store an image with google app engine (java)

【讨论】:

  • 我没有将它们复制到 WEB-INF/lib,我已将它们添加为外部 JAR。但我的构建路径和类路径中有它们
  • 避免发布更新作为答案!!!由于您正在尝试使用谷歌应用引擎,您的查询可能会由stackoverflow.com/questions/1513603/… 回答
  • 我没有更新回答我更新了,因为问题还没有解决,还有其他问题。您可以查看下面的答案,问题已解决但有其他错误谢谢您的帮助!
【解决方案2】:

一个 Google App Engine 应用程序cannot write to the filesystem

您使用的 DiskFileItemFactory 对象尝试写入文件系统,因此您得到以下异常:

java.lang.NoClassDefFoundError: `java.io.FileOutputStream is a restricted class. Please see the Google  App Engine developer's guide for more details.

这是DiskFileItemFactory documentation的解释:

此实现创建 FileItem 实例,这些实例保留其 内容要么在内存中,对于较小的项目,要么在临时文件中 磁盘,用于较大的项目。大小阈值,超过该阈值的内容将 存储在磁盘上,是可配置的,在其中的目录也是 将创建临时文件。如果没有另外配置,则 默认配置值如下:大小阈值为10KB。

解决办法: 您应该增加文件大小阈值。覆盖默认值。将其设置为您希望上传到 servlet 的最大文件大小。

DiskFileItemFactory factory= new DiskFileItemFactory(5000000,null);

DiskFileItemFactory factory= new DiskFileItemFactory();
factory.setSizeThreshold(5000000);

【讨论】:

    猜你喜欢
    • 2017-10-06
    • 1970-01-01
    • 2014-03-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-10
    • 2011-05-10
    相关资源
    最近更新 更多