在后端使用Jersey上传大文件

时间:2014-07-12 18:20:48

标签: 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());
    ...

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

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

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

1 个答案:

答案 0 :(得分:0)

最终我使用了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具有相同的文件大小字段。