Главная Библиотека Шаблоны и примерыЗадача Domino HTTP. Агент Скачать файлы одним архивом и обработка отдаваемых пользователю файлов. Часть первая
Николай Норкин
г. Киров
notesnet@notesnet.ru
Когда у тебя в руках молоток, все шурупы превращаются в гвозди
Народная мудрость
Буквально недавно попалась задачка, решение которой вроде бы известно, и все компоненты решения автор уже изложил на страницах этого проекта. А вон оно что получилось
Итак, есть документ Notes в web-интерфейсе. Документ содержит вложенные файлы. Нужно на страницу добавить ссылку на скачивание всех файлов одним архивом
Казалось бы, всё буквально пройдено в течение последних полутора месяцев. На страницах проекта был описан и доступ к файлам документа (материал Java в Domino. Вывод в поток присоединённых файлов) и работа с zip-архивом (Пример обработки файловых потоков. Работа с бланком Microsoft Excel)
То есть, данная статья, в действительности, должна была бы называться Ещё один небольшой пример обработки файловых потоков. Однако, путь к решению получился более тернистым
Быстренько создадим в базе web-агента, получающего unid документа из строки get-запроса, затем ищущего документ по этому unid'у, выводящего в поток вложенные файлы и генерирующего zip-архив. Да, не забыть поставить галочку, что агент запускается от имени web-пользователя и имеет доступ к документу под его правами
public void NotesMain() {
this.stream = this.getAgentOutputStream();
try {
this.session = this.getSession();
lotus.domino.AgentContext agentContext = this.session.getAgentContext();
this.database = agentContext.getCurrentDatabase();
lotus.domino.Document context = agentContext.getDocumentContext();
String query_string = context.getItemValueString("query_string_decoded").substring(10);
java.util.Map parameters = new java.util.HashMap();
String[] params = query_string.split("&");
for ( int i = 0; i <params.length; i++) {
String[] parameter = params[i].split("=");
parameters.put(parameter[0], parameter[1]);
}
String unid = (String) parameters.get("id");
lotus.domino.Document document = this.database.getDocumentByUNID(unid);
java.io.ByteArrayOutputStream zip = this.getPack(document);
...
Засада первая. Пакет java.util.zip, который был использован при разборе содержимого архива Excel, не работает с кодировками, поддерживающими русские (как, видимо, и другие национальные) символы в заголовках файлов. Поэтому, приходится использовать альтернативный пакет работы с zip-архивом apache-ant-1.7.0.jar
protected java.io.ByteArrayOutputStream getPack(lotus.domino.Document document) {
try {
java.io.ByteArrayOutputStream stream = new java.io.ByteArrayOutputStream();
org.apache.tools.zip.ZipOutputStream zip = new org.apache.tools.zip.ZipOutputStream(stream);
zip.setEncoding("CP866");
// zip = new java.util.zip.ZipOutputStream(stream, new java.nio.charset.Charset());
zip.setLevel(java.util.zip.ZipOutputStream.DEFLATED);
ru.medkirov.mail.Attachment attachments = new ru.medkirov.mail.Attachment(this.session,
this.database, document);
java.util.Vector vector = this.session.evaluate("@AttachmentNames", document);
for ( int i = 0; i < vector.size(); i++) {
String filename = (String) vector.elementAt(i);
ru.medkirov.mail.AttachedFile attach = attachments.getFile(filename);
String base64 = attach.getResource();
byte[] decodeBase64 = com.ibm.xml.enc.dom.Base64.decode(base64.getBytes());
org.apache.tools.zip.ZipEntry entry = new org.apache.tools.zip.ZipEntry(filename);
// entry.setComment(entry.getComment());
// entry.setExtra(entry.getExtra());
// entry.setMethod(entry.getMethod());
zip.putNextEntry(entry);
copy(new java.io.ByteArrayInputStream(decodeBase64), zip);
zip.closeEntry();
}
zip.flush();
zip.close();
return stream;
}
catch (Exception e) {
e.printStackTrace();
}
return null;
}
protected static void copy(java.io.InputStream input, java.io.OutputStream output) throws java.io.IOException {
int bytesRead;
while ((bytesRead = input.read(BUFFER))!= -1) {
output.write(BUFFER, 0, bytesRead);
}
}
Ну, вот и всё. Архив получен, осталось его только отдать пользователю
И вот тут у нас на пути основная засада. Web-engine Domino не пропускает бинарные данные, обрезая их по пути к пользователю. Да, примерно то же самое, с чем ранее автор столкнулся при загрузке файлов
Как из этой засады удалось выбраться - читайте вторую часть статьи
Ссылки
Задача Domino HTTP. Агент Скачать файлы одним архивом и обработка отдаваемых пользователю файлов. Часть вторая
Java в Domino. Вывод в поток присоединённых файлов
Пример обработки файловых потоков. Работа с бланком Microsoft Excel
Задача Domino HTTP. Обработка загружаемых файлов сервлетом UploadProcess. Часть первая
Пакет работы с zip-архивом apache-ant-1.7.0.jar
|
Опубликовано — 02/28/2021 |
| |
|
|