java - 在后端使用 Jersey 上传大文件

标签 java jersey jetty

我运行一个简单的后端应用程序,它允许上传文件。我使用 Jersey 并在 Jetty 中运行它。我的代码如下所示:

@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFile(@Context UriInfo uriInfo, FormDataMultiPart multipart, @Context  HttpServletRequest httpRequest) {
    FormDataBodyPart fileId = multipart.getField("fileId");
    FormDataBodyPart fileSize = multipart.getField("fileSize");
    FormDataBodyPart file = multipart.getField("file");

    ContentDisposition cd = file.getContentDisposition();
    String fileName = cd.getFileName();
    long size = Long.valueOf(fileSize.getValue());
    ...

Upload 工作得很好,但我发现该方法是在整个流上传到后端时调用的。因此,举例来说,如果我发送大文件(要上传 3Gigs),我的 POST 请求会立即出现在后端,但只有当整个 3Gigs 通过网络上传时才会调用上述方法。

我想在该方法中进行一些检查,并且在某些情况下不上传文件,因此不需要将整个内容传递到后端,然后将错误消息发送回来。

如何避免将整个文件内容上传到后端,但在开始从数据流读取之前调用该方法?

最佳答案

最终我通过客户端应该上传如此大文件的 2 个连续 POST 来解决这个问题:

@POST
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response newUpload(@Context UriInfo uriInfo, FormDataMultiPart multipart,
        @Context HttpServletRequest httpRequest) {
    FormDataBodyPart fileSize = multipart.getField("fileSize");
    long size = Long.valueOf(fileSize.getValue());
    if (!checkSizeLimits(size)) {
        return Response.status(Status.BAD_REQUEST).build();
    }
    // here comes some code which generates an unique id and its URI for the data
    ...
    return Response.status(Status.CREATED).entity(new FileUploadInfo(uri.toString())).build();
}

@POST
@Path("/{fileId}")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadFile(@Context UriInfo uriInfo, FormDataMultiPart multipart,
        @Context HttpServletRequest httpRequest, @PathParam("fileId") String fileId) {
    FormDataBodyPart fileSize = multipart.getField("fileSize");
    FormDataBodyPart file = multipart.getField("file");
    //...
    return Response.status(Status.CREATED).entity(new FileUploadInfo(uri.toString())).build();
 }

它看起来很难看,但比在数据流完全加载后进行文件大小检查要好。因此,客户端应该首先对 newUpload() 方法进行 POST 调用,提供文件大小。如果大小合适,响应将包含第二个 POST 传输文件数据的 URI。第二种方法可以再次进行文件大小检查(未提供),以确保初始 POST 具有相同的文件大小字段。

关于java - 在后端使用 Jersey 上传大文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24715970/

相关文章:

java - 禁用 JAVA 中的所有键和组合键

java - 安卓 : Use one service class for multiple notifications?

java - 读取 excel 文件 --> 使用 java 的 xlsx 格式

java - 从 servlet 开始嵌入 Neo4j

java - 带有嵌入式 Jetty + PostReplaceFilter 的 Jersey

java - JSON 响应中的 @type

multithreading - 为什么play(netty3)上传使用单线程?

eclipse - 在 eclipse 上导入并运行 WAR

java - Jersey Rest 服务何时实际启动/关闭?

java - 在 Tomcat7 上部署 webapp