首页 > 解决方案 > Embedded jetty 11 - 处理文件上传和文件上传进度

问题描述

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


@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()上传所有文件之前,这样做一直卡住。
我目前正在使用码头版本11.0.6

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

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

标签: javafile-uploadjettyjava-11embedded-jetty

解决方案


在您的示例代码中,您正朝着正确的方向前进。

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

有两点需要注意。

仅用作内容类型,空间中的multipart/form-data其他任何内容都multipart/*不受. (例如:)HttpServletRequest.getParts()MultipartConfigElementmultipart/byteranges

接下来,正确配置MultipartConfigElement.

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

至于上传进度,是的,你是对的。最好的地方是在客户端。

如何在 servlet 3.1 中监控上传文件的进度


推荐阅读