Как я могу вручную загрузить сеанс 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 и он должен работать.
тогда вы можете сделать это, чтобы получить сеанс.