使用Jersey上载文件时设置文件大小限制

时间:2011-11-11 08:32:21

标签: java rest file-upload jersey multipartform-data

我目前正在使用泽西休息实现上传文件的功能。我想设置一个允许的最大文件大小对我来说似乎是一个非常常见的要求。

我的第一种方法是使用Jerseys FormDataContentDisposition,它应该包含我可能需要的有关该文件的所有信息。但是除了文件名之外的所有信息似乎都缺失了,包括文件大小。

这是我的休息方法:

@POST
@Path("uploadFile/")
@Consumes("multipart/form-data")
@Produces("text/html")
public String handleDocumentUpload(
    @FormDataParam("file") InputStream uploadedInputStream,
    @FormDataParam("file") FormDataContentDisposition fileDetail)
{
    if(fileDetail.getSize() > MAX_FILE_SIZE)
    {
        throw new IllegalArgumentException(
                "File is to big! Max size is " + MAX_FILE_SIZE);
    }
    // ...more file handling logic
}

由于返回的大小始终为“-1”,因此无法正常工作!

我使用非常简单的html表单进行文件上传:

<html>
  <head>
    <title>File upload</title>
  </head>
  <body>
 <p>Choose file</p>
 <form enctype="multipart/form-data" method="POST" action="uploadFile">
   <input type="file" name="file" size="50">
   <input type="submit" value="Upload">
 </form>
  </body>
</html>

现在问我的问题;你将如何使用泽西强制执行文件大小限制?必须有一些简单的方法,而不必诉诸于将整个文件读入内存(ByteArray),然后获得实际大小,对吧?

5 个答案:

答案 0 :(得分:6)

如果你正在使用tomcat,你可以设置 the size threshold at which the file will be written to the disk为您的机器提供合理的价值。

e.g。如果servlet在web.xml中

<servlet>
  <servlet-name>Upload Servlet</servlet-name>
  <servlet-class>YourServletName</servlet-class>

  <multipart-config>
   <!-- 10MB of files -->
   <max-file-size>10485760</max-file-size>
   <!-- 10KB of form data -->
   <max-request-size>10240</max-request-size>
   <!-- Buffer to disk over 512KB -->
   <file-size-threshold>524288</file-size-threshold>
 </multipart-config>

</servlet>

或使用注释:

@MultipartConfig(
    maxFileSize=10485760,     // 10Mb max
    fileSizeThreshold=524288, //512 Kb before buffering to disk
    maxRequestSize=10240      // 10Kb of meta data
    location=/tmp             // with permission to write, default uses tomcat tmp
)

参考HttpRequest maximum allowable size in tomcat?

答案 1 :(得分:5)

如果客户端没有发送文件大小,则回退到从流中读取文件。达到大小限制后,停止阅读并拒绝该文件。无论如何,您应该这样做,因为您无法信任客户端(任何人都可以创建一个向您的服务发送http请求的应用程序,而这些请求可能没有您期望的正确数据 - 因此必须考虑到这一点。)

此外,可以在Web表单中添加一些验证以及快速失败,但我不是JavaScript专家,因此不确定是否/如何完成。

答案 2 :(得分:2)

您可以使用以下代码检查请求正文的长度(以字节为单位),并由输入流提供:

public Response uploadFile(@Context final HttpServletRequest request, @FormDataParam("uploadFile") InputStream uploadedInputStream,
      @FormDataParam("uploadFile") FormDataContentDisposition fileDetail, @FormDataParam("uploadFile") FormDataBodyPart body) {

关键部分是@Context final HttpServletRequest request。然后在方法体中,您可以获得输入流的长度并对其做出相应的反应:

int contentLength = request.getContentLength();

if (contentLength == -1 || contentLength > MAX_REQUEST_SIZE) {
  // deal with it
}

答案 3 :(得分:1)

您可以通过阅读标题来获取请求大小。 在您的示例中:

@POST
@Path("uploadFile/")
@Consumes("multipart/form-data")
@Produces("text/html")
public String handleDocumentUpload(
    @HeaderParam("content-length") long contentLength,
    @FormDataParam("file") InputStream uploadedInputStream,
    @FormDataParam("file") FormDataContentDisposition fileDetail) {

    if(contentLength > MAX_FILE_SIZE) {
      throw new IllegalArgumentException(
            "File is to big! Max size is " + MAX_FILE_SIZE);
    }
  // ...more file handling logic
}

答案 4 :(得分:0)

您可以拥有自定义class LimitedSizeInputStream extends InputStream 使用@Override读取方法检查https://stackoverflow.com/a/30072143/5962766中提到的特定大小限制。使用InputStream包裹您的new LimitedSizeInputStream(fileStream, FILE_SIZE_LIMIT),当达到读取限制时,您将获得例外。