在 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。
如何解决这个问题。??
回答有点晚了,但我也遇到了同样的问题。
为什么会出现该异常: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();
}
}
我也有同样的问题。为了解决这个问题,我必须在阅读最后一项后跳出 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;
是解决我问题的线路。
每当您从表单字段访问数据时,请跳过该迭代。
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);
}
}
}