Tomcat: как получить доступ к менеджеру (сеанса) из сервлета

#session #tomcat #servlets #jakarta-ee

#сеанс #tomcat #сервлеты #джакарта-ee

Вопрос:

Мне нужно получить доступ к менеджеру из сервлета (или фильтра) в Tomcat, чтобы загрузить пользовательский сеанс по идентификатору пользовательского сеанса.

Отвечая на ваш следующий вопрос: зачем мне это нужно. Во Flash есть старая ошибка, из-за которой он отправляет файлы cookie из IE, а не из текущего браузера. Итак, если я нахожусь в FF и пытаюсь загрузить файл с помощью SWFUpload, я получаю неправильный сеанс и выдаю ошибку.

Я хочу добавить в POST параметр magic, который должен переопределять идентификатор сеанса по умолчанию (неправильный), затем загрузить пользовательский сеанс вместо того, который загружается Tomcat. Я не могу использовать перезапись URL, поскольку сначала разрешаются файлы cookie, и когда flash отправляет неверный файл cookie из IE, Tomcat не пытается загрузить сеанс с URL-переписанного адреса.

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

Заранее спасибо, Юрий

Ответ №1:

для Tomcat:

    ApplicationContextFacade appContextFacadeObj = (ApplicationContextFacade)    request.getSession().getServletContext();

    try
    {
        Field applicationContextField = appContextFacadeObj.getClass().getDeclaredField("context");
        applicationContextField.setAccessible(true);
        ApplicationContext appContextObj = (ApplicationContext) applicationContextField.get(appContextFacadeObj);
        Field standardContextField = appContextObj.getClass().getDeclaredField("context");
        standardContextField.setAccessible(true);
        StandardContext standardContextObj = (StandardContext) standardContextField.get(appContextObj);
        Manager persistenceManager = standardContextObj.getManager();
    }
    catch(SecurityException e)
    {
        logger.error(e);
    }
    catch(NoSuchFieldException e)
    {
        logger.error(e);
    }
    catch(IllegalArgumentException e)
    {
        logger.error(e);
    }
    catch(IllegalAccessException e)
    {
        logger.error(e);
    }
  

Ответ №2:

В отличие от кода Игоря, этот код использует немного меньше абстракции, получая Manager из HttpSession :

 private Manager manager(HttpSession session) throws Exception {

    Field facadeSessionField = StandardSessionFacade.class.getDeclaredField("session");
    facadeSessionField.setAccessible(true);
    StandardSession stdSession = (StandardSession) facadeSessionField.get(session);

    return stdSession.getManager();
}
  

Ответ №3:

Он должен быть доступен через реализацию ServletContext . Найдите исходные файлы tomcat, чтобы проверить это, или используйте отражение, чтобы получить все поля контекста. Возможно, вам придется использовать много размышлений, чтобы добраться до менеджера.

(Я не смог найти, доступен ли менеджер в JNDI, но вы также можете посмотреть там)

Ответ №4:

 private Manager getManager(ServletContext servletContext) {
        try {
            ApplicationContextFacade applicationContextFacade = (ApplicationContextFacade) servletContext;
            Field applicationContextFacadeField = ApplicationContextFacade.class.getDeclaredField("context");
            applicationContextFacadeField.setAccessible(true);
            ApplicationContext appContext = (ApplicationContext) applicationContextFacadeField.get(applicationContextFacade);
            Field applicationContextField = ApplicationContext.class.getDeclaredField("context");
            applicationContextField.setAccessible(true);
            StandardContext stdContext = (StandardContext) applicationContextField.get(appContext);
            return stdContext.getManager();
        } catch (Exception e) {
            //skip this as we can also use Manager as null for metrics
            //"Unable to get Catalina Manager. Cause: {}", e.getMessage() , e;
        }
        return null;
    }
  

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

1. Пожалуйста, добавьте некоторое объяснение к вашему ответу, чтобы другие могли извлечь из него уроки