| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Java EE (J2EE) и Spring > Как "убить" или остановить сервлет вручную? |
| Автор: olegrolik 30.11.2007, 16:25 |
| Есть веб приложение, есть два сервлета, которые работают. Первый что-то выполняет (отправляет, принимает и т.д.). Второй нужен для того, чтобы при его запуске убить первый (или хотя бы остановить - если остановка возможна конечно). Как это можно реализовать? Есть кое-какие мысли и соображения: Например второй сервлет ищет инстанс первого и убивает его. Забегая вперёд, хочу спросить, можно ли таким же образом осуществить запуск первого сервлета? Т.е. в зависимости от параметра запускать/останавливать первый ? Спасибо. |
| Автор: olegrolik 30.11.2007, 17:24 | ||
| Maksym, понимаю создать инстанс/убить инстанс. Для начала так. Убивать сервлет, для того, чтобы он ничего не делал ----------------------------------------------------------- Хм.... а вообще я тут ступил конкретно.... Можно ведь сделать что-то вроде такого:
|
| Автор: Souljah 30.11.2007, 17:52 |
| Опиши задачу поточнее. Что значит "ничего не делал"? Чтобы перестал отзываться на url-mapping к нему? Менеджментом инстансов сервлетов заведует контейнер, убить сервлет без правки контейнерного кода не получится никак |
| Автор: Maksym 30.11.2007, 17:59 | ||
Ты пробовал после этого отправить запрос на сервлет..? Я не тестил, но вроде как этот метод должн дергаться контейнером и открыт в API, чтобы в нем ресурсы освобождать, контейнер может протупить твой вызов и не заблокировать следующее обращение к service... |
| Автор: COVD 30.11.2007, 19:42 |
| Речь очевидно о том, что надо остановить поток, обслуживающий запрос клиента. Клиентов в общем случае много и потоков столько же (а сервлет один, про него вообще можно забыть, это всего лишь описание последовательности действий, "виртуальная функция" Клиент послал запрос. На сервере создался новый поток (или свободный из пула взят) и стал его выполнять. Клиент устал ждать и нажимает кнопку "Отменить". Сервер получает новый запрос "отменить" (очевидно, обрабатывается другим сервлетом). Опять создается новый поток, чтобы выполнить эту команду, т.е. остановить первый поток. Чтобы остановить выполнение первого потока надо предусмотреть в его шагах условия остановки, т.е. контрольную точку, флаг, которую он периодически проверяет, не слишком ли долго он копается с обработкой. Если да, то поток прекращает выполнение и закрывает соединение или шлет код ошибки. А второй поток, отменяющий, должен иметь доступ к этому флагу. Если бы клиент предполагался всегда один, то этот флаг можно было бы сделать статическим. Но если клиентов одновременно может быть много, то этот флаг должен быть в сессии клиента, чтобы клиент не отменил чужой запрос. |
| Автор: olegrolik 2.12.2007, 23:43 | ||
Да, речь о том, чтобы остановить поток. И поток будет один, т.к. мой сервлет-класс реализует SingleThreadModel интерфейс (правда он deprecated, но речь не об этом). Souljah, если ты имеешь ввиду: не получится убрать <servlet> из web.xml, то я с этим согласен. Требуется просто остановить. Я точно не могу сформулировать свою задачу. Просто скажу то, что к сервлету постоянно кто-то обращается и передаёт какую-то информацию. Я хочу с помощью запроса типа http://server:8080/MyServlet?action=shutdown остановить его. Что в данном случае остановить - не знаю. Возможно запустить его метод destroy, возможно ещё есть какие-то варианты? Опять повторюсь : Забегая вперёд, хочу спросить, можно ли таким же образом осуществить запуск первого сервлета? Спасибо за помощь. |
| Автор: olegrolik 3.12.2007, 11:02 |
| Maksym, попробовал вариант с this.destroy(). Метод вроде бы выполняется, но сервлет не убивается, т.е. потом запросы к нему приходят. Ты был прав. Вопрос остаётся открытым. |
| Автор: Maksym 3.12.2007, 12:24 |
| 1. Обрамить весь код в service() сервлета if'ом по какому-нибудь флагу из статики. Сделать синхронизированный метод по переключению этого флага (action=shutdown будет дергать это метод). При вызове сервлета клиентом -- service(), конечно, отработает но if его не пустит, а на else можно повесить, например, редирект на какую-нибудь страницу "сервис отключен, обратитесь к администрации". 2. Написать фильтр, который будет перехватывать обращения к сервлетам и проверять включена ли эта функциональность (вызванный сервлет) в данный момент. Если нет -- делать редирект на всю ту же "сервис отключен, обратитесь к администрации". Оба подхода позволяют включить функциональность обратно (а вдруг понадобится..) без перезапуска контейнера. Второй подход намного гибче и идеологически вернее -- рекомендую его. Сама же идея принудительной выгрузки сервлета "изнутри" не кажется мне правильной в рамках лайф цикла веб-приложения; разработчики контейнера и спецификации тоже, думаю, не случайно не оставили такой возможности. |
| Автор: olegrolik 3.12.2007, 13:23 | ||||||
Maksym, совсем не понял что ты хотел сказать. Синхронизация мне не нужна, т.к. инстанс будет всегда один.
Это о чём вообще?
|
| Автор: Maksym 3.12.2007, 14:25 |
Может быть я очень сложно написал очень простую мысль о том, что запретить выполнение кода в метода можно с помощью конструкции if.. сори http://java.sun.com/products/servlet/Filters.html Тот пример, который ты привел -- не очень верный. Сейчас убегаю, напишу про него позже. |
| Автор: olegrolik 3.12.2007, 17:18 | ||||
| Maksym, спасибо. С нетерпением жду твою версию. Я тут сделал небольшой "трюк". Смысл моего приложения в приёме файла от клиента. Я создал public class Global, который содержит в себе перменную boolean manage.
В сервлете рассмотрел следующие условия (метод doGet, к примеру):
Как вам такой вариант? Конечно не "стильно", зато полностью отвечает тому, что я хотел сделать. Получается, что тему неправильно назвал. Хотя, посмотрим что предложит Maksym. |
| Автор: Maksym 3.12.2007, 17:31 |
| olegrolik В последнем примере ты положил флаг в статику, а изменяешь его из кода, который будет выполняться в различных потоках. Мне кажется, что здесь нужна синхронизация доступа к этому флагу. Посмотрел ли ты про фильтры? Это инструмент специально предназначенный для осуществления проверок такого типа, как в последнем сервлете. |
| Автор: olegrolik 3.12.2007, 17:46 |
| Maksym, у меня поток будет один, т.к. сервлет реализует SingleThreadModel интерфейс. Фильтры посмотрел, но видимо здесь можно обойтись и без них. P.S. Я собираюсь реализовывать это дело в Spring MVC. Эти условия (if'ы) будут прописаны в контроллере. хмм.... если Spring, то прийдётся сделать синхронизацию доступа. Не хочется использовать просто устаревший интерфейс SingleThreadModel. К тому же под вопросом возможность его использования. Как бы то ни было, Maksym, спасибо. Лови плюсик! Также хочу добавить, что клиент может сам остановить сервлет. А это недопустимо. В принципе можно в качестве параметра взять что-то вроде: "45345fdsfisdof3i-3ffsdf" Но это некрасиво. Кто ещё что предложит? |