讀取配置文件的正確姿勢(關於配置文件的路徑獲取)



0、寫在前面的話

最近在做微信的公眾號開發,因為調用微信接口失敗的話是以各類錯誤碼和錯誤信息返回的,在Github發現有位老哥整理成了xml( weixin/error.xml),索性也就想借鑒他的方式和這份xml,將內容讀取存儲到一個Map中,這樣在遇到微信返回的錯誤碼時就可以從Map中取出對應的具體錯誤信息。

在工具類中建立一個靜態塊,然后試圖讀取xml然后存入Map,問題來了,之前在Servlet中都是利用的ServletContext上下文對象,使用getRealPath(String path)方法獲取文件路徑。可是這個工具類並不是Servlet,也就沒有ServletContext。

然而,什么都難不倒Google,下面就類似的配置文件的讀取問題,進行一下總結。

另外,要說一個前提是, xml、properties等配置文件和Java資源都是放在WEB-INF下面的classes文件夾中(以下則稱之為classpath)。我們的目的是如何獲取該目錄下的文件資源,假如我們現在的文件為應用根目錄下" .../WEB-INF/classes/error.xml "。

 

1、在Servlet類中讀取

假如要將文件獲取為流,有兩種讀取方式:

(1)直接讀取文件為流,getResourceAsStream(path)方法,path默認為應用的根目錄
InputStream inputStream = this.getServletContext().getResourceAsStream("/WEB-INF/classes/error.xml"); 

(2)先讀取文件,再讀取為流,獲取路徑的方式和上面是類似的
String path = this.getServletContext().getRealPath("/WEB-INF/classes/error.xml");
InputStream inputStream = new FileInputStream(path);


2、在非Servlet類中(普通Java類中)的讀取

在非Servlet類中,要將文件獲取為流,也有兩種方式:

(1)用ClassLoader類加載資源文件,這里默認是從classes目錄下讀取

用ClassLoader加載配置文件時,path,也就是這里的 "error.xml" 不能以"/"開頭,在查找時直接在classpath下進行查找:
InputStream in = ClassName.class.getClassLoader().getResourceAsStream("error.xml");

同樣的方法,也可以迂回一下,先讀取到文件的路徑,再用流讀出,這里FileInputStream的path就可以使用絕對或者相對路徑:
String path = ClassName.class.getClassLoader().getResource("error.xml").getPath();  
InputStream inputStream = new FileInputStream(path); 


(2)用Class類加載資源文件,形參不同,訪問路徑不同
InputStream inputStream = ClassName.class.getResourceAsStream("/error.xml");
需要注意的是,這種方式的形參有兩種方式:
  • 絕對定位,“/”開頭,此時即以classpath為根目錄
  • 相對定位,不加“/”,則以調用getResourceAsStream類的包路徑作為根目錄(即該類所在包下獲取資源)


最后,也就是用了如上的方法,解決了我讀取error.xml的問題:
//讀取errorCode錯誤碼到Map中
static {
    InputStream xml = WeChatUtil.class.getResourceAsStream("/error.xml");
    SAXReader saxReader = new SAXReader();
    try {
        Document document = saxReader.read(xml);
        Element root = document.getRootElement();
        List<Element> elements = root.elements();
        for (Element element : elements) {
            String code = element.elementText("code");
            String text = element.elementText("text");
            WeChatUtil.errorCodeMap.put(code, text);
        }
    } catch (DocumentException e) {
        log.debug("error.xml讀取失敗");
        e.printStackTrace();
    }
}


3、參考鏈接



題外話:

在使用Spring時通常看到諸如 <param-value >classpath:applicationContext-*.xml</param-value> 的配置,此處的classpath確實是指WEB-INF下的classes目錄,但此處畢竟只是配置的字符串,實際上獲取資源路徑時是框架進行了識別和處理的。我之前也是很愚,一直不理解所謂的classpath,今天才明白了些許,順便追了下Spring源碼。

在Spring的配置中,實際上有classpath和classpath*,區別在於:
  • classpath     只會到你的classes路徑中查找找文件
  • classpath*    不僅包含classes路徑,還包括jar文件中(class路徑)進行查找



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM