【问题标题】:How to get real path in JSF in a SessionListener如何在 SessionListener 中获取 JSF 中的真实路径
【发布时间】:2011-11-26 13:54:54
【问题描述】:

我的要求如下:

INFO: icefaces 上传组件,将文件上传到相关文件夹,并为每个用户在该文件夹中创建一个带有 sessionId 的子目录。

要求:sessionDestroyed为每个用户,我想获取真实路径,删除当前用户文件夹。

我知道如何使用 JSF 获取真实路径如下:

ServletContext ctx = (ServletContext) FacesContext.getCurrentInstance()
                .getExternalContext().getContext();
        String deploymentDirectoryPath = ctx.getRealPath("/");

问题:如果你尝试在sessionDestroyed 中获取真实路径,你会得到空指针异常,所以我想知道是否有办法在监听器中初始化变量deploymentDirectoryPath 所以我可以在sessionDestroyed 方法中使用它,或者在应用程序启动时初始化真实路径变量并在这里使用它?

请告知如何解决此问题。

【问题讨论】:

    标签: servlets jsf-2 servlet-listeners


    【解决方案1】:

    即使您没有发布与问题相关的实际代码,以下为我提供了真正的路径:

    public class MySessListener implements HttpSessionListener {
    
        @Override
        public void sessionCreated(final HttpSessionEvent se) {
            System.out.println(Thread.currentThread().getStackTrace()[1]);
            new Timer().schedule(new TimerTask() {
    
                @Override
                public void run() {
                    HttpSession sess = se.getSession();
                    sess.invalidate();
                }
            }, 10000);
        }
    
        @Override
        public void sessionDestroyed(HttpSessionEvent se) {
            System.out.println(Thread.currentThread().getStackTrace()[1]);
            String realPath = se.getSession().getServletContext().getRealPath("/");
            System.out.println("realPath: " + realPath);
        }
    }
    

    输出

    信息:com.bhesh.demo.web.listener.MySessListener.sessionCreated(MySessListener.java:13) 信息:com.bhesh.demo.web.listener.MySessListener.sessionDestroyed(MySessListener.java:26) 信息:realPath:C:\Documents and Settings\Bhesh\My Documents\NetBeansProjects\JsfMessageList\build\web\

    【讨论】:

    • 我在 sessionDestroy 中尝试了以下代码,可能是 ServletContext ctx = (ServletContext) FacesContext.getCurrentInstance() .getExternalContext().getContext(); String deploymentDirectoryPath = ctx.getRealPath("/"); 的问题
    • 这就是我真正的猜测。这些与 JSF 相关,IMO 最好将它们保留在 JSF 中。
    • 在会话销毁期间不一定意味着FacesContext,因为它可以在没有对 JSF 资源的 HTTP 请求的情况下执行。所以getCurrentInstance() 将返回null。顺便说一句,ExternalContext 也有一个getRealPath() 方法。您应该更喜欢使用它。在 JSF 支持 bean 中引入 javax.servlet 是一种糟糕做法的标志。最后但不是最后一点,您应该真正考虑到getRealPath() 可以返回null,当容器配置为在内存而不是磁盘中扩展WAR 时。如果您没有 100% 的管理员控制权,则不应使用它。
    【解决方案2】:

    基于 BalusC 在这里和其他地方的合理建议,人们可以编写一个像这样的通用函数:

      String getPath(){
    
    ExternalContext tmpEC;      
    
    tmpEC = FacesContext.getCurrentInstance().getExternalContext();   
    String realPath=tmpEC.getRealPath("/");
    return realPath;    
    }
    

    【讨论】:

    • 你能解释一下这个问题是如何回答这个问题的,这是关于在会话拆除期间获取路径,当(正如@BalusC 在 cmets 中对另一个答案所解释的那样)可能不是 FacesContext?
    • 基于我的假设:“顺便说一下,ExternalContext 也有一个 getRealPath() 方法。您应该更喜欢使用它”。但对 JSF 来说还算新,我怀疑我误解了。
    • 方法没问题。关键是整个上下文可能不可用。在某些情况下,您的代码会导致 NullPointerException。
    【解决方案3】:

    你可以得到真正的路径如下:-

    FacesContext.getCurrentInstance().getExternalContext().getRealPath("/");
    

    编辑:-

    正如 BalusC 在他的一个答案中所提到的,在使用 getRealPath("/") 之前您应该三思而后行,因为如果没有选择扩展 war 文件,getRealPath("/") 可能会返回 null

    请改用getExternalContext.getResourceAsStream。根据docs,在应用启动或关闭时调用该方法有效。

    【讨论】:

    • 请先解释一下这是如何在HttpSessionListener中工作的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-28
    • 1970-01-01
    • 2013-07-20
    • 2013-07-06
    • 2020-01-29
    相关资源
    最近更新 更多