簡體   English   中英

Java - 如何在沒有 servlet 上下文的情況下訪問 WEB-INF 文件夾中的文件

[英]Java - How to access a file in the WEB-INF folder WITHOUT servlet context

我有一個中心類( RuntimeConfiguration ),它為我的應用程序保存了大約100參數。 這些參數取自我存儲在WEB-INF文件夾中的XML 文件 在我的開發箱中,我對路徑進行了硬編碼,但由於非常明顯的原因,這不是一個有效的解決方案。

出於可移植性的原因(我的應用程序可能在TomcatJetty上以及在 Windows 或 Unix 下執行),我希望從我的RuntimeConfiguration類中獲得對該文件的通用訪問方式。

我知道,如果我有一個 servlet,我可以使用getRealPath ,但是RuntimeConfiguration不是在servlet context 中啟動的。 它是從作業(爬蟲)調用的,而作業(爬蟲)又是通過applicationContext.xml從石英作業控制啟動的。 現在這似乎是我問題的核心。

誰能告訴我,如何在這種環境中獲取我的 XML 的絕對路徑?

我嘗試了這種ClassLoader方法,但它給了我一個NullPointerException

ClassLoader loader = this.getClass().getClassLoader();
loader.getResource("WEB-INF");
result = loader.getSystemResource(RTCF).toString(); 

我也試過

URL url = this.getClass().getClassLoader().getResource("WEB-INF");

這也會引發空指針異常

誰能給我一個可移植的解決方案,一個可以在我的開發機器和我的應用程序部署為 WAR 文件的生產系統上運行的解決方案?

順便說一句,該方法最好能夠處理基於 Windows 和 Mac OS X / Unix 的系統。

您始終可以使用持有者模式:您創建一個類,其中包含一個包含WEB-INF目錄的真實路徑的靜態字段(及其靜態 getter)。 此類應實現ApplicationContextAware

您在根 spring 應用程序上下文中創建此持有者類的實例,Spring 給它一個指向 ApplicationContext 的指針,該指針將成為WebApplicationContext ,就像您在 Web 應用程序中一樣。

在 init 方法中,您使用WebApplicationContext獲取路徑並將其存儲在靜態字段中。 感謝 Spring,您可以確定該方法在應用程序真正啟動之前只被調用一次。

現在,在應用程序中您想要獲取路徑的任何地方,您都可以通過調用靜態 getter 來使用它。

public class ResourcePathHolder implements ApplicationContextAware, InitializingBean{
    private WebApplicationContext wac;
    private static String resourcePath;
    private static ServletContext sc;
    private String path = "WEB-INF";

    public static String getResourcePath() {
        return resourcePath;
    }

    public static ServletContext getServletContext() {
        return sc;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        wac = (WebApplicationContext) applicationContext;
    }

    public void setPath(String path) {
        this.path = path;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        ResourcePathHolder.sc = wac.getServletContext();
        ResourcePathHolder.resourcePath = sc.getRealPath(path);
    }
}

此實現還允許您訪問ServletContext以允許您使用ServletContext.getResource()

編輯 :

使用完整路徑可能不適用於不會引發戰爭的生產服務器。 來自ServletContext.getRealPath()的 javadoc:如果 servlet 容器無法將給定的虛擬路徑轉換為真實路徑,則此方法返回 null 但在這種情況下,您始終可以使用ServletContext.getResource()ServletContext.getResourceAsStream()將文件作為資源訪問

在 Spring Web 應用程序中,除非在 Web 應用程序上下文中將某個類聲明為 bean,否則無法獲取上下文路徑 在您的RuntimeConfiguration類中添加以下代碼

@Autowired
private ServletContext servletContext;

public {desired returnType} getDirectoryPath(){
    File webInfPath = new File(this.getClass().getClassLoader().getResource("WEB-INF"));
    // OR use getResourceAsStream() method
    InputStream is = RuntimeConfiguration.class.getClassLoader().getResourceAsStream("WEB-INF");
}

或者

如果您不想進行自動裝配,那么您可以使用 ServletContextAware 接口實現 RuntimeConfiguration。 就像下面一樣,在這個類中獲取 servlet 上下文對象:-

public class RuntimeConfiguration implements ServletContextAware {

    private ServletContext context;
    private ServletConfig config;

    @Override
    public void setServletContext(final ServletContext servletContext) {
        this.context = servletContext;
    }

    public ServletContext getServletContext()[
        return context;
    }
    //do other tasks
}

或者

看看ServletContextResource ServletContextResource - Spring Docs

只需將它放在您的類路徑中並使用“getResourcesAsStream()”加載它,或者最好將其設為“.properties”文件並以通常的方式加載它:

ResourceBundle config = ResourceBundle.getBundle("filename");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM