Установка ограничений размера файла при загрузке файлов с помощью Jersey
в настоящее время я реализую функциональность для загрузки файлов с помощью jersey rest. Я хотел бы установить максимальный размер файла, который мне кажется довольно распространенные требования.
мой первый подход состоял в использовании 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 ответов
Если клиент не отправляет размер файла, вернитесь к чтению файла из потока. Как только вы нажмете ограничение размера, прекратите чтение и откажитесь от файла. Вы должны сделать это в любом случае, так как вы не можете доверять клиенту (любой может создать приложение, которое отправляет http - запросы на вашу службу, и эти запросы могут не иметь правильных данных, которые вы ожидаете, поэтому должны учитывать это).
кроме того, возможно, можно добавить некоторую проверку в веб-форму, а также быстро потерпеть неудачу, но я не эксперт JavaScript, поэтому не уверен, что/как это можно сделать.
Если вы используете tomcat, вы можете установить пороговый размер, при котором файл будет записан на диск к разумному значению для вашей машины.
например, если сервлет в интернете.в 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 максимально допустимый размер в tomcat?
вы можете проверить длину, в байтах, тела запроса и доступны с помощью входного потока со следующим кодом:
public Response uploadFile(@Context final HttpServletRequest request, @FormDataParam("uploadFile") InputStream uploadedInputStream,
@FormDataParam("uploadFile") FormDataContentDisposition fileDetail, @FormDataParam("uploadFile") FormDataBodyPart body) {
ключевая часть @Context final HttpServletRequest request
. Затем в теле метода, вы можете получить длину InputStream и реагировать на него соответственно:
int contentLength = request.getContentLength();
if (contentLength == -1 || contentLength > MAX_REQUEST_SIZE) {
// deal with it
}
вы можете иметь ваш заказ class LimitedSizeInputStream extends InputStream
с @Override
читать методы, которые будут проверять определенные ограничения на размер, как указано на https://stackoverflow.com/a/30072143/5962766. Оберните ваши InputStream
С new LimitedSizeInputStream(fileStream, FILE_SIZE_LIMIT)
и вы получите исключение, когда предел чтения будет достигнут.
вы можете получить размер запроса, прочитав заголовок. В вашем примере:
@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
}