关于fileupload里面的Stream ended unexpectedly

项目需要做一个客户端将崩溃日志文件发送到服务器的功能,然后同事就用到了apache的commons-fileupload-1.3.1.jar这个包,部分代码如下:

ServletFileUpload upload = new ServletFileUpload();
				upload.setHeaderEncoding("utf-8");

				// Set overall request size constraint
				upload.setSizeMax(4194304); // 设置最大文件尺寸,这里是4MB
				upload.setFileSizeMax(3 * 1024 * 1024l);

				FileItemIterator i = upload.getItemIterator(request);//得到所有的文件
				//Iterator i = items.iterator();
				FileOutputStream fout = null;
				BufferedOutputStream bout = null;
				BufferedInputStream bin = null;
				try {
					while (i.hasNext()) {
						FileItemStream item = i.next();
						String name = item.getName();
						out.println(name);
						InputStream stream = item.openStream();
						File f = new File("/" + item.getName());

						System.out.println(f.getAbsolutePath());

						fout = new FileOutputStream(f);
						bout = new BufferedOutputStream(fout);
						bin = new BufferedInputStream(stream);

						int byte_;

						while ((byte_ = bin.read()) != -1) {
							bout.write(byte_);
						}

						bout.close();
						bin.close();
					}
				} catch (Exception e) {
					e.printStackTrace();
					if (fout != null) {
						fout.close();
					}
					if (bout != null) {
						bout.close();
					}
					if (bin != null) {
						bin.close();
					}
				}

代码因为照着apache的格式写的,所以也没啥问题。但是每次测试都会报错,错误日志如下:

org.apache.commons.fileupload.MultipartStream$MalformedStreamException: Stream ended unexpectedly
	at org.apache.commons.fileupload.MultipartStream$ItemInputStream.makeAvailable(MultipartStream.java:1005)
	at org.apache.commons.fileupload.MultipartStream$ItemInputStream.close(MultipartStream.java:943)
	at org.apache.commons.fileupload.MultipartStream$ItemInputStream.close(MultipartStream.java:922)
	at java.io.FilterInputStream.close(FilterInputStream.java:181)
	at org.apache.commons.fileupload.util.LimitedInputStream.close(LimitedInputStream.java:164)
	at java.io.BufferedInputStream.close(BufferedInputStream.java:472)
	at org.apache.jsp.fileupload_jsp._jspService(fileupload_jsp.java:210)
	at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
	at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
	at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
	at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)

	at javax.servlet.http.HttpServlet.service(HttpServlet.java:727)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at com.sharp.filter.AuthorityFilter.doFilter(AuthorityFilter.java:52)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
	at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2441)
	at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2430)

	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
	at java.lang.Thread.run(Thread.java:744)


网上查了一下,答案很多。大致分为以下几类:

1、session超时断开连接,解决方案:

修改tomcat配置文件server.xml,找到类似于下面配置:


将上面的参数disableUploadTimeout值改为false即可。

2、文件过大,还是修改server.xml。在connector里面添加配置 maxPostSize="0" ,0表示无限大。


这两种方法都尝试了,还是没找到问题所在,然后找到我,我也是最开始在stackovverflow,csdn等网站上看了各种答案并尝试还是不行。后来断点看了一下流的信息,发觉后面很大一部分数据都是空的,那么就怀疑是不是被整个框架中间拦截导致的,于是查看了一下web.xml,发现中间有个filter,而filter因为之前项目功能需求对所有请求进行了拦截和修改,于是将这个filter的代码注释之后终于成功了。


总结下来就是 查看在fileupload进行解析request之前,看看request是不是已经进行了修改。











你可能感兴趣的:(java)