为什么会出现此异常 FileItemStream$ItemSkippedException?

问题描述 投票:0回答:3

在 gwt Web 应用程序中。 我必须发送一个文件和附加的一些参数。

在服务器端

try {

        ServletFileUpload upload = new ServletFileUpload();

        FileItemIterator iterator = upload.getItemIterator(request);

        while (iterator.hasNext()) {
            FileItemStream item = iterator.next();


            if (item.isFormField()) {

                String fieldName=item.getFieldName();
                String fieldValue = Streams.asString(item.openStream());
                System.out.println(" chk  " +fieldName +"  =  "+ fieldValue);
            } else {
                stream = item.openStream();
                fileName = item.getName();
                mimetype = item.getContentType();
                int c;
                while ((c = stream.read()) != -1) { 
                  System.out.print((char) c); 
                    }
            }
        }
    }catch (Exception e) {
        // TODO: handle exception
        e.printStackTrace();
    }
    System.out.println("out of try");
    ByteArrayOutputStream output = new ByteArrayOutputStream();
    int nRead;
    while ((nRead = stream.read(buffer, 0, buffer.length)) != -1) {
        System.out.println("lenth111" +nRead);
        output.write(buffer, 0, nRead);
    }
    System.out.println("lenth" +nRead);
    output.flush();

使用此代码我可以读取流。 并且还在控制台上“out of try”也打印了

最后

while ((nRead = stream.read(buffer, 0, buffer.length)) != -1)
我收到一条警告线

警告:/UploadFileServlet:org.apache.commons.fileupload.FileItemStream$ItemSkippedException。

如何解决这个问题。??

java file-upload apache-commons-fileupload
3个回答
10
投票

回答有点晚了,但我也遇到了同样的问题。

为什么会出现该异常:ItemSkippedException 的 JavaDocs 解释了一点:

如果在创建 FileItemStream 的迭代器上调用 Iterator.hasNext() 之后尝试从 FileItemStream.openStream() 返回的 InputStream 读取数据,则会引发此异常。

您在 while 循环之外使用 InputStream stream,这会导致问题,因为调用了另一个迭代,该迭代会关闭(跳过)您尝试从中读取的文件 InputStream。

解决方案:在while循环中使用InputStream。如果您在处理文件之前需要所有表单字段,请确保在客户端按正确的顺序进行设置。首先是所有字段,最后是文件。例如使用 JavaScript FormData:

var fd = new window.FormData();

fd.append("param1", param1);
fd.append("param2", param2);

// file must be last parameter to append
fd.append("file", file);

在服务器端:

FileItemIterator iter = upload.getItemIterator(request);
while (iter.hasNext()) {
    FileItemStream item = iter.next();
    InputStream stream = item.openStream();

    // the order of items is given by client, first form-fields, last file stream
    if (item.isFormField()) {
        String name = item.getFieldName();
        String value = Streams.asString(stream);
        // here we get the param1 and param2
    } else {
        String filename = item.getName();
        String mimetype = item.getContentType();

        ByteArrayOutputStream output = new ByteArrayOutputStream();
        int nRead;
        while ((nRead = stream.read(buffer, 0, buffer.length)) != -1) {
            System.out.println("lenth111" +nRead);
            output.write(buffer, 0, nRead);
        }
        System.out.println("lenth" +nRead);
        output.flush(); 
    }
}

0
投票

我也有同样的问题。为了解决这个问题,我必须在阅读最后一项后跳出 while 循环:

import java.io.InputStream;
import org.apache.commons.fileupload.FileItemIterator;
import org.apache.commons.fileupload.FileItemStream;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.util.Streams;

final String ID = "id";
final String FILE_NAME = "fileName";
final String APIKEY = "apikey";

DiskFileItemFactory factory = new DiskFileItemFactory();
ServletFileUpload upload = new ServletFileUpload(factory);      

String id = null;
String apikey = null;
String fileName = null;
InputStream stream = null;

FileItemIterator iterator = upload.getItemIterator(request);
outer: while (iterator.hasNext()) {
    FileItemStream item = iterator.next();
    switch (item.getFieldName()) {
    case ID:
        id = Streams.asString(item.openStream());
        break;
    case APIKEY:
        apikey = Streams.asString(item.openStream());
        break;
    case FILE_NAME:
        fileName = item.getName();
        stream = item.openStream();
        break outer;
    }
}

break outer;
是解决我问题的线路。


0
投票

每当您从表单字段访问数据时,请跳过该迭代。

while (iterator.hasNext()) { FileItemStream item = iterator.next();

        if (item.isFormField()) {

            String fieldName=item.getFieldName();
            String fieldValue = Streams.asString(item.openStream());
            System.out.println(" chk  " +fieldName +"  =  "+ fieldValue);
            continue;//// this line you need to add. then it will close the FileItemStream object for that iteration
        } else {
            stream = item.openStream();
            fileName = item.getName();
            mimetype = item.getContentType();
            int c;
            while ((c = stream.read()) != -1) { 
              System.out.print((char) c); 
                }
        }
    }
© www.soinside.com 2019 - 2024. All rights reserved.