Embedded jetty 11 - 处理文件上传和文件上传进度

Embedded jetty 11 - Handling file upload and file upload progress

在将 java 和 jetty 升级到版本 11(从版本 8)之前,我有一个嵌入式 jetty 服务器可以接受上传请求。我刚刚升级,现在我处理这样的请求(这与之前非常相似):


@Path("/")
public class FilesRestService {
    @POST
    @Path("/files/upload")
    @Produces("application/json")
    @Consumes("multipart/form-data")
    public WebapiResult<FileUploadResponse> uploadFile() {
        return getFilesImpl().uploadFile();
    }
}

然后在 uploadFile() 方法中,我这样设置多部分配置:

if (request.getContentType().startsWith("multipart/")) {
    request.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT, new MultipartConfigElement("/storage/tmp"));
}

List<Part> multipartItems = new ArrayList<>();
try {
    multipartItems = (List<Part>) request.getParts();
} catch (Exception e) {
    logger.error("Error uploading file: ", e);
}

[... here I obtain the parts and get the file one ( part )]


 String fileFinalPath = "/storage/userfiles/uploadedFIle.txt";
 // Moves file
 File destFile = new File(fileFinalPath);
 try (InputStream input = part.getInputStream()) {
     boolean movedSuccessfully = Files.copy(input, destFile.toPath(), StandardCopyOption.REPLACE_EXISTING) > -1;
     if (movedSuccessfully) {
         return fileFinalPath;
     } else {
         return "";
     }
 }

这样做,我发现文件已正确移动到最终文件夹中,但是,在调试和上传时,即使文件很大,我也没有在临时文件夹中看到该文件,所以我想知道如果它使用正确的多部分配置。
我还读到应该使用注释 @MultipartConfig 但我使用的是嵌入式码头所以我不能让它工作(至少我没有发现)。

另一个问题是我无法找到一种方法来实现带有嵌入式码头 11 的进度侦听器,因为执行 request.getParts() 只会卡住,直到所有文件都上传完毕。
我目前使用的是 jetty 版本 11.0.6

如何实现进度监听和正确的文件上传?

编辑:经过一些额外的研究,我发现一些文章 说上传监控不应该在服务器端完成,但可以在请求中完成,所以客户端......是这是正确的方法吗?尽管如此,我没有看到 tmp 上传文件的问题仍然存在。

在您的示例代码中,您的方向是正确的。

if (request.getContentType().startsWith("multipart/")) {
    request.setAttribute(Request.__MULTIPART_CONFIG_ELEMENT, 
       new MultipartConfigElement("/storage/tmp"));
}

有两点需要注意。

仅使用 multipart/form-data 作为内容类型,multipart/* space 中的任何其他内容不受 HttpServletRequest.getParts()MultipartConfigElement 的影响。 (例如:multipart/byteranges

接下来,正确配置MultipartConfigElement

设置最大大小,以便在超过您在此处配置的阈值时将文件正确写入磁盘。 (IIRC,默认是全部保存在内存中)

就上传进度而言,是的,你是对的。 最好的地方是在客户端。