Как я могу вручную загрузить сеанс Java с помощью JSESSIONID?

у меня есть сервлет, который обрабатывает составные формы. Сообщение фактически выполняется компонентом загрузки Flash-файла, встроенным в страницу. В некоторых браузерах Flash - сообщение не включает JSESSIONID, что делает невозможным загрузку определенной информации из сеанса во время публикации.

компонент flash upload включает файлы cookie и информацию о сеансе в специальное поле формы. Используя это поле формы, я могу получить Значение JSESSIONID. Проблема в том, что я не знаю, как использовать это значение JSESSIONID для ручной загрузки этого конкретного сеанса.

изменить - на основе решения ChssPly76 я создал следующее HttpSessionListener реализация:

    @Override
    public void sessionCreated(final HttpSessionEvent se) {
        final HttpSession session = se.getSession();
        final ServletContext context = session.getServletContext();
        context.setAttribute(session.getId(), session);
    }

    @Override
    public void sessionDestroyed(final HttpSessionEvent se) {
        final HttpSession session = se.getSession();
        final ServletContext context = session.getServletContext();
        context.removeAttribute(session.getId());
    }

который добавляет все сеансы в ServletContext как атрибуты, отображаемые их уникальными идентификаторами. Вместо этого я мог бы поместить карту сеансов в контекст, но это кажется излишним. Пожалуйста, опубликуйте любые мысли об этом решении. Затем я добавляю следующий метод в свой сервлет для разрешения сеанса по id:

    private HttpSession getSession(final String sessionId) {
        final ServletContext context = getServletContext();
        final HttpSession session = (HttpSession) context.getAttribute(sessionId);
        return session;
    }

5 ответов


нет API для извлечения сеанса по идентификатору.

Что вы можете сделать, однако, реализовать сессии слушатель в вашем веб-приложении и вручную поддерживать карту сеансов с ключом id (идентификатор сеанса извлекается через сессии.getId()). Затем вы сможете получить любой сеанс, который хотите (в отличие от обмана контейнера в замене текущего сеанса на него, как предлагали другие)


безопасный способ сделать это - установить идентификатор jsession в cookie-это намного безопаснее, чем установить его в url.

Как только он установлен как cookie, вы можете получить сеанс обычным способом, используя

request.getSession();

method.setRequestHeader("Cookie", "JSESSIONID=88640D6279B80F3E34B9A529D9494E09");

в спецификации сервлета нет способа, но вы можете попробовать:

  • ручная настройка cookie в запросе, сделанном Flash

  • или делать, как Тейлор L только что предложил, когда я печатал и добавлял параметр jsessionid путь URI.

оба метода свяжут ваше приложение с запуском на контейнере сервлетов, который ведет себя как Tomcat; я думаю, что большинство из них. Для обоих также потребуется ваш Flash-апплет запрашивать у страницы файлы cookie, которые могут налагать зависимость JavaScript.


Это действительно хороший пост. Одна потенциальная проблема, которую я вижу с использованием прослушивателя сеансов для добавления сеансов в контекст, заключается в том, что он может стать довольно толстым в зависимости от количества одновременных сеансов. А затем вся дополнительная работа по настройке веб-сервера для прослушивателя.

Так как насчет этого для гораздо более простое решение. Я реализовал это, и это работает довольно хорошо. Поэтому на странице, загружающей объект flash upload, сохраните сеанс и sessionid в качестве пары ключ-значение в объекте приложения затем передать этот идентификатор сеанса на страницу загрузки в качестве параметра post. На странице загрузки см., Если этот sessionid уже находится в приложении, поэтому используйте этот сеанс, иначе получите его из запроса. Кроме того, затем перейдите и удалите этот ключ из приложения, чтобы сохранить все в чистоте.

на странице swf:

application.setAttribute(session.getId(), session);

затем на странице загрузки:

String sessid = request.getAttribute("JSESSIONID");
HttpSession sess = application.getAttribute(sessid) == null ?
        request.getSession() :
        (HttpSession)application.getAttribute(sessid);
application.removeAttribute(sessid);

очень хорошее решение, ребята. Спасибо для этого.


Если вы используете Tomcat, вы спрашиваете tomcat напрямую (но это уродливо). Бьюсь об заклад, есть и другие хакерские решения для других веб-серверов.

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

Ниже приведен контекстный прослушиватель, который захватывает этот менеджер при запуске контекста, а затем может использоваться для получения Tomcat Сессия.

public class SessionManagerShim implements ServletContextListener {
    static Manager manager;

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        try {
            manager = getManagerFromServletContextEvent(sce);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        manager = null;
    }

    private static Manager getManagerFromServletContextEvent(ServletContextEvent sce) throws NoSuchFieldException, IllegalAccessException {
        // Step one - get the ApplicationContextFacade (Tomcat loves facades)
        ApplicationContextFacade contextFacade = (ApplicationContextFacade)sce.getSource();

        // Step two - get the ApplicationContext the facade wraps
        Field appContextField = ApplicationContextFacade.class.getDeclaredField("context");
        appContextField.setAccessible(true);
        ApplicationContext applicationContext = (ApplicationContext)
                appContextField.get(contextFacade);

        // Step three - get the Context (a tomcat context class) from the facade
        Field contextField = ApplicationContext.class.getDeclaredField("context");
        contextField.setAccessible(true);
        Context context = (Context) contextField.get(applicationContext);

        // Step four - get the Manager. This is the class Tomcat uses to manage sessions
        return context.getManager();
    }

    public static Session getSession(String sessionID) throws IOException {
        return manager.findSession(sessionID);
    }
}

вы можете добавить это в качестве слушателя в свои сети.XML и он должен работать.

тогда вы можете сделать это, чтобы получить сеанс.