gpt4 book ai didi

java - 在 CXF jax-rs 中禁用多部分缓存

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:54:47 26 4
gpt4 key购买 nike

posted这个问题到 CXF 列表,没有任何运气。所以我们开始吧。我正在尝试将大文件上传到远程服务器(想想它们是虚拟机磁盘)。所以我有一个接受上传请求的 Restful 服务。上传的处理程序如下所示:

@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Path("/doupload")
public Response receiveStream(MultipartBody multipart) {
List<Attachment> allAttachments = body.getAllAttachments();
Attachment att = null;
for (Attachment b : allAttachments) {
if (UPLOAD_FILE_DESCRIPTOR.equals(b.getContentId())) {
att = b;
}
}
Assert.notNull(att);
DataHandler dh = att.getDataHandler();
if (dh == null) {
throw new WebApplicationException(HTTP_BAD_REQUEST);
}
try {
InputStream is = dh.getInputStream();
byte[] buf = new byte[65536];
int n;
OutputStream os = getOutputStream();
while ((n = is.read(buf)) > 0) {
os.write(buf, 0, n);
}
ResponseBuilder rb = Response.status(HTTP_CREATED);
return rb.build();
} catch (IOException e) {
log.error("Got exception=", e);
throw new WebApplicationException(HTTP_INTERNAL_ERROR);
} catch (NoSuchAlgorithmException e) {
log.error("Got exception=", e);
throw new WebApplicationException(HTTP_INTERNAL_ERROR);
} finally {}

}

此代码的客户端相当简单:

public void sendLargeFile(String filename) {
WebClient wc = WebClient.create(targetUrl);
InputStream is = new FileInputStream(new File(filename));
Response r = wc.post(new Attachment(Constants.UPLOAD_FILE_DESCRIPTOR,
MediaType.APPLICATION_OCTET_STREAM, is));
}

代码在功能方面运行良好。在性能方面,我注意到在我的处理程序(receiveStream() 方法)从流中获取第一个字节之前,整个流实际上被保存到一个临时文件中(使用 CachedOutputStream)。不幸的是,这对我的目的来说是 Not Acceptable 。

  • 我的处理程序只是将传入的字节传递到后端存储系统(虚拟机磁盘存储库),等待整个磁盘写入缓存然后再次读取需要花费大量时间,占用大量时间资源,并降低吞吐量。
  • 写入 block 并再次读取它们会产生成本,因为应用程序在云端运行,并且云提供商会按读/写 block 收费。
  • 由于每个字节都写入本地磁盘,因此我的服务 VM 必须有足够的磁盘空间来容纳所有正在上传的流的总大小(即,如果我有 10 个 100GB 的上传,我必须有 1TB 的磁盘只是为了缓存内容)。这又是一笔额外的钱,因为服务 VM 的大小急剧增长,并且云提供商还对配置的磁盘大小收费。

鉴于所有这些,我正在寻找一种方法来使用 HTTP InputStream(或尽可能接近它)直接从那里读取附件并在之后处理它。我想这个问题转化为以下之一:- 有没有办法告诉 CXF 不做缓存- 或者 - 有没有办法通过 CXF 输出流(我写的一个)来使用,而不是使用 CachedOutputStream

我发现了一个类似的问题here .该决议说使用 CXF 2.2.3 或更高版本,我正在使用 2.4.4(并尝试使用 2.7.0)但没有成功。

谢谢。

最佳答案

我认为这在逻辑上是不可能的(无论是在 CXF 还是其他任何地方)。您正在调用 getAllAttachements(),这意味着服务器应该从 HTTP 输入流中收集有关它们的信息。这意味着整个流必须进入内存 MIME解析。

在您的情况下,您应该直接使用流,并自己进行 MIME 解析:

public Response receiveStream(InputStream input) {

现在您可以完全控制输入并可以将其逐字节消耗到内存中。

关于java - 在 CXF jax-rs 中禁用多部分缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13596857/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com