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,默认是全部保存在内存中)
就上传进度而言,是的,你是对的。
最好的地方是在客户端。
在将 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
如何实现进度监听和正确的文件上传?
编辑:经过一些额外的研究,我发现一些文章
在您的示例代码中,您的方向是正确的。
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,默认是全部保存在内存中)
就上传进度而言,是的,你是对的。 最好的地方是在客户端。