Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Java EE (J2EE) и Spring > Проблема с сервлетами


Автор: 3,14 10.11.2004, 10:48
В одном package описано два различных сервлета, как обратиться из одного сервлета к методам другого?

Автор: Domestic Cat 10.11.2004, 16:15
Ответ тут:

http://www.jguru.com/faq/view.jsp?EID=5049

Автор: 3,14 11.11.2004, 10:56
Мне как раз нужно что-нить вроде:
Код

MyServlet ms=(MyServlet)  getServletConfig().getServletContext().getServlet("myname");

а он depricated smile
RequestDispatcher не пдходит, потомучто там нужно не forward-ить request, а именно достучаться до методов одного сервлета из другого

Автор: Domestic Cat 11.11.2004, 16:55
Ну так просто создай инстанс сервлетa и вызывай егo методы. Или я нe так понял ?

Автор: 3,14 12.11.2004, 14:24
Не, это не подойдёт. Ситуация такая
Сервлет 1: обрабатывает HTTP запросы
Сервлет 2: обеспечивает связь с некой удалённой БД (проверяет через некие отрезки времени если соединения нет, то пытается поднять его). Так же содержит простейшие API для работы с этой БД.

Дак вот ситуцаия такая - из сервлета 1 нужно обратиться к БД через сервлет 2. Инстанс создавать нельзя потомучто нужно обратиться именно к тому что торчит в памяти, потомучто он соединён с БД.

Автор: Nobody 12.11.2004, 16:20
Я бы переделал архитектуру приложения. Например, зарегистрировал DataSource в JNDI.

Автор: Domestic Cat 12.11.2004, 16:22
Но в память можно положить обычный класс, прицепив его к ServletContext. Тогда этот инстанс можно будет получать откуда угодно через getAttribute.

Если нужно чтобы это все-таки был сервлет, можно использовать URLConnection.

Автор: 3,14 12.11.2004, 16:40
Цитата(Nobody @ 12.11.2004, 16:20)
Я бы переделал архитектуру приложения.

Это не реально, сделать этого мне не дадут

Цитата(Domestic @ 12.11.2004, 16:22)
Но в память можно положить обычный класс, прицепив его к ServletContext.
Если я правильно понял, то сервлет 2 просто цепляет к ServletContext-у, а сервлет 1 его оттуда достаёт? smile

Цитата(Domestic @ 12.11.2004, 16:22)
Если нужно чтобы это все-таки был сервлет, можно использовать URLConnection.
Это не то, через него как я понимаю нельзя обратиться к методам класса smile

Автор: 3,14 12.11.2004, 16:51
Может где есть API по Tomcat-овским библиотекам, думаю что через них это должно решаться элементарно

Автор: Domestic Cat 12.11.2004, 17:06
Цитата
Это не то, через него как я понимаю нельзя обратиться к методам класса


Но раз это сервлет, то предполагается, что он должен обрабатывать POST/GET реквесты?

Автор: 3,14 12.11.2004, 17:23
Понятно что doGet, doPost, service сработают, но еть не то. Попробую обьяснить по подробней:
На сайт понадобилось добавить возможность дёргать данные из удалённой БД. Делается еть так: открывается TCP сокет к хосту БД, в сокет записывается ряд команд (ничего общего с SQL) и оттуда в ответ приходят данные. Простейшая имплементация этого элементарна, но проблема в том что каждый раз создавать сокет заново и авторизоваться слишком долго, поэтому желательно чтоб к моменту клиентского запроса сокет уже бы был открыт. Хранить сам сокет в основном сервлете (сервлет 1) плохо по следующей причине : в случае падение конекта (а если он упадёт то в лучшем случае появится минут через 10) при каждой попытке прочитать что-то из БД пользователем придётся пытаться конектиться по новой, что будет сильно тормозить систему. Для обхода этой проблемы я решил создать отдельный сервлет (сервлет 2), который каждые n-минут проверяет не упал ли конект, а если упал то пытается поднять. А сервлет 1 просто пользуется открытым сервлетом 2 конектом.

Автор: Domestic Cat 12.11.2004, 17:28
Но ведь можно создать объект класса (не сервлета), который будет этим заниматься; грузить его при загрузке приложения, подцепляя к контексту этого приложения. Оттуда он будет доступен всем сервлетам.

Автор: 3,14 12.11.2004, 18:53
А как сделать чтоб он автоматически через нек-ие переоды времени проверял доступна связь или нет?

Автор: Domestic Cat 12.11.2004, 19:16
так же, как бы ты сделал для любого другого обычного класса - запусти тред / таймер.

Автор: 3,14 12.11.2004, 19:22
В какой процедуре его запускать, не в service-е же? Обьясни пжайлуста, ато я совсем с этим не знаком smile

Автор: Domestic Cat 12.11.2004, 19:37
Если этo будеt обычный класс, тo и метода service нe nado. Запускать можнo кak угодно - в конструкторе например.

Автор: 3,14 12.11.2004, 19:42
Кажется начинаю понимать. Экземпляр этого класса должон быть членом сервлета, а стартовать таймер должен в init-е сервлета, так?

Автор: Domestic Cat 12.11.2004, 20:15
Можно и статическим членом сервлета (smile smile), нo лучшe цеплять егo к ServletContext (getServletContext().addAttribute("db", myClass)) в методе contextInitialized у ServletContextListener'a.

Автор: DarkDS 12.11.2004, 21:24
В процедуре инициализации сервлета проверяешь - есть ли в контексте класс (по какому то адрессу)
Если нет - создаешь новый инстанс класса и ложишь в контекст.
В контрукторе класса делаешь запуск нового треда таймера с пингом.
При обработке реквеста просто берешь из контекста этот класс и обращаешься к его методам.

Автор: Domestic Cat 12.11.2004, 23:42
Цитата
В процедуре инициализации сервлета проверяешь - есть ли в контексте класс (по какому то адрессу)
Если нет - создаешь новый инстанс класса и ложишь в контекст.


Болеe естественно грузить ресурсы в листенерe при стартe веб приложения.

Автор: 3,14 13.11.2004, 08:52
Цитата(Domestic @ 12.11.2004, 23:42)
Болеe естественно грузить ресурсы в листенерe при стартe веб приложения.

А чем этот вариант лучше?

Автор: Domestic Cat 13.11.2004, 23:32
Листенер ServletContextListener служит для того чтобы грузить нужные ресурсы при старте веб приложения и избавляться от них при завершении работы. это гарантирует, чтo даже до тогo, как первый клиент обратился к сервлету (-там), все нужные ресурсы находятся в памяти.

Если же делать объект, осуществляющий коннеhн, полем сервлета, то эот объект будet создаn только при загрузке сервлета, тo есть при первом запросe нa этот сервлет.


Автор: 3,14 15.11.2004, 11:10
Цитата(Domestic @ 13.11.2004, 23:32)
Если же делать объект, осуществляющий коннеhн, полем сервлета, то эот объект будet создаn только при загрузке сервлета, тo есть при первом запросe нa этот сервлет.

Дык а настройка loadonstartup для сервера чем хуже этого варианта?

Автор: Domestic Cat 15.11.2004, 16:32
smile Тады стандартный аргумент - разделение функциональности. Листенер ответственен за одно, сервлет - за другое.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)