上传文件停止并在套接字异常上读取意外的 EOF
Posted
技术标签:
【中文标题】上传文件停止并在套接字异常上读取意外的 EOF【英文标题】:Upload file stop with Unexpected EOF read on the socket Exception 【发布时间】:2016-04-10 14:55:28 【问题描述】:有时当我尝试在远程 vps 上上传文件时出现此异常(上传过程停止在 60%)
06-Jan-2016 11:59:36.801 SEVERE [http-nio-54000-exec-9] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [mvc-dispatcher] in context with path [] threw exception [Request processing failed;
nested exception is org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request;
nested exception is org.apache.commons.fileupload.FileUploadBase$IOFileUploadException: Processing of multipart/form-data request failed. Unexpected EOF read on the socket]
with root cause
java.io.EOFException: Unexpected EOF read on the socket
在Google Chrome
中,连接丢失,就像服务器关闭一样,我得到ERR_CONNECTION_ABORTED
我在spring mvc中上传这样的文件
public void save_file(MultipartFile upfile , String path)
try
File fichier = new File( path ) ;
byte[] bytes = upfile.getBytes();
BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream( fichier ));
stream.write(bytes);
stream.close();
System.out.println( "You successfully uploaded " + upfile.getOriginalFilename() + "!" );
catch (Exception e)
System.out.println( "You failed to upload " + upfile.getOriginalFilename() + " => " + e.getMessage() ); ;
我的控制器:
@RequestMapping(value = "/administration/upload", method = RequestMethod.POST)
public String Upload_AO_journal(
@ModelAttribute UploadForm uploadForm,
Model map , HttpServletRequest request, HttpSession session ) throws ParseException, UnsupportedEncodingException
我的豆子
public class UploadForm
...
public MultipartFile scan;
那么如何解决这个问题呢?
【问题讨论】:
所有文件大小都失败,还是小文件成功?您可以分享将请求映射到此方法的特定于 spring 的代码吗? @tdimmig 有时它会失败,有时对于相同的大小它是好的!我更新了我的问题。 看看这个答案能不能帮到你:***.com/a/18543887/4056187 【参考方案1】:你试过直播吗?
jsp代码:
<form method="POST" onsubmit="" ACTION="url?$_csrf.parameterName=$_csrf.token" ENCTYPE="multipart/form-data">
控制器:
@RequestMapping(
value = "url", method = RequestMethod.POST
)
public void uploadFile(
@RequestParam("file") MultipartFile file
) throws IOException
InputStream input = upfile.getInputStream();
Path path = Paths.get(path);//check path
OutputStream output = Files.newOutputStream(path);
IOUtils.copy(in, out); //org.apache.commons.io.IOUtils or you can create IOUtils.copy
spring 4.0 和 spring security 对我有用。
其次,您应该检查http连接是否超时。 Chrome 不支持该配置。所以你可以使用 Firefox 并关注这里http://morgb.blogspot.com.es/2014/05/firefox-29-and-http-response-timeout.html。
【讨论】:
文件的 apache api 比文件的默认 java api 更安全? 我使用它,只是因为它干净且经过测试。我不认为它更安全。 @Youssef 我面临着类似的问题,但在我的情况下,我在 finally 块中关闭流。这里不需要关闭输入输出流吗?【参考方案2】:不确定 upfile 上的 getBytes() 方法。更合适的方法是使用 InputStream 来管理任何大小的文件,并在必要时进行缓冲。比如:
public void save_file(MultipartFile upfile , String path)
try
File fichier = new File( path ) ;
BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream( fichier ));
InputStream is = upfile.getInputStream();
byte [] bytes = new byte[1024];
int sizeRead;
while ((sizeRead = is.read(bytes,0, 1024)) > 0)
stream.write(bytes, 0, sizeRead);
stream.flush();
stream.close();
System.out.println( "You successfully uploaded " + upfile.getOriginalFilename() + "!" );
catch (Exception e)
System.out.println( "You failed to upload " + upfile.getOriginalFilename() + " => " + e.getMessage() ); ;
【讨论】:
为什么是new byte[1024]
?大小将除以 1024 ?
你可以把它做成你需要的任何大小,1024是1K,通常是下载性能最高的大小。你试过了吗?
还没回家我试试【参考方案3】:
出现此问题是因为您关闭流直到流写入整个数据。
错误的方式:
stream.write(bytes);
stream.close();
正确的方式:
try (BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(fichier)))
stream.write(data);
您应该在写入整个数据后关闭您的流。
【讨论】:
当然,stream.close() 应该放到 finally 块中。【参考方案4】:我遇到了类似的问题,问题是当您上传文件时,您正在使用 Multipart Form POST 请求。您可以阅读有关MIME 的信息。
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary=frontier
This is a message with multiple parts in MIME format.
--frontier
Content-Type: text/plain
This is the body of the message.
--frontier
Content-Type: application/octet-stream
Content-Transfer-Encoding: base64
PGh0bWw+CiAgPGhlYWQ+CiAgPC9oZWFkPgogIDxib2R5PgogICAgPHA+VGhpcyBpcyB0aGUg
Ym9keSBvZiB0aGUgbWVzc2FnZS48L3A+CiAgPC9ib2R5Pgo8L2h0bWw+Cg==
--frontier--
我遇到的基本问题是请求中的多部分具有元信息部分、文本部分和我相信 base64 编码的实际文件。每个部分都按边界分割。如果您没有正确设置此边界(在上面的示例中,它被称为“边界”),服务器开始读取文件,但在到达 EOF 之前不知道它在哪里结束,并返回有关意外 EOF 的错误,因为它没有找到所需的边界。
您的代码的问题是您正在将文件写入 ByteOutputStream,这适用于将文件从服务器返回给用户而不是其他方式。服务器期望这个 Multipart 请求带有一些标准的预定义格式。使用Apache Commons HttpClient 库为您完成所有这些请求格式和边界设置。如果你使用 Maven,那么this link。
File f = new File("/path/fileToUpload.txt");
PostMethod filePost = new PostMethod("http://host/some_path");
Part[] parts =
new StringPart("param_name", "value"),
new FilePart(f.getName(), f)
;
filePost.setRequestEntity(
new MultipartRequestEntity(parts, filePost.getParams())
);
HttpClient client = new HttpClient();
int status = client.executeMethod(filePost);
免责声明:代码不是我的,它是来自Apache website for multipart request的示例
【讨论】:
从他的问题我了解到他是从 Spring 客户端上传的,因为他说“我在 spring mvc 中上传这样的文件”这就是为什么我认为他是从客户端上传的原因 我猜他的意思是“进入”。他在客户端使用谷歌浏览器上传,服务器端有 Spring MVC。 @MichaelDD 是的,我使用浏览器 哦,抱歉,我没有正确理解这个问题。从客户端上传时我遇到了同样的问题,所以我认为这也是你的情况 没问题兄弟..我可以在未来面对你的问题【参考方案5】:当我没有正确设置要放置文件的路径时,我遇到了同样的错误。
解决方法是这样改变它:
factoryMaster.setCertificateFile("E:\\Project Workspace\\Live Projects\\fileStore\\Factory Master\\"+factoryMasterBean.getFile().getOriginalFilename());
并在控制器中使用 throws 异常:
public @ResponseBody ResponseEntity<FactoryMaster> saveFactoryMaster(@ModelAttribute("factoryMasterBean") FactoryMasterBean factoryMasterBean,FactoryMaster factoryMaster) throws IllegalStateException, IOException ...............
并确保不要发送任何已存在的同名文件。
【讨论】:
以上是关于上传文件停止并在套接字异常上读取意外的 EOF的主要内容,如果未能解决你的问题,请参考以下文章
org.eclipse.jetty.io.EofException:上传大文件时抛出早期 EOF
拿来。 Stripe 集成在本地主机上工作,并在上传到 Firebase 后停止工作