Безголовый Java-сервлет?

У меня есть автономное, безголовое приложение Java-сервера, которое выполняет кучу обработки на основе очередей в базе данных, которую я думаю перенести на сервер приложений Java. У меня много опыта работы с java и немного JSP, но не так много опыта работы с сервлетами.

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

Несколько вопросов:

1) Поскольку в моем приложении нет механизма HTTP (или другого) запроса/ответа, было бы глупо реализовать сервлет, который не имеет сопоставлений URL? Глядя на API, могу ли я просто реализовать GenericServlet и просто оставить метод service() пустым?

2) Другая часть моего java-приложения открывает/управляет своими собственными сетевыми сокетами (не HTTP) для приема потока входящих данных. Я думаю, что потребуется немало усилий, чтобы вписать его в модель запроса/ответа сервлета. Это нормально, что сервлет открывает/управляет своими сетевыми сокетами?

3) У нас также есть куча веб-приложений (в настоящее время в coldfusion), которые не очень хорошо интегрированы с java-приложением (поскольку они могут общаться только через БД). Мы смотрим на railo (еще один сервлет), и я пытаюсь выяснить, насколько легко приложения coldfusion/railo (работающие на одном сервере приложений) могли бы напрямую взаимодействовать друг с другом. Возможно, веб-страница, которая отображает текущую статистику/показатели времени выполнения движка java и, в конечном итоге, также вызывает некоторую бизнес-логику в движке java.

Спасибо, Брайан


person Brian    schedule 22.03.2010    source источник


Ответы (2)


  1. Сервлеты — это общий механизм, не привязанный конкретно к миру HTTP (несмотря на то, что HttpServlets используются в 99,999% случаев). Вы можете создать подкласс класса Servlet для реализации, скажем, MailServlet, который будет реагировать на почтовые события, но, насколько я знаю, современные веб-серверы поддерживают только HTTP-сопоставления.

  2. Сокеты принадлежат миру Java EE, и запуск пользовательских потоков в этой среде считается плохой вещью — и вам наверняка придется это делать, если вы открываете сокеты (для опроса данных и т. д.)

person Olivier Croisier    schedule 22.03.2010
comment
У меня определенно есть куча потоков, которые я запускаю/управляю. Неужели так уж плохо иметь потоки порождения сервлета? Я читал, что он должен быть потокобезопасным, но никогда не видел ничего о порождении потоков. - person Brian; 22.03.2010
comment
@ Брайан, это обычно не одобряется; потому что плохо управляемый поток, запущенный вашим сервлетом, может помешать контейнеру/серверу сервлета реагировать на команды выключения. Вместо этого посмотрите на использование фреймворка Executor. - person matt b; 22.03.2010
comment
@Brian - Почему создание потоков считается плохим -› stackoverflow.com/questions/533783/. В вашем случае это сведет на нет ваши рассуждения об управляемости, поскольку вы делаете то, с чем контейнер не может справиться. - person Robin; 22.03.2010

Если вы не хотите перехватывать HTTP-запросы, просто не расширяйте HttpServlet. Это не имеет никакого смысла. Если вы действительно хотите выполнить его как «фоновую задачу» при запуске веб-приложения и остановить его при завершении работы веб-приложения, просто реализуйте ServletContextListener соответственно.

public class Config implements ServletContextListener {

    private YourApp yourApp;

    public void contextInitialized(ServletContextEvent event) {
        yourApp = new YourApp();
        yourApp.start();
    }

    public void contextDestroyed(ServletContextEvent event) {
        yourApp.stop();
    }

}

который вы можете зарегистрировать в web.xml следующим образом:

<listener>
    <listener-class>com.example.Config</listener-class>
</listener>

Если YourApp на самом деле не запускает задачу в отдельном потоке, вам нужно заключить ее в Runnable и выполните его, используя ExecutorService. Например.

public class Config implements ServletContextListener {

    private ExecutorService executor;

    public void contextInitialized(ServletContextEvent event) {
        executor = Executors.newSingleThreadExecutor();
        executor.submit(new YourApp()); // YourApp should implement Runnable.
    }

    public void contextDestroyed(ServletContextEvent event) {
        executor.shutdown();
    }

}

Если, в конце концов, ваше веб-приложение ничего не делает, кроме этого, то я сомневаюсь в ценности его запуска в контейнере сервлетов. Вместо этого просто запустите его как отдельное Java-приложение, используя метод main().

person BalusC    schedule 22.03.2010
comment
В настоящее время он работает автономно через main(). Я оцениваю сервер приложений, потому что: 1) управляемость (особенно если мы можем запускать его вместе с остальными нашими веб-приложениями, 2) возможность интеграции наших веб-приложений с движком (вопрос № 3 в моем исходном посте) 3) долгосрочная перспектива: раскрытие некоторые из его внутренностей как веб-сервисы. - person Brian; 22.03.2010
comment
также, как службы приложений выставляются на серверах приложений? Нравится служба планировщика в Coldfusion/Railo? Будут ли они использовать механизм ServletContextListener? - person Brian; 22.03.2010
comment
Тогда просто используйте подход ServletContextListener, вам нужно только обернуть его в Runnable. Я не занимаюсь Coldfusion/Railo, но могу представить, что они делают нечто подобное. В противном случае просто загляните в их документы/исходный код, чтобы убедиться. - person BalusC; 22.03.2010