Вопрос о дизайне JSP/ сервлета - Сделать запрос / ответ глобально доступным через JNDI
В PHP всегда можно получить доступ к текущему запросу или ответу из любой части своего кода. Эта концепция является фундаментальной для программирования PHP. Данные запроса, данные ответа, данные сеанса (и т. Д.) Всегда рядом!
Этого не происходит в Java-сервлетах! Чтобы иметь доступ к HttpServletRequest, HttpServletResponse, HttpSession (и т. Д.) В вашем коде, вам необходимо передать их как переменные функции. Это означает, что вы не можете кодировать веб-фреймворк, который по своей сути "знает" обо всем этом и устраняет сложность их передачи.
Итак, я разработал это решение:
- Создать и зарегистрировать ServletRequestListener.
- При событии requestInitialized связывайте текущий запрос HttpServletRequest с контекстом JNI, указав имя текущего потока (Thread.currentThread(). GetName());
- После события requestDestroyed отсоедините указанный выше ресурс JNI для очистки.
Таким образом, можно получить доступ к текущему запросу / ответу из любого места своего кода, поскольку они всегда присутствуют в контексте JNI и могут быть получены путем предоставления имени текущего потока.
Все известные контейнеры сервлетов реализуют однопотоковую модель для каждого запроса, поэтому нельзя смешивать запросы (конечно, не следует забывать их очищать).
Кроме того, ресурсы JNI каждого веб-приложения по умолчанию разделены, поэтому нет проблем их смешивания или проблем безопасности, которые могут возникнуть из-за того, что одно веб-приложение имеет доступ к запросам других.
Какая-то скрученная, но приятная и простая...
Как вы думаете?
2 ответа
Я думаю, что некоторые веб-фреймворки (GWT, Axis) уже делают это, но гораздо более простым способом: с помощью статической переменной ThreadLocal (или доступной из единственного объекта). Весна также имеет такую возможность.
Я не уверен, что он работает со всеми контейнерами, хотя. Если контейнер использует неблокирующий ввод-вывод и повторно использует один и тот же поток для параллельной обработки нескольких запросов, он больше не будет работать.
См. Раздел Получение объекта HttpServletRequest (request) из кода Java для аналогичного вопроса (и его ответов).
Если вы беспокоитесь о том, что разные запросы могут быть испорчены (а затем думаете о "подзапросах", как окошко модели), возможно, вы бы предпочли использовать Seam? Они используют абстракцию, называемую "Сессия", для обработки МНОГО того, что мы, разработчики, пытаемся взломать с помощью других традиционных стеков веб-технологий. Шов построен на JSF так же, как к вашему сведению. Вам не нужно использовать EJB 3 или Hibernate с ним, но он прекрасно интегрируется с обоими из них. Что-то думать о.