Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/384.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用Jersey上载文件时设置文件大小限制_Java_Rest_File Upload_Jersey_Multipartform Data - Fatal编程技术网

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

Java 使用Jersey上载文件时设置文件大小限制,java,rest,file-upload,jersey,multipartform-data,Java,Rest,File Upload,Jersey,Multipartform Data,我目前正在使用jersey rest实现上传文件的功能。我想设置允许的最大文件大小,这对我来说似乎是一个非常常见的要求 我的第一种方法是使用Jersey FormDataContentDisposition,它应该包含我可能需要的关于该文件的所有信息。但是除了文件名之外的所有信息似乎都丢失了,包括文件大小 这是我的休息方法: @POST @Path("uploadFile/") @Consumes("multipart/form-data") @Produces("text/html") pub

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

我的第一种方法是使用Jersey 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>

文件上传
选择文件


现在来回答我的问题;您将如何使用jersey强制执行文件大小限制?必须有一些简单的方法,不必将整个文件读入内存(ByteArray),然后获得实际大小,对吗

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


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

如果使用tomcat,可以设置 为您的机器提供合理的价值

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>

参考

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

public Response uploadFile(@Context final HttpServletRequest request, @FormDataParam("uploadFile") InputStream uploadedInputStream,
      @FormDataParam("uploadFile") FormDataContentDisposition fileDetail, @FormDataParam("uploadFile") FormDataBodyPart body) {
关键部分是上下文最终HttpServletRequest请求。然后在方法体中,您可以获得inputstream的长度,并相应地对其作出反应:

int contentLength = request.getContentLength();

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

您可以自定义
类LimitedSizeInputStream扩展InputStream

使用
@Override
读取方法检查特定的大小限制,如所述。使用
newlimitedsizeInputStream(fileStream,FILE\u SIZE\u LIMIT)
包装您的
InputStream
,当达到读取限制时,您会遇到异常。

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

@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
}

只是想澄清一下,除了不能限制文件大小外,它就像一个符咒。目前对于jersey 2,下面的帖子解决了这个问题谢谢Martin!你当然是对的,我不应该指望客户给我正确的文件大小。我们实现了它,因此如果客户机声明的文件大小>MAX_size,那么我们“快速失败”,否则我们将向上读取流,直到达到MAX_size。我们没有找到在客户端验证文件大小的简单方法,因此必须这样做。再次感谢您的投入!为了防止您的API接收不需要的HTTP调用,您可以创建一个CORS筛选器。内容长度可以是伪造的。下面我要说的是,最大文件大小仅适用于一个文件,最大请求大小适用于整个请求(因此可能有多个文件和多部分).MultipartConfig不被JAX-RS/Jersey使用,因为它用于servlet,而不是JAX-RS资源。Jersey中的MultipartConfig没有等效项。详情请参阅。没有快速失败的解决方案。不能依赖内容长度标题。我们必须检查文件的大小,并在超过预设阈值时拒绝它。为什么这么可怕?想象一个巨大的文件被上传。Jersey必须首先将整个文件保存在磁盘上;如果服务器的磁盘空间有限,这不仅耗时而且不安全。在这种情况下,假设您希望将文件大小限制在
1gb以上,那么
一旦我们上载整个文件,您的验证就会出现。因此,这是非常缓慢的,是不可接受的。你想过这个案子吗?
@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
}