Java 使用Jersey上载文件时设置文件大小限制
我目前正在使用jersey rest实现上传文件的功能。我想设置允许的最大文件大小,这对我来说似乎是一个非常常见的要求 我的第一种方法是使用Jersey FormDataContentDisposition,它应该包含我可能需要的关于该文件的所有信息。但是除了文件名之外的所有信息似乎都丢失了,包括文件大小 这是我的休息方法: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
@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
}