Войти
 
 
   
 
  
Новости Notes.ру Библиотека Биржа труда Вопрос - ответ Форум Регистрация Поиск О проекте
Разделы
О Notes
Советы
Шаблоны и примеры
Литература
Презентации
 
Всё о задаче AdminP. Proxy-действия в R5 и Domino 6   Приложение к статье об административном процессе
О Notes Читать статью
 
Всё о задаче AdminP. Часть первая   Перевод классической статьи 2003-его года о задаче административного процесса (AdminP). Очень полезна для понимания работы механизма этой задачи. В первой части статьи описаны компоненты задачи AdminP, как они работают, и как их использование помогает сделать работу администратора Domino проще. Задача AdminP (сакращённо от Administration Process, Административный процесс) работает с базой административных запросов (Administration Requests, admin4.nsf)
О Notes Читать статью
 
Задача Domino HTTP. Агент Скачать файлы одним архивом и обработка отдаваемых пользователю файлов. Часть вторая   Завершаем описание решения задачи по генерации файлов web-агентом и выдаче файлов, задействуя сервлет, также представляемый в настоящей статье
Шаблоны и примеры Читать статью
 


Шаблоны и примеры

Главная   Библиотека   Шаблоны и примеры

Задача Domino HTTP. Агент Скачать файлы одним архивом и обработка отдаваемых пользователю файлов. Часть вторая

Краткое содержание предыдущей части

На пути к решению "дела на одну трубку" встают всё новые и новые проблемы. Герой их преодолевает с завидной лёгкостью, пока не приходит в засаду, выбраться из которой помогут лишь отчаянные средства. Иль никакие

Николай Норкин

г. Киров

notesnet@notesnet.ru

На нашем пути к решению опять, как и в прошлый раз (Обработка загружаемых файлов сервлетом UploadProcess. Часть первая), встала web-engine Domino. В прошлом решении препятствие удалось обойти, перенеся обработку на сервлет. Аналогично попробуем обмануть преграду и в данном решении

Агент на этот раз остаётся частью решения, так как его посредством будет контролироваться доступ к документу. Но выходной поток будет не бинарным, а в кодировке base64, благодаря чему он благополучно преодолеет web-engine Domino. Промежуточным звеном между пользователем и web-engine станет сервлет DownloadProcess, в чьи функции будут входить следующие задачи:

  • приём запроса от браузера и перенаправление его на Web-engine Domino
  • получение ответа от engine Domino
  • перекодировка потока из base64 в бинарный формат
  • и, наконец, антивирусная проверка

К сожалению, на призыв автора поделиться success story использования антивирусного решения, добровольцев не нашлось, эту тему придётся оставить до более светлого будущего

Обо всём же остальном речь пойдёт прямо сейчас

Вывод результата работы агента

Описание агента в прошлой части прервалось на строке получения zip-архива

    this.stream = this.getAgentOutputStream();

java.io.ByteArrayOutputStream zip = this.getPack(document);

продолжим с этого места

String base64 = javax.xml.bind.DatatypeConverter.printBase64Binary(zip.toByteArray());

this.stream.write("Content-Type:application/zip\n".getBytes());

this.stream.write("Content-Disposition: attachment; filename*=utf-8''%D0%9E%D0%B4%D0%BD%D0%B8%D0%BC%20%D1%84%D0%B0%D0%B9%D0%BB%D0%BE%D0%BC.zip\n".getBytes()); // Одним файлом.zip

this.stream.write("Content-Transfer-Encoding: base64\n".getBytes());

this.stream.write(("Content-Length: ".concat(Long.toString(base64.length())).concat("\n")).getBytes());

this.stream.write(base64.getBytes());

zip.flush();

zip.close();

} catch(Exception e) {

e.printStackTrace();

}

finally {  

try {this.stream.flush();} catch(Exception e) {}

try {this.stream.close();} catch(Exception e) {}

}

}

Полностью код агента в архиве zip-download.src.zip

Настройка серверных правил

Для простоты обращения создадим документы web-правил для сайта

