Загрузка документа, указанного в URL, в массив байтов

#java #html #jakarta-ee #servlets #file-upload

#java #HTML #джакарта-ee #сервлеты #загрузка файла

Вопрос:

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

Я хочу загрузить результат этой выборки в сервлет Java (через http POST-запрос) и поместить его в массив байтов. Поскольку это низкоуровневое представление, я не уверен, следует ли мне использовать Apache FileUpload.

Еще один момент, который меня смутил, заключается в том, что FileItem s в FileUpload предоставляют только OutputStream то, где я ожидал InputStream прочитать файл.

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

Как мне создать эту функциональность? Пожалуйста, обратите внимание, что я новичок в этой области разработки Java (хотя мои общие (т. Е. SE) Навыки Java очень хороши).

Комментарии:

1. Чтобы сделать то, что вы хотите, пользователю нужно будет загрузить двоичный файл, сохранить его на своем диске, а затем использовать файловый ввод, чтобы выбрать местоположение файла на своем диске и загрузить файл. AFAIK, нет способа автоматически передавать содержимое URL-адреса на сервер. Вы могли бы просто опубликовать URL-адрес, но тогда серверу пришлось бы обращаться к самому URL-адресу, чтобы загрузить изображение.

2. @JBNizet На самом деле мой вопрос касался написания сервлета. Извлечение внешнего интерфейса — еще один (интересный) момент, о котором я могу задать вопрос. Я обновил свой вопрос, чтобы уточнить, что речь идет о сервлете, а не о интерфейсе.

Ответ №1:

Просто продолжайте использовать FileUpload, не изобретайте его самостоятельно. Это будет пустой тратой времени.

Я не уверен, почему вы думаете, что FileItem это обеспечивает только OutputStream , есть также getInputStream() метод. Просто запишите его в ByteArrayOutputStream .

 InputStream input = fileItem.getInputStream();
ByteArrayOutputStream output = new ByteArrayOutputStream();
IOUtils.copy(input, output);
byte[] bytes = output.toByteArray();
// ...
  

Вам нужно только иметь в виду, что это может привести к увеличению использования памяти вашего сервера, если одновременно загружается много пользователей. файлы. Каждый байт массива байтов потребляет один байт памяти JVM. Итак, представьте, что у вас есть 100 одновременных пользователей, которые загружают каждый файл размером 10 МБ, тогда на это тратится 1 ГБ памяти сервера.

Комментарии:

1. Вы абсолютно правы getInputStream ; я только что реализовал это таким образом. Видимо, я был неаккуратен. Теперь мой вопрос кажется глупым. Спасибо за ваш ответ.

Ответ №2:

Если я вас правильно понял, вы просто пытаетесь получить файл, загруженный через HTTP в сервлет? В сети есть множество примеров того, как это сделать, например, http://www.servlets.com/jservlet2/examples/ch04/UploadTest.java

Я просто что-то упустил в вашем вопросе?

Комментарии:

1. Суть в том, чтобы поместить его в массив байтов. Вероятно, неразумно создавать что-то подобное с нуля (если я хочу реализовать RFC 1867), поскольку доступны хорошие реализации. Моя проблема в том, что я не понимаю, как получить массив байтов с помощью (например) Apache FileUpload. Как уже было сказано, поскольку у меня нет опыта в разработке EE, возможно, я просто что-то упускаю из виду или неправильно понимаю.

2. В примере, на который я ссылался, вы получаете файловый объект, подобный этому File f = multi.getFile(name); , оттуда вы можете получить входной поток и прочитать его в массив байтов.