2009-07-14 48 views
1

實際的問題是:有沒有辦法讓XmlWebApplicationContext使用相對於上下文位置的路徑加載資源?爲了清楚起見,我們假設「上下文位置」是通過setConfigLocation()方法指定的第一個文件的位置。通過Spring指定相對資源路徑XmlWebApplicationContext

詳細解釋如下:
我在web層中使用Spring MVC,在中層使用Spring IOC。如Spring Documentation中所述分層次地定義適當的上下文:網絡材料在my-servlet.xml中定義,並且服務等在services.xml中定義,其通過ContextLoaderListener加載。中間層可以與Web層一起部署(例如,整個事件在ServletContainer中運行)或單獨部署(在這種情況下,services.xml由定義遠程存根的remote-services.xml取代)。整個安裝完美的作品,除了以下問題:

我必須位於同一文件夾中services.xml需要被訪問某些資源(額外的XML文件,你有什麼)說服務。這些資源在services.xml中使用相對路徑被指定爲相關性。中間層獨立部署可以正常工作,但不能在servlet容器內部署時使用。在後一種情況下,中間層上下文被實例化爲XmlWebApplicationContext,它加載了所有基於servlet上下文根的資源,這意味着我必須在所有我想要避免的東西前加上前綴。使用PropertyPlaceholderConfigurer也會出現類似的問題。

我知道我可以通過從類路徑加載資源來解決這個問題,但這也不是很理想 - 對於獨立部署,這意味着我需要將配置文件夾添加到類路徑中,對於Web部署,它意味着所有內容都必須複製到WEB-INF/classes中。

任何想法?

回答

3

我已經結束了Spring的XmlWebApplicationContext以允許相對資源路徑。這就是我想要的,這允許我使用相同的context.xml文件,無論它是作爲Web應用程序的一部分還是獨立部署的。

對於任何感興趣的源代碼可在下面找到。它使用SOV(堆棧溢出投票)許可證:-)這意味着你可以自由地做,只要你給予好評這個答案:-)

import java.io.IOException; 

import org.springframework.core.io.Resource; 
import org.springframework.util.StringUtils; 
import org.springframework.web.context.support.XmlWebApplicationContext; 

/** 
* Extends Spring's default web application context to allow relative 
* resource paths. Resources without explicitly specified URL protocol 
* and/or leading slash are loaded relative to the first location 
* from getConfigLocations(). 
*/ 

public class SpringApplicationContext extends XmlWebApplicationContext { 

    @Override 
    protected Resource getResourceByPath(String path) { 
    path = StringUtils.cleanPath(path); 
    if (path.startsWith("/") || (path.indexOf(':')>0)) { 
     return super.getResourceByPath(path); 
    } 
    try { 
     return super.getResourceByPath(getConfigLocations()[0]) 
     .createRelative(path); 
    } catch (IOException E) { 
     // failed to create relative resource - default to standard implementation 
     return super.getResourceByPath(path); 
    } 
    } // getResourceByPath() 
} 
1

我同意這很煩人。我通過完成你的建議來解決這個問題,這就是將我的spring配置放在類路徑中,所以儘管我仍然使用完全限定的導入,但它們可以在任何環境下工作。

雖然我不確定爲什麼你的類路徑配置需要那麼複雜。這些文件可以在Java文件旁邊的java源文件夾中,所以它們的處理方式相同。

+0

謝謝你的答覆。在某些情況下,將資源與java文件放在一起是完全正確的(我爲Hibernate查詢做了這些工作......),但是對於在部署過程中可以更改的東西(比如`PropertyPlaceholderConfigurer`使用的屬性文件),這是非常不方便的。它必須是可訪問的(例如不在jar等內部) - 因此,我必須將它放在/ WEB-INF/classes中,或者在獨立部署期間將它所在的「conf」文件夾添加到類路徑中。 – ChssPly76 2009-07-14 16:40:07

1

怪任何你想用它出版。您的解決方案對我無效。這是我的:

package dmp.springframework.web.context; 

import java.io.IOException; 
import org.springframework.core.io.FileSystemResource; 
import org.springframework.core.io.Resource; 
import org.springframework.util.StringUtils; 
import org.springframework.web.context.support.XmlWebApplicationContext; 

public class RelativeResourceXmlWebApplicationContext extends XmlWebApplicationContext { 

    @Override 
    protected Resource getResourceByPath(String path) { 
     path = StringUtils.cleanPath(path); 
     if (path.startsWith("/") || (path.contains(":"))) { 
      return super.getResourceByPath(path); 
     } 
     try { 
      String newFilename = super.getResourceByPath(getConfigLocations()[0]).getFile().getParentFile().getAbsolutePath(); 
      newFilename = newFilename + "/" + path; 
      return new FileSystemResource(newFilename); 
     } catch (IOException E) { 
      // failed to create relative resource - default to standard implementation 
      return super.getResourceByPath(path); 
     } 
    } // getResourceByPath() 
}