Для агента
Basics
Description:
Type of rule:Substitution
Incoming URL pattern:/edu/*.zip
Replacement pattern:/www/education.nsf/zip-download?openagent&id=*
и для сервлета
Basics
Description:
Type of rule:Substitution
Incoming URL pattern:/download/*
Replacement pattern:/servlets/downloadProcess?url=http://mysite.com/*
Теперь для обращения к сервлету будет использован URL /download/edu/идентификатор_документа.zip. Сервлет будет транслировать его агенту на адрес /edu/идентификатор_документа.zip вашего сайта

И, на всякий случай, во избежание шуток с рекурсией
Basics
Description:
Type of rule:Substitution
Incoming URL pattern:/download/download/*
Replacement pattern:/0.gif
Сервлет DownloadProcess

Итак, сервлет принимает пользовательский запрос и перенаправляет его на адрес, заданный параметром URL get-запроса

protected void doGet(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException {

java.io.InputStream stream = this.getResponse(request, response);

}

protected void doPost(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) throws javax.servlet.ServletException, java.io.IOException {

doGet(request, response);

}

protected java.io.InputStream getResponse(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response) {

java.net.HttpURLConnection connection = null;

java.net.URL url = null;

try {

java.io.OutputStream reqStream = null;

java.io.InputStream resStream = null;

String host = request.getHeader("HOST");

String parameter = request.getQueryString();

String address = this.getAddress(parameter);

url = new java.net.URL(address);

connection = (java.net.HttpURLConnection) url.openConnection();

java.util.Enumeration _unum = request.getHeaderNames();

while (_unum.hasMoreElements()) {

String headerName = (String)_unum.nextElement();

String headerValue = request.getHeader(headerName);

connection.setRequestProperty(headerName, headerValue);

}

connection.setDoOutput(true);

connection.setDoInput(true);

connection.setUseCaches (false);

connection.setRequestMethod("GET");

}

catch (Exception e) {

response.setStatus(500);

return null;

}

.....

После того, как пришёл ответ от сервера, сервлет прозрачно возвращает этот ответ пользователю (пока мы ещё не добрались до антивирусной проверки), или, если ответ пришёл в кодировке base64, преобразует ответ в бинарный вид перед тем, как опять же, отдать его пользователю

            int responseCode = connection.getResponseCode();

            response.setStatus(responseCode); // передача статуса ответа

            String header = null; // чтение заголовков с передачей их web-пользователю

            try { header = connection.getHeaderField("Content-Type");} catch (Exception e) {}

            if (header != null)

            response.setContentType(header);

            header = null;

            try { header = connection.getHeaderField("Content-Disposition");} catch (Exception e) {}

            if (header != null)

            try { response.setHeader("Content-Disposition", header);} catch (Exception e) {}

            header = null;

            try { header = connection.getHeaderField("Content-Transfer-Encoding");} catch (Exception e) {}

// а этот заголовок установлен агентом и требует перекодировки в binary

            if (header != null && header.equalsIgnoreCase("base64")) {

            try { response.setHeader("Content-Transfer-Encoding", "binary");} catch (Exception e) {}

            byte[] bytes = this.streamToByteArray(connection.getInputStream());

            byte[] decoded = org.apache.commons.codec.binary.Base64.decodeBase64(new String(bytes));

            try { response.setContentLength(decoded.length);} catch (Exception e) {}

            java.io.OutputStream outputStream = response.getOutputStream();

            outputStream.write(decoded);

            }

            else {

            if (header != null)

            try { response.setHeader("Content-Transfer-Encoding", header);} catch (Exception e) {}

            header = null;

            try { header = connection.getHeaderField("Content-Length");} catch (Exception e) {}

            if (header != null)

            try { response.setContentLength(Integer.parseInt(header));} catch (Exception e) {}

            if (responseCode == java.net.HttpURLConnection.HTTP_OK){

            java.io.InputStream stream = connection.getInputStream(); // поток ответа переписывается в возвращаемый пользователю поток

            byte[] buffer = new byte[20*1024];

            java.io.OutputStream outputStream = response.getOutputStream();

            while(true) {

            int readSize = stream.read(buffer);

            if(readSize==-1)

            break;

            outputStream.write(buffer,0,readSize);

            }

            }

            }

}

catch (Exception e) {}

finally {

          if (connection != null){

               connection.disconnect();

           }

}

return null;

}

Ну, вот и всё. Решение готово. Архив с кодом сервлета можно скачать

Ссылки

Задача Domino HTTP. Агент Скачать файлы одним архивом и обработка отдаваемых пользователю файлов. Часть первая

Задача Domino HTTP. Обработка загружаемых файлов сервлетом UploadProcess

Код агента zip-download

Код сервлета DownloadProcess

Пакет commons-codec-1.7.jar (для работы с base64)
 
  Опубликовано — 03/03/2021 |    



Добавить комментарий
Имя * :
e-mail
Комментарий * :
Код подтверждения * :


Мероприятия
Пресс-релизы
Биржа труда
Последнее на форуме
 
А так же:
Как удалить профиль?
16.04.2016 00:08:51
Скопировать в буфер поле документа
24.05.2015 08:55:52
Импорт DXL-описания документов в Lotus Domino. Одноимённые поля
16.04.2015 16:49:58
 
© LOGOSPHERE.RU