2014-02-11 60 views
2

我正在開發使用Eclipse和Tomcat 6將配置值傳遞給servlet,而無需在.war文件中對其進行硬編碼?

我需要一個值傳遞給未硬編碼到.war文件 servlet的Java中的Web應用程序。
例如,假設我的servlet需要一個文件名,並且每個服務器上的文件名都不相同。
如何將它傳遞給servlet,而不在.war文件中對其進行硬編碼?

請幫我如何做到這一點的說明:在Eclipse

  • 從(例如:添加XXXX到文件YYY,然後運行)
  • 關於這一點我將部署在服務器上應用

我想在getInitParameter方向,但我還沒有找到一種方式來傳遞除了web.xml .war文件初始化參數,這是不是一個選擇因爲它需要可配置。所以如果你能告訴我如何在外部文件中設置init參數,問題就解決了。

注:我在尋找真正準確的建議,在「編輯文件上位置」。我發現了許多相關的問題和答案,但是沒有一個具體足以使其工作。

回答

1

,你可以把它作爲一個servlet參數。在你web.xml,你申報你的servlet(我指的是CONFIGFILE作爲文件你希望得到一個引用):

<servlet> 
    <servlet-name>ConfigParser</servlet-name> 
    <servlet-class>foo.baar.ConfigParser</servlet-class> 
    <init-param> 
     <param-name>configFilePath</param-name> 
     <param-value>/path/to/the/config/file</param-value> 
    </init-param> 
</servlet> 

我想你知道哪裏有web.xml文件是因爲你已經在使用的servlet。

然後在你的servlet中,你可以用你ServletConfig.getInitParameter("configFilePath")來獲取配置文件的位置。例如在你的servlet:你在哪裏得到您的參考配置文件

public void init(ServletConfig config) throws ServletException { 
    super.init(config); 
    String path_to_config_file=config.getInitParameter("configFilePath"); 
} 

容器將調用此方法與ServletConfig。 這意味着,你不需要在eclipse中擁有該文件。採用這種方法,您不必在服務器上做任何特殊的事情,唯一需要注意的就是文件被複制並且您在web.xml上聲明的路徑是正確的。

如果文件的位置可以動態構建,可以使用返回webapp的絕對路徑的ServletContext.getRealPath(「/」)。

--- UPDATE ---

回答到更新的問題。我不知道最佳做法是什麼,但有一個解決方法。您在tomcat主目錄中創建一個文件(conf_location.txt),其中包含一行,包含要傳遞給servlet的文件的位置。在你的servlet,你可以訪問這個黑客的文件(假設你的戰爭是$TOMCAT_HOME/webapps/mywar.war):

public void init() throws ServletException{ 
     String contextPath=getServletContext().getRealPath("/"); 
     File tomcatHome=new File(contextPath).getParentFile().getParentFile(); 
     File configFile=new File(tomcatHome,"conf_location.txt"); 
     try { 
      String config_location = new Scanner(configFile).useDelimiter("\\Z").next(); 
     } catch (Exception e) {} 
    } 
+0

但不是'.war'文件的'web.xml'部分?因爲那是我聲明我的servlet的地方。我喜歡'init-param'的方式,但我希望能夠在'.war'之外設置它。這是可能的,我把它放在哪裏? –

+0

但是你的servlet需要知道使用/解析什麼。您只需傳遞文件的引用,而不是文件本身。如果你想要包含這個文件,你可以將它放在「webapp/WEB-INF/classes」中,並且從你的servlet中可以解析爲「Dhanush Gopinath」在下面描述。我可能會誤解這個問題。 – 2014-02-11 19:53:13

+0

傳遞引用是好的,但我該怎麼做(沒有在我的.war文件中對引用進行硬編碼)? –

0

在你的servlet代碼,你可以從一個屬性文件,該文件駐留在你的classpath如果配置的位置是已知的加載它,這樣

Properties props = new Properties(); 
    try { 
     props.load(this.getClass().getClassLoader().getResourceAsStream("config.properties")); 
    } catch (IOException e1) { 
     log.error(e1.getMessage(), e1); 
    } 
    String prop1 = props.getProperty("prop1"); 
+0

不要忘記在你的tomcat上添加一個extenal目錄。您可以查看文件conf/catalina.properties上的屬性'shared.loader' –

+0

我需要在哪裏放置「config.properties」? 是否有必要把它放在外部文件夾中? –

+0

Tomcat/Lib目錄將是一個地方 –

3

有多種方法去了解這一點。這真的取決於你知道你正在加載的文件的位置。如果它是每個tomcat實例/服務器配置的東西,那麼環境變量或JVM參數可能是最簡單的。然後你可以在代碼中通過System.getProperty查找這個變量。

您可以通過CATALINA_HOME/bin/setenv.sh以每個Tomcat的方式傳遞JVM參數。

#!/bin/sh 
CATALINA_OPTS="$CATALINA_OPTS 
    -Dmy.file.path=/path/on/this/host/file.txt" 

並在代碼:

String path = System.getProperty("my.file.path") 

丹努什的建議也是一個很好的一個,可能是從長遠來看更具有可持續性。它具有將所有每個環境配置保留在一個單獨位置的優點,您可以將其保留在源代碼管理中。不過,你仍然需要一種方法來從屬性文件中選擇適當的鍵(因爲這個屬性文件將被捆綁在你的戰爭中),你可以再次使用環境變量或JVM參數來控制。

如果你想獲得小幅愛好者,你可以考慮使用JNDI

1
  1. 對於一個真正的項目,你不應該直接使用servlet。使用一個框架,可以幫助你指導一個方向。春天很常見。
  2. 如果您使用Spring,在您的應用程序上下文中,您將擁有一個名爲Property Placeholder配置器的bean。參見例如:spring PropertyPlaceholderConfigurer and context:property-placeholder。最佳做法是對該文件位置(file:classpath:)進行硬編碼,但該文件位於WAR文件之外。

應用context.xml中:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
    <property name="locations"> 
     <list> 
      <value>classpath:config/properties/database.properties</value> 
     </list> 
    </property> 
    <property name="ignoreResourceNotFound" value="true"/> 
</bean> 
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> 
    <property name="driverClassName" value="${jdbc.driverClassName}" /> 
    <property name="url" value="${jdbc.url}" /> 
    <property name="username" value="${jdbc.username}" /> 
    <property name="password" value="${jdbc.password}" /> 
</bean> 
  • 有幾種設計問題,在需要它的代碼加載配置文件。它使測試變得困難,它使通用設計的靈活性降低,如果明天你認爲屬性文件不足,並且想要將配置存儲在ZooKeeper或JNDI中,則必須重寫很多代碼。將你的代碼寫成對象,然後用設置注入,並按照上面的dataSource模式實例化它們。
  • +0

    對於較大的項目,我完全同意,我過去曾使用Spring。但是,我正在研究單個servlet,需要在不同的應用程序中重用它。這就是爲什麼我不想使用任何特定的框架。 –

    相關問題