Java 从POST中保存拆分的上载文件最终为空

Java 从POST中保存拆分的上载文件最终为空,java,http,servlets,file-upload,http-post,Java,Http,Servlets,File Upload,Http Post,我正在尝试用Java完全实现一个可恢复的文件上传系统。我正在使用的库是resubable.js,它发送文件块以另存为.part,然后在最后将它们合并在一起。当我收到POST请求时,在我的doPost方法中,我接受请求,将其保存到HttpServletRequestWrapper中,然后使用它来获取我需要的所有数据。但是,当将文件另存为.part时,我的结果是文件为空,大小为0字节 我已经检查过了,数据似乎都在那里,但我似乎无法保存数据。是否有我执行错误的东西 下面是我用于执行此任务的代码的一小部

我正在尝试用Java完全实现一个可恢复的文件上传系统。我正在使用的库是resubable.js,它发送文件块以另存为
.part
,然后在最后将它们合并在一起。当我收到
POST
请求时,在我的
doPost
方法中,我接受请求,将其保存到
HttpServletRequestWrapper
中,然后使用它来获取我需要的所有数据。但是,当将文件另存为
.part
时,我的结果是文件为空,大小为0字节

我已经检查过了,数据似乎都在那里,但我似乎无法保存数据。是否有我执行错误的东西

下面是我用于执行此任务的代码的一小部分:

public void doPost(HttpServletRequest request, HttpServletResponse response) {
    try {
        HttpServletRequestWrapper wrapReq = new HttpServletRequestWrapper(request);
        BufferedReader reader = wrapReq.getReader();
        /**
        * Get some data from the BufferedReader
        */
        if(ServletFileUpload.isMultipartContent(wrapReq)){
            File mkd = new File(temp_dir);
            if(!mkd.isDirectory())
                mkd.mkdirs();

            DiskFileItemFactory factory = new DiskFileItemFactory();
            ServletFileUpload upload = new ServletFileUpload(factory);
            Iterator<FileItem> iter = upload.parseRequest(request).iterator();
            OutputStream out;

            out = new FileOutputStream(new File(dest_dir));
            while(iter.hasNext()){
                try {

                    FileItem item = iter.next();
                    IOUtils.copy(item.getInputStream(), out);                       
                    logger.debug("Wrote file " + resumableIdentifier + " with chunk number "
                            + resumableChunkNumber + " to " + temp_dir);
                    out.close();
                } catch (FileNotFoundException fnfe) {
                    fnfe.printStackTrace();
                }
            }
        }
        tryCreateFileFromChunks(temp_dir, resumableFileName, resumableChunkSize, resumableTotalSize);

    } catch (Exception e) {
        e.printStackTrace();
    }
}
public void doPost(HttpServletRequest请求,HttpServletResponse响应){
试一试{
HttpServletRequestWrapper wrapReq=新的HttpServletRequestWrapper(请求);
BufferedReader reader=wrapReq.getReader();
/**
*从BufferedReader获取一些数据
*/
if(ServletFileUpload.isMultipartContent(wrapReq)){
文件mkd=新文件(临时目录);
如果(!mkd.isDirectory())
mkd.mkdirs();
DiskFileItemFactory=新的DiskFileItemFactory();
ServletFileUpload upload=新的ServletFileUpload(工厂);
Iterator iter=upload.parseRequest(request.Iterator();
输出流输出;
out=新文件输出流(新文件(dest_dir));
while(iter.hasNext()){
试一试{
FileItem=iter.next();
复制(item.getInputStream(),out);
logger.debug(“写入的文件”+resumableIdentifier+“带有区块编号”
+可恢复弹簧编号+“至”+温度方向);
out.close();
}捕获(FileNotFoundException fnfe){
fnfe.printStackTrace();
}
}
}
tryCreateFileFromChunks(临时目录、resumableFileName、resumableChunkSize、ResumableTotalize);
}捕获(例外e){
e、 printStackTrace();
}
}
其中,
tryCreateFileFromChunks()
方法只是检查是否所有部分都在那里并合并它们。这不是问题所在。
.part
文件本身存储为空


那么,我是不是处理错了?我一直在努力让它正常工作。

您不应该使用
HttpServletRequestWrapper
,也不应该调用它的
getReader()
。请求正文只能读取一次,您必须选择是对同一个请求使用
getReader()
方法、还是
getInputStream()
方法、还是
getParameterXxx()
方法,并且不要混合使用它们

Apache Commons FileUpload在内部使用
getInputStream()
解析请求正文。但是如果您事先调用了
getReader()
getParameterXxx()
,那么Apache Commons FileUpload将获得一个空的请求正文

总之,要解决您的问题,只需将
wrapReq
全部删除即可

if(ServletFileUpload.isMultipartContent(request)){
    // ...
另见:

至少有一个错误。你的
out.close()在while循环内,而您在循环外打开流。如果iter包含多个元素,则必须产生错误的结果。我不确定这是否可以解决您的问题,但它肯定是一个bug。。。嗯,打开一个
FileOutputStream
到一个目录也应该失败(不确定),针对文件而不仅仅是目录打开它。但是我需要从
getReader()
获取的所有信息,例如块大小、文件名、块编号等。还有其他方法可以获取这些信息吗?它不在头中,调用
getParameterXxx()
也不会得到任何结果。我能够从请求负载中获取数据的唯一方法是调用
getReader()
所有这些数据都来自请求后。我从来没有听说过
resumable.js
,但在快速浏览其文档后,它似乎实际上发送了一个包含所有提到的信息的
多部分/表单数据
请求(块大小、数字等)作为表单数据元素。因此它们都可以在
FileItem
迭代器中使用。您只需以通常的方式检查
item.isFormField()
是否是表单字段或文件字段。这在“另请参阅”中有详细说明链接。就好像你在处理隐藏的输入字段一样。很抱歉,迟来的接受答案,我不得不去工作以应用更改