Фильтр для ограничения размера файла при загрузке в Джерси - PullRequest
0 голосов
/ 15 ноября 2011

У меня есть HTML-форма, которая будет загружать файл (среди других полей формы) на мой сервер. Там я использую Java и Jersey и создал фильтр, который будет выдавать исключение, если файл слишком большой (> 10 МБ). Но я не могу заставить браузер остановить загрузку файла, как только я сгенерирую исключение. Я вижу, что чтение из InputStream прекращается после 10 МБ на стороне сервера, но браузер по-прежнему будет загружать файл до его завершения. Только тогда будет показана ошибка.

Есть ли что-то в работе HTTP и браузеров, которая мешает этому работать?

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

Это фильтр Джерси, который я использую. Похоже, что это работает правильно на стороне сервера, поэтому проблема, кажется, с браузером.

import java.io.IOException;

import org.apache.commons.fileupload.util.LimitedInputStream;
import org.springframework.stereotype.Component;

import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerRequestFilter;
import com.sun.jersey.spi.container.ContainerResponseFilter;
import com.sun.jersey.spi.container.ResourceFilter;

@Component
public class SizeLimitFilter implements ResourceFilter, ContainerRequestFilter {

    @Override
    public ContainerRequest filter(final ContainerRequest request) {
        LimitedInputStream limitedInputStream = new LimitedInputStream(request.getEntityInputStream(), 1024 * 1024 * 10) {
            @Override
            protected void raiseError(final long pSizeMax, final long pCount) throws IOException {
                // Throw error here :)
            }
        };
        request.setEntityInputStream(limitedInputStream);
        return request;
    }

    @Override
    public ContainerRequestFilter getRequestFilter() {
        return this;
    }

    @Override
    public ContainerResponseFilter getResponseFilter() {
        return null;
    }
}

(и да, я знаю, что существуют более привлекательные и современные решения для загрузки файлов (функции Javascript), но мне нужно использовать подход, который работает в IE7: /)

Edit:

Чтобы уточнить: все работает, единственная проблема заключается в том, что я не могу заставить браузер показать ошибку до того, как весь файл будет загружен. Следовательно, если я попытаюсь загрузить файл размером 200 МБ, ошибка не будет отображаться до загрузки всего файла, даже если мой код выдает ошибку сразу после 10 МБ ...

1 Ответ

2 голосов
/ 22 февраля 2012

Это связано с тем, что браузер не ищет ответ сервера, пока ПОСЛЕ того, как он отправит полный запрос.

Вот два способа остановить загрузку больших файлов до того, как они поступят на ваш сервер:

1) Сценарии на стороне клиента.Апплет (загрузка файла Java) или плагин браузера (загрузка файла Flash, ActiveX или любой другой) может проверить размер файла и сравнить его с тем, что вы объявляете ограничением (вы можете использовать запрос OPTIONS для этого илипросто включите максимальный размер, допустимый в вашей форме, в качестве скрытого или нестандартного атрибута для элемента ввода файла.)браузер.Настройте форму на странице так, чтобы она загружалась в службу данных, и в случае успеха вызовите написанную вами функцию javascript, которая уведомит ваш сервер о доступной загрузке файла (с подробной информацией об экземпляре).Затем ваш сервер отправляет запрос в службу данных, чтобы выяснить размер файла ... если он достаточно мал, вы извлекаете его со стороны сервера.Если он слишком велик, вы просто отправляете запрос на удаление в службу данных, а затем отправляете свой ответ в браузер (ваша функция javascript), что файл слишком велик, и им нужно сделать это снова.Ваша функция JavaScript затем воздействует на дисплей, чтобы уведомить пользователя.

...