有时当我尝试在远程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;
那怎么能解决这个问题呢?
答案 0 :(得分:5)
你试过流吗?
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
}
所有这些都适用于我的春季4.0和春季安全。
其次,您应该检查http连接是否超时。 Chrome不支持该配置。所以你可以使用firefox并点击这里http://morgb.blogspot.com.es/2014/05/firefox-29-and-http-response-timeout.html。
答案 1 :(得分:2)
出现此问题是因为您关闭流直到流写入整个数据。
错误的方式:
stream.write(bytes);
stream.close();
正确的方式:
try (BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(fichier)))
{
stream.write(data);
}
您应该在写完整个数据后关闭您的信息流。
答案 2 :(得分:1)
不确定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() ); ;
}
}
答案 3 :(得分:1)
我有类似的问题和问题,当你上传文件时,你正在使用Multipart Form POST Request。你可以阅读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。每个部分都按边界分割。如果您没有设置此边界(例如上面的示例,它被称为&#34; frontier&#34;)正确的服务器开始读取文件但是在它到达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
答案 4 :(得分:0)
当我没有正确设置文件放置路径时,我遇到了同样的错误。
解决方法是像这样更改它:
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 {...............}
并确保不要发送任何已经存在的同名文件。