使用Jersey上载文件时设置文件大小限制
我目前正在使用泽西rest实现上传文件的function。 我想设置一个允许的最大文件大小对我来说似乎是一个非常常见的要求。
我的第一种方法是使用Jerseys FormDataContentDisposition,它应该包含我可能需要的有关该文件的所有信息。 但是除了文件名之外的所有信息似乎都缺失了,包括文件大小。
这是我的rest方法:
@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表单来上传文件:
File upload Choose file
那么现在问我的问题; 你将如何使用泽西强制执行文件大小限制? 必须有一些简单的方法,而不必诉诸于将整个文件读入内存(ByteArray),然后获得实际大小,对吧?
如果客户端未发送文件大小,则回退到从流中读取文件。 达到大小限制后,停止阅读并拒绝该文件。 无论如何,您应该这样做,因为您无法信任客户端(任何人都可以创建一个向您的服务发送http请求的应用程序,并且这些请求可能没有您期望的正确数据 – 因此必须考虑到这一点)。
此外,有可能在Web表单中添加一些validation以及快速失败,但我不是JavaScript专家,所以不确定是否/如何做到这一点。
如果您正在使用tomcat,则可以将文件写入磁盘的大小阈值设置为机器的合理值。
例如,如果servlet在web.xml中
Upload Servlet YourServletName 10485760 10240 524288
或使用注释:
@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 )
在tomcat中参考HttpRequest最大允许大小?
您可以使用以下代码检查请求正文的长度(以字节为单位),并使输入流可用:
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 }
您可以使用自定义class LimitedSizeInputStream extends InputStream
读取方法class LimitedSizeInputStream extends InputStream
,该方法检查特定大小限制,如https://stackoverflow.com/a/30072143/5962766所述 。 使用new LimitedSizeInputStream(fileStream, FILE_SIZE_LIMIT)
包装InputStream
,当达到读取限制时,您将获得exception。
您可以通过阅读标题来获取请求大小。 在你的例子中:
@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 }