【问题标题】:Tomcat: how to access (session) Manager from servletTomcat:如何从 servlet 访问(会话)管理器
【发布时间】:2011-08-14 00:58:14
【问题描述】:

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

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

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

如果有任何其他提示如何从上下文访问管理器或原始问题的解决方案,我将不胜感激。

提前致谢, 陪审团

【问题讨论】:

    标签: session tomcat servlets jakarta-ee


    【解决方案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】:

      Ihor 的代码相比,此代码通过从 HttpSession 获取 Manager 使用更少的抽象:

      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中是否暴露了manager,不过你也可以看看)

        【讨论】:

          【解决方案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;
              }
          

          【讨论】:

          • 请在您的答案中添加一些解释,以便其他人可以从中学习
          猜你喜欢
          • 2011-04-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-12-27
          • 2014-08-24
          • 2011-06-07
          • 1970-01-01
          相关资源
          最近更新 更多