这就是我正在做的事情。我想通过 Ajax 将多部分文件上传到我的 Spring Web 应用程序。当服务器收到 POST 请求时,它会在数据库中创建一个票号。然后它启动一个处理实际文件上传的线程。然后服务器返回票号。
我正在使用 CommonsMultipartResolver 来处理请求,并且我已将 resolveLazily 标志设置为 true,以便不会立即解析 Multipart。
所以这是我所拥有的
@Controller
public class myController{
@RequestMapping(value = "/upload", method = RequestMethod.POST)
@ResponseStatus(value = HttpStatus.OK)
@ResponseBody
public String upload(MultipartHttpServletRequest request, String fileName){
String ticket = dao.createUploadTicket(fileName);
Runnable run = new Runnable(){
@Override
public void run(){
dao.writeUpdate(ticket, "Getting data from request");
final MultipartFile file = request.getFile("theFile");
dao.writeUpdate(ticket, "Multipart file processed");
try {
dao.writeUpdate(ticket, "Saving file to disk");
file.transferTo(new File("/myDirectory"));
dao.writeUpdate(ticket, "File saved to disk");
}
catch(Exception e){
dao.writeUpdate(ticket, "File upload failed with the exception " + e.toString());
}
}
};
Thread t = new Thread(run);
t.start();
return ticket;
}
}
所以这里的重点是票号可以用来获取进度更新。假设正在上传一个大文件。使文件上传 POST(在本例中为 Ajax 请求)的客户端可以异步执行此操作并取回票号。客户端可以使用该票号来确定文件上传的阶段并在另一个页面中显示信息。
另一种用途是,我可以有一个 HTML 页面,它向服务器请求所有票号,然后显示服务器上发生的所有文件上传的“实时”视图。
我无法让它工作,因为一旦控制器返回,Spring 就会在 CommonsMultipartResolver 中调用 cleanupMultipart()。由于 resolveLazily 标志设置为 false,所以当 cleanupMultipart() 被调用时,它将开始解析和初始化多部分文件。这会导致调用“request.getFile("theFile");”之间的竞争条件。在 runnable 和 cleanupMultipart() 调用中最终导致异常。
有人有想法么?我是否通过想要进行后端异步文件处理来打破某种 HTTP 合同。