JSP download - приложение / октет-стрим - PullRequest
0 голосов
/ 20 декабря 2009

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

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

Вот мой код:

<%@page language="java"%>
<%@page import="sun.misc.Request"%>
<%@page import="listing.ClientTCPStockage"%>
<%@page import="java.net.InetAddress"%>

<%
out.clearBuffer();

String nomFichier = request.getParameter("fichier");
String adresseStockage = request.getParameter("adresseStockage");

ClientTCPStockage clientStockage = new ClientTCPStockage(InetAddress.getByName(adresseStockage), 2004);
byte donneeFichier[] = clientStockage.getDonneesFichier(nomFichier);

response.setHeader("Content-Disposition", "attachment;filename=\"" + nomFichier + "\"");
response.setHeader("Content-Type", "application/octet-stream;");
response.setHeader("Accept-Ranges", "bytes");
response.setHeader("Content-Length", String.valueOf(donneeFichier.length));

for(int i = 0; i < donneeFichier.length; i++){
    out.write(donneeFichier[i]);
}
%>

Это прекрасно работает для текстовых файлов, таких как .csv или обычный .txt. но он не работает для других типов, таких как .mp3 или .jpeg .. файлы в конечном итоге повреждены.

Я думаю, что есть проблема с моей кодировкой, но я не могу найти где ..

Вот ответ HTTP-заголовка:

HTTP/1.x 200 OK
Server: Apache-Coyote/1.1
Content-Disposition: attachment;filename="test.mp3"
Accept-Ranges: bytes
Content-Type: application/octet-stream;
Content-Length: 5387668
Date: Sun, 20 Dec 2009 18:52:18 GMT

Спасибо.

Ответы [ 2 ]

4 голосов
/ 20 декабря 2009

Если вы вынуждены использовать JSP (а не сервлет), вы можете взглянуть на это с практическими рекомендациями

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

Также обратите внимание на настройки обрезки пробелов.

4 голосов
/ 20 декабря 2009

JSP - это технология просмотра. Все, что находится за пределами скриптлетов <% %>, будет напечатано для ответа, включая пробельные символы, такие как символы новой строки. Это наверняка повредит бинарные файлы.

Вы можете обрезать пробелы в файле JSP, но скриптлеты не рекомендуется с десятилетия и в настоящее время считается плохой практикой . Необработанный код Java принадлежит классам Java, а не файлам JSP. Реальное решение - использовать Servlet для этого.

Создайте класс, который extends HttpServlet, реализуйте метод doGet(), переместите код Java из файла JSP в этот метод, сопоставьте этот сервлет с определенным url-pattern, и ваша проблема должна исчезнуть. Вы можете найти здесь a basic пример такого сервлета.

Помимо этой проблемы, вы храните весь файл в byte[] вместо InputStream. Я не уверен, что на самом деле делает ваш ClientTCPStockage, но я бы посоветовал это исправить. Это потому, что каждый byte из byte[] стоит эффективно один байт памяти JVM. Представьте, что у вас 128 МБ памяти JVM и более 10 пользователей одновременно запускают этот фрагмент кода с файлом размером более 12,8 МБ. Да, OutOfMemoryError.

...