Веб-приложение на Java: добавление заголовка размещения содержимого для принудительного поведения браузеров "сохранять как" - PullRequest
7 голосов
/ 09 марта 2010

Несмотря на то, что он не является частью веб-приложений HTTP 1.1 / RFC2616, которые желают заставить загружать (а не отображать) ресурс в браузере, можно использовать заголовок Content-Disposition, например:

Content-Disposition: attachment; filename=FILENAME

Даже несмотря на то, что он определен только в RFC2183, а не часть HTTP 1.1, он работает в большинстве веб-браузеров, как и хотел.

Так что со стороны клиента все достаточно хорошо.

Однако на стороне сервера, в моем случае, у меня есть веб-приложение на Java, и я не знаю, как мне установить этот заголовок, особенно в следующем случае ...

У меня будет файл (скажем, " bigfile "), размещенный на экземпляре Amazon S3 (моя корзина S3 должна быть доступна по частичному адресу, например: files.mycompany.com / ), поэтому пользователи смогут получить доступ к этому файлу по адресу files.mycompany.com / bigfile .

Есть ли способ создания сервлета (или .jsp ), чтобы заголовок Content-Disposition всегда добавлялся, когда пользователь хочет загрузить этот файл?

Как будет выглядеть код и каковы ошибки, если таковые имеются?

Ответы [ 4 ]

4 голосов
/ 26 октября 2011

У меня все получилось, как указал Пойнти. Вместо прямой ссылки на ресурс - в моем случае это pdfs - теперь нужно ссылаться на JSP с именем download.jsp, который принимает и анализирует параметры GET, а затем выдает файл pdf для загрузки.

Скачать здесь

Вот код jsp, который я использовал. Работает в IE8, Chrome и Firefox:

<%@page session="false"
            contentType="text/html; charset=utf-8"
            import="java.io.IOException,
                    java.io.InputStream,
        java.io.OutputStream,
        javax.servlet.ServletContext,
        javax.servlet.http.HttpServlet,
        javax.servlet.http.HttpServletRequest,
        javax.servlet.http.HttpServletResponse,
        java.io.File,
        java.io.FileInputStream"
 %>
<%  
//Set the headers.
response.setContentType("application/x-download"); 
response.setHeader("Content-Disposition", "attachment; filename=downloaded.pdf");

[pull the file path from the request parameters]   

File file = new File("[pdf path pulled from the requests parameters]");
FileInputStream fileIn = new FileInputStream(file);
ServletOutputStream outstream = response.getOutputStream();

byte[] outputByte = new byte[40096];

while(fileIn.read(outputByte, 0, 40096) != -1)
{
    outstream.write(outputByte, 0, 40096);
}
fileIn.close();
outstream.flush();
outstream.close();

%>
2 голосов
/ 09 марта 2010

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

Класс HttpServletResponse имеет API-интерфейсы, которые позволят вам установить все нужные заголовки. Вы должны убедиться, что вы установили заголовки до , и вы начинаете выгружать содержимое файла, потому что заголовки буквально должны стоять на первом месте в потоке, отправляемом в браузер.

Это не сильно отличается от ситуации, когда у вас может быть сервлет, который генерирует загрузку на лету.

edit Я оставлю этот материал здесь для потомков, но отмечу, что есть (или может быть) какой-то способ передать некоторые заголовки HTTP на S3, когда вы сохраните файл, так что Amazon будет выплевывать их обратно, когда файл будет выдан. Я не совсем уверен, как вы это сделаете, и я не уверен, что «Content-disposition» - это заголовок, который вы можете настроить таким образом, но я буду продолжать искать.

0 голосов
/ 09 января 2016

Я только что нашел это через Google.

И у меня была схожая проблема, но я все еще хочу использовать сервлет (при создании контента).


Однако следующая строка - это все, что вам нужно в сервлете.

response.setHeader("Content-Disposition", "attachment; filename=downloadedData.json");
0 голосов
/ 09 марта 2010

Поместите файл .htaccess в корневую папку со следующей строкой:

Header set Content-Disposition attachment
...