получить HttpSession | запрос от простого класса java, а не от класса servlet

#java #jsp #servlets #jakarta-ee

#java #jsp #сервлеты #джакарта-ee

Вопрос:

я хочу, чтобы объект сеанса был не в классе servlet, а обычным из нашего приложения.

WEB.XML

 <listener>
        <listener-class>com.abc.web.ApplicationManager</listener-class>
</listener>
<listener>
        <listener-class>com.abc.web.SessionManager</listener-class>
</listener>
  

ViewPrices.java

 public class ViewPrices implements Cloneable, Serializable {

 Session session = request.getSession();
                   servletContext.getSession()
                   anyWay.getSession();
}
  

Ответ №1:

вызовите это:

 RequestFilter.getSession();
RequestFilter.getRequest();
  

в вашем пользовательском фильтре:

 public class RequestFilter implements Filter {

    private static ThreadLocal<HttpServletRequest> localRequest = new ThreadLocal<HttpServletRequest>();


    public static HttpServletRequest getRequest() {
        return localRequest.get();
    }

    public static HttpSession getSession() {
        HttpServletRequest request = localRequest.get();
        return (request != null) ? request.getSession() : null;
    }


    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        if (servletRequest instanceof HttpServletRequest) {
            localRequest.set((HttpServletRequest) servletRequest);
        }

        try {
            filterChain.doFilter(servletRequest, servletResponse);
        } finally {
            localRequest.remove();
        }
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void destroy() {
    }
}
  

что вы зарегистрируете его в своем web.xml файл:

 <filter>
    <filter-name>RequestFilter</filter-name>
    <filter-class>your.package.RequestFilter</filter-class>
</filter>

<filter-mapping>
    <filter-name>RequestFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
  

Комментарии:

1. должен ли я использовать цепочку. doFilter (запрос, ответ); для дальнейшего процесса, потому что я получаю пустой экран браузера.

2. извините, моя ошибка (я полностью забыл об этом), я только что исправил это 🙂

3. -1: не потокобезопасен. Потоки объединены контейнером, и вы неправильно освобождаете переменную threadlocal.

4. добавлено удаление запроса после завершения запроса

5. Я люблю тебя <3 ты только что спас мне жизнь 🙂

Ответ №2:

Есть несколько способов сделать это, но .. не делайте. Только ваш веб-уровень должен иметь доступ к сеансу. Другие уровни должны получать только те параметры из сеанса, которые ему нужны. Например:

 service.doSomeBusinessLogic(
     session.getAttribute("currentUser"), 
     session.getAttribute("foo"));
  

Параметры, которые у вас есть для получения запроса, а из него — сеанса в классе, отличном от servlet, который все еще находится на веб-уровне:

  • сохраните запрос в ThreadLocal в Filter (и очистите его впоследствии)
  • передайте это как аргумент — либо в конструкторе (если экземпляр объекта создается при каждом запросе), либо в качестве аргумента метода.

Комментарии:

1. Передача интересующей информации (и, следовательно, не самого сеанса!) — абсолютно лучший способ.

2. Но как вы настраиваете вещи в сеансе?

3. @ mjaggard doSomeBusinessLogic вернет карту для сохранения обратно в сеанс.

Ответ №3:

Я не думаю, что это возможно, напрямую обращаться к сеансу и запрашивать объект. Что вы можете сделать, это передать сеанс и / или объект запроса из servlet в класс Java либо в каком-либо методе, либо в конструкторе класса Java.