Получение контекста сервлета, сеанса и запроса во внешнем контейнере POJO - PullRequest
7 голосов
/ 22 января 2011

Есть ли способ получить сеанс из POJO?Или, в конечном счете, для получения bean-компонента из POJO.

Чтобы уточнить:

В основном я создаю bean-компонент из сервлета, и мне нужно получить доступ к свойствам этого bean-компонента извне веб-контейнера.(из POJO).Я не могу передать просьбу в Pojo;и запрос необходим для получения сеанса.

В частности, у меня есть веб-приложение, которое использует платформу Cactus для запуска тестов JUnit из веб-интерфейса.Однако сервлет, который вызывает тестер JUnit, скомпилирован в jar;Я добавил дополнительные раскрывающиеся меню, чтобы изменить настройки, из которых будет считываться тест JUnit, для переключения между различными средами (кластерами WLI), поэтому, учитывая, что сервлет бегуна уже скомпилирован, я не могу изменить его для обработки дополнительных параметров из нескольких сред.Я попробовал постоянный подход записи в файл .dat, из которого тест JUnit будет читать с помощью класса Reader;также я попробовал бобовый подход, который в конечном итоге не был доступен из теста JUnit.

Ответы [ 4 ]

11 голосов
/ 22 января 2011

Только и только если ваш POJO работает в том же потоке , в котором работает HttpServletRequest, вы сможете достичь этого с помощью ThreadLocal<T>.

Создайте следующий класс:

public final class YourContext implements AutoCloseable {

    private static ThreadLocal<YourContext> instance = new ThreadLocal<>();

    private HttpServletRequest request;
    private HttpServletResponse response;

    private YourContext(HttpServletRequest request, HttpServletResponse response) {
        this.request = request;
        this.response = response;
    }

    public static YourContext create(HttpServletRequest request, HttpServletResponse response) {
        YourContext context = new YourContext(request, response);
        instance.set(context);
        return context;
    }

    public static YourContext getCurrentInstance() {
        return instance.get();
    }

    @Override    
    public void close() {
        instance.remove();
    }

    public HttpServletRequest getRequest() {
        return request;
    }

    public HttpSession getSession() {
        return request.getSession();
    }

    public ServletContext getServletContext() {
        return request.getServletContext();
    }

    // ... (add if necessary more methods here which return/delegate the request/response).    
}

Реализуйте javax.servlet.Filter, который выполняет следующие действия в методе doFilter() и отображается на интересующий url-pattern, например, /* или servlet-name вашего сервлета фронт-контроллера.

@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws ServletException, IOException {
    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;

    try (YourContext context = YourContext.create(request, response)) {
        chain.doFilter(request, response);
    }
}

Обратите внимание на важность оператора try-with-resources. Это гарантирует, что YourContext#close() будет вызван после того, как фильтр выполнит свою работу, а ресурс ThreadLocal будет очищен. В противном случае поток все равно будет содержать его при повторном использовании для другого HTTP-запроса.

А вот как вы могли бы использовать его в POJO:

YourContext context = YourContext.getCurrentInstance();
HttpSession session = context.getSession();

В основном все это также работает с Context объектами среднего MVC-фреймворка, такими как FacesContext JSF и объект в Wicket.

Сказал, что вы смотрели на CDI ? Возможно, проще создать артефакты, управляемые CDI, чтобы вы могли просто @Inject соединить их друг с другом.

3 голосов
/ 22 января 2011

Да, есть.

Если вы используете веб-фреймворк, например, Wicket, часто есть способ получить текущую HttpSession.Оттуда вы можете получить Spring ApplicationContext и, если у вас есть, вы можете получить Spring Beans из него.Это работает в любом месте, так как мы используем только статические служебные методы.

Пример кода:

import org.apache.wicket.protocol.http.WebApplication;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.context.WebApplicationContext;

ServletContext sc = WebApplication.getServletContext();
WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(sc);

Object bean = wac.getBean("myBeanId");

Обратите внимание, что должны быть установлены пружинный фильтр и фильтр калитки и обработать текущий запрос, в противном случае служебные методы выиграютне работает.

Если вы не имели в виду Spring Beans, то вам бы пришлось хранить их в HTTP-сессии самостоятельно.Если у вас нет веб-фреймворка, вы можете сделать то, что предлагает rfeak , и реализовать свой собственный ThreadLocal.

2 голосов
/ 22 января 2011

Предполагая, что вы имеете в виду программирование сервлета ....

Нет прямого способа добраться из POJO в сессию.Вам нужно получить Session от объекта HttpServletRequest.

Есть два популярных решения, которые я видел для решения этой проблемы.

Первый вариант - создать объект контекста, которыйсодержит сессию.Затем этот контекст передается на ваш бизнес-уровень, чтобы ваши POJO могли получить эту информацию, если им это нужно.

Второй вариант - использовать хранилище ThreadLocal.Часто сеанс помещается в хранилище ThreadLocal с помощью фильтра или перехватчика.Тогда любой объект в вашей системе может получить его из потока.Этот шаблон обнаруживается во многих веб-фреймворках, таких как Spring и Struts.

2 голосов
/ 22 января 2011

Pojo - это простой старый Java-объект.POJOS не имеет ничего общего с сессиями.

Сеанс https доступен для объекта запроса.

Проверьте это

http://download.oracle.com/docs/cd/E17802_01/webservices/webservices/docs/1.6/api/index.html

, в частности,Интерфейс HttpServletRequest и метод getSession ().

Для части «bean» вашего вопроса.Бин - это Java-класс, соответствующий 3 стандартам.

  1. Нет конструктора arg
  2. Установщики и получатели для доступа к закрытым полям
  3. Реализует сериализуемый.

POJO - это боб, если он следует этим соглашениям.

...