代码之家  ›  专栏  ›  技术社区  ›  Robert Campbell

如何使用JSESSIONID手动加载Java会话?

  •  34
  • Robert Campbell  · 技术社区  · 17 年前

    flash上传组件确实在一个特殊的表单字段中包含cookie和会话信息。使用此表单字段,我实际上可以检索JSESSIONID值。问题是,我不知道如何使用此JSESSIONID值手动加载特定会话。

    编辑- 基于ChssPly76的解决方案,我创建了以下内容 实施:

        @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映射的属性。我可以把会议地图放在上下文中,但这似乎是多余的。请发表对这一决定的任何想法。接下来,我将以下方法添加到我的servlet中,以通过id解析会话:

        private HttpSession getSession(final String sessionId) {
            final ServletContext context = getServletContext();
            final HttpSession session = (HttpSession) context.getAttribute(sessionId);
            return session;
        }
    
    5 回复  |  直到 13 年前
        1
  •  27
  •   ChssPly76    17 年前

    没有API可以通过id检索会话。

    session listener 在您的web应用程序中,手动维护一个由id键控的会话映射(会话id可通过以下方式检索 session.getId()

        2
  •  3
  •   Youcef LAIDANI    9 年前

    一种安全的方法是在cookie中设置jsession id,这比在url中设置要安全得多。

    一旦设置为cookie,您就可以使用以下命令以正常方式检索会话

    request.getSession();
    
    method.setRequestHeader("Cookie", "JSESSIONID=88640D6279B80F3E34B9A529D9494E09");
    
        3
  •  3
  •   Sam Sieber    8 年前

    它使用“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);
        }
    }
    

    您可以将其添加为web.xml中的侦听器,它应该可以工作。

    然后你可以这样做以获得一个会话。

        4
  •  1
  •   Andrew Duffy    17 年前

    servlet规范中没有办法,但您可以尝试:

    • 在Flash发出的请求中手动设置cookie

    • 或者按照Taylor L刚才建议的那样做,因为我正在键入并添加jsessionid参数——URI的路径。

    这两种方法都会将您的应用程序绑定到在行为类似于Tomcat的servlet容器上运行;我认为它们中的大多数都是这样。两者都需要你的Flash小程序向页面请求Cookie,这可能会带来JavaScript依赖。

        5
  •  0
  •   Garfield    14 年前

    这是一篇非常好的文章。我看到使用会话侦听器不断向上下文中添加会话的一个潜在问题是,根据并发会话的数量,它可能会变得相当庞大。然后是监听器的web服务器配置的所有额外工作。

    在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);
    

    非常好的解决方案,伙计们。谢谢你。