Установка ограничений на размер файла при загрузке файлов с Джерси - PullRequest
11 голосов
/ 11 ноября 2011

В настоящее время я реализую функциональность для загрузки файлов с использованием отдыха из джерси. Я хотел бы установить максимально допустимый размер файла, который мне кажется довольно распространенным требованием.

Мой первый подход состоял в том, чтобы использовать 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 ]

6 голосов
/ 27 марта 2014

Если вы используете tomcat, вы можете установить порог размера, при котором файл будет записан на диск до разумного значения для вашей машины.

например. если сервлет находится в 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 в tomcat?

5 голосов
/ 12 ноября 2011

Если клиент не отправляет размер файла, вернитесь к чтению файла из потока.Как только вы достигнете предела размера, прекратите чтение и откажитесь от файла.В любом случае вам следует это сделать, поскольку вы не можете доверять клиенту (любой может создать приложение, которое отправляет http-запросы к вашей службе, и эти запросы могут содержать неверные данные, которые вы ожидаете, - так что примите это во внимание).

Кроме того, можно также добавить некоторую проверку в веб-форму, чтобы быстро потерпеть неудачу, но я не эксперт по JavaScript, поэтому не уверен, что / как это можно сделать.

2 голосов
/ 21 апреля 2016

Вы можете проверить длину в байтах тела запроса и сделать его доступным для потока ввода с помощью следующего кода:

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
}
1 голос
/ 23 марта 2017

Размер запроса можно узнать, прочитав заголовок.В вашем примере:

@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
}
0 голосов
/ 04 ноября 2016

Вы можете иметь свой пользовательский class LimitedSizeInputStream extends InputStream с @Override методами чтения, которые проверяют определенный лимит размера, как указано в https://stackoverflow.com/a/30072143/5962766. Оберните ваш InputStream с помощью new LimitedSizeInputStream(fileStream, FILE_SIZE_LIMIT), и вы получите исключение при достижении лимита чтения.

...