Tomcat:如何从servlet访问(会话)管理器

时间:2011-04-27 16:50:18

标签: session tomcat servlets java-ee

我需要从Tomcat中的servlet(或过滤器)访问Manager,以通过自定义会话ID加载自定义会话。

回答你的下一个问题:为什么我需要它。 Flash中存在一个旧错误,导致它从IE发送cookie,而不是从当前浏览器发送。所以,如果我在FF中并且我正在尝试使用SWFUpload上传文件,那么我最终会得到错误的会话和错误。

我想将magic参数添加到应该覆盖默认(错误)会话ID的POST,然后加载自定义会话而不是Tomcat加载的会话。我不能使用URL重写,因为cookie首先被解析,当flash从IE发送错误的cookie时,Tomcat不会尝试从url重写的地址加载会话。

我很欣赏任何其他提示如何从上下文访问Manager或原始问题的解决方案。

提前致谢, Juriy

4 个答案:

答案 0 :(得分:6)

Ihor 的代码相反,此代码通过从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();
}

答案 1 :(得分:5)

对于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 :(得分:4)

应该可以通过ServletContext的实施来访问它。获取tomcat的源代码来检查它,或使用反射来获取上下文的所有字段。你可能不得不使用大量的反思才能找到经理。

(我无法找到经理是否在JNDI中公开,但你也可以在那里看看)

答案 3 :(得分:0)

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;
    }