【问题标题】:Commons File Upload Not Working In Servlet公共文件上传在 Servlet 中不起作用
【发布时间】:2011-06-01 16:18:09
【问题描述】:

我有一个 servlet,用于处理超大文件的上传。我正在尝试使用 commons fileupload 来处理它。目前,我尝试上传的文件为 287MB。

我设置了 FileItemFactory 和 ServletFileUpload,然后在 ServletFileUpload 上设置了一个非常大的最大文件大小。

不幸的是,当我尝试创建 FileItemIterator 时,没有任何反应。表单设置了正确的操作、多部分编码和 POST 方法。

有人可以帮忙吗? servlet 的 doPost() 贴在下面:

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

    // ensure that the form is multipart encoded since we are uploading a file
    if (!ServletFileUpload.isMultipartContent(req)) {
        //throw new FileUploadException("Request was not multipart");
        log.debug("Request was not multipart. Returning from call");
    }

    // create a list to hold all of the files
    List<File> fileList = new ArrayList<File>();
    try {
        // setup the factories and file upload stuff
        FileItemFactory factory = new DiskFileItemFactory();
        ServletFileUpload upload = new ServletFileUpload(factory);
        upload.setFileSizeMax(999999999);

        // create a file item iterator to cycle through all of the files in the req. There SHOULD only be one, though
        FileItemIterator iterator = upload.getItemIterator(req);

        // iterate through the file items and create a file item stream to output the file
        while (iterator.hasNext()) {

            // get the file item stream from the iterator
            FileItemStream fileItemStream = iterator.next();

            // Use the Special InputStream type, passing it the stream and the length of the file
            InputStream inputStream = new UploadProgressInputStream(fileItemStream.openStream(), req.getContentLength());

            // create a File from the file name
            String fileName = fileItemStream.getName();  // this only returns the filename, not the full path
            File file = new File(tempDirectory, fileName);

            // add the file to the list
            fileList.add(file);

            // Use commons-io Streams to copy from the inputstrea to a brand-new file
            Streams.copy(inputStream, new FileOutputStream(file), true);

            // close the inputstream
            inputStream.close();

        }
    } catch (FileUploadException e) {
        e.printStackTrace();
    }

    // now that we've save the file, we can process it.
    if (fileList.size() == 0) {
        log.debug("No File in the file list. returning.");
        return;
    }

    for (File file : fileList) {

        String fileName = file.getName();
        BufferedReader reader = new BufferedReader(new FileReader(fileName));

        String line = reader.readLine();
        List<Feature> featureList = new ArrayList<Feature>(); // arraylist may not be the best choice since I don't know how many features I'm importing
        while (!line.isEmpty()) {
            String[] splitLine = line.split("|");
            Feature feature = new Feature();
            feature.setId(Integer.parseInt(splitLine[0]));
            feature.setName(splitLine[1]);
            feature.setFeatureClass(splitLine[2]);
            feature.setLat(Double.parseDouble(splitLine[9]));
            feature.setLng(Double.parseDouble(splitLine[10]));
            featureList.add(feature);

            line = reader.readLine();
        }

        file.delete();   // todo: check this to ensure it won't blow up the code since we're iterating in a for each
        reader.close();  // todo: need this in a finally block somewhere to ensure this always happens.

        try {
            featureService.persistList(featureList);
        } catch (ServiceException e) {
            log.debug("Caught Service Exception in FeatureUploadService.", e);

        }
    }
}

【问题讨论】:

  • “什么都没有发生”,所以代码卡在那个点并永远挂在那里?不就是忙着读请求体吗?还是hasNext() 立即返回false?请更具体地说明问题。哪些行被执行,哪些不被执行。哦,您的第一张 if 支票根本没有返回...
  • 很公平。失败点的开始似乎是对upload.getItemIterator(req) 的调用。返回一个 FileItemIterator,但它是“空的”:对 iterator.hasNext() 的调用返回 false。
  • 好的,很清楚 :) 可以肯定的是,ServletFileUpload.isMultipartContent(req) 确实返回了true?您只在 false 的情况下记录它,然后不管其结果如何继续代码流。
  • 我添加了 return 语句(感谢您指出这一点)。是的,ServletFileUpload.isMultipartContent(req) 确实返回了 true(我在其中设置了一个断点和一个手表来仔细检查)。
  • 好的,谢谢。当你上传一个小文件时怎么样?例如。 foo.txt 里面有 hello 还是什么?如果这也没有给出任何结果,请让我们知道当您在代码的开头执行Streams.copy(request.getInputStream(), System.out, false); return; 时会得到什么?

标签: java servlets apache-commons-fileupload


【解决方案1】:

这是一个非常愚蠢的问题。我在 GWT UiBinder 中的 FileUpload 条目中保留了 name 属性。感谢大家的帮助。

【讨论】:

  • 哇,我也遇到了完全相同的问题,您的解决方案对我帮助很大!谢谢!
【解决方案2】:

是否只有可用的请求参数文件项?因为您可能需要检查:

if (!fileItemStream.isFormField()){
// then process as file

否则你会得到错误。从表面上看,您的代码看起来不错:Tomcat 日志中没有错误?

【讨论】:

  • 只有一个文件上传字段和两个按钮(提交和取消)。但是,我忘记了,谢谢。
  • 该项目是以托管模式(jet​​ty)运行的 GWT 项目。但是,我没有看到任何异常抛出。
  • 啊。好吧,不确定:从未尝试过使用 GWT 上传文件。它不会以某种奇怪的方式破坏请求吗?
【解决方案3】:

需要在html表单中添加enctype='multipart/form-data'

【讨论】:

    猜你喜欢
    • 2015-09-17
    • 2018-10-02
    • 2012-09-30
    • 1970-01-01
    • 2019-07-05
    • 2010-09-18
    • 1970-01-01
    • 1970-01-01
    • 2019-03-19
    相关资源
    最近更新 更多