这是你的选择。 Java Web 应用程序归档 (WAR) 基本上有三种方式:
1.将其放入类路径中
这样你就可以通过以下方式加载它ClassLoader#getResourceAsStream() http://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html#getResourceAsStream%28java.lang.String%29使用类路径相对路径:
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("foo.properties");
// ...
Properties properties = new Properties();
properties.load(input);
Here foo.properties
应该放置在 web 应用程序的默认类路径覆盖的根目录之一中,例如网络应用程序/WEB-INF/lib
and /WEB-INF/classes
, 服务器的/lib
,或 JDK/JRE 的/lib
。如果属性文件是特定于 Web 应用程序的,最好将其放在/WEB-INF/classes
。如果您正在 IDE 中开发标准 WAR 项目,请将其放入src
文件夹(项目的源文件夹)。如果您使用的是 Maven 项目,请将其放入/main/resources
folder.
您也可以将其放在默认类路径之外的某个位置,并将其路径添加到应用程序服务器的类路径中。例如,在 Tomcat 中,您可以将其配置为shared.loader
的财产Tomcat/conf/catalina.properties
.
如果您已放置foo.properties
它在 Java 包结构中,例如com.example
,那么你需要按如下方式加载它
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("com/example/foo.properties");
// ...
请注意,上下文类加载器的此路径不应以/
。仅当您使用“相对”类加载器时,例如SomeClass.class.getClassLoader()
,那么你确实需要以/
.
ClassLoader classLoader = getClass().getClassLoader();
InputStream input = classLoader.getResourceAsStream("/com/example/foo.properties");
// ...
但是,属性文件的可见性取决于相关的类加载器。它仅对加载该类的同一类加载器可见。因此,如果该类是由例如加载的服务器通用类加载器而不是 webapp 类加载器,并且属性文件位于 webapp 本身内部,那么它是不可见的。上下文类加载器是您最安全的选择,因此您可以将属性文件放置在类路径中的“任何位置”和/或您打算能够从 Web 应用程序覆盖服务器提供的属性文件。
2. 将其放入网页内容中
这样你就可以通过以下方式加载它ServletContext#getResourceAsStream() http://docs.oracle.com/javaee/7/api/javax/servlet/ServletContext.html#getResourceAsStream%28java.lang.String%29具有网络内容相对路径:
InputStream input = getServletContext().getResourceAsStream("/WEB-INF/foo.properties");
// ...
请注意,我已经演示了将文件放入/WEB-INF
文件夹,否则任何网络浏览器都可以公开访问它。另请注意,ServletContext
是在任何HttpServlet
类只能由继承访问GenericServlet#getServletContext() http://docs.oracle.com/javaee/7/api/javax/servlet/GenericServlet.html#getServletContext%28%29 and in Filter
by FilterConfig#getServletContext() https://docs.oracle.com/javaee/7/api/javax/servlet/FilterConfig.html#getServletContext--。如果您不在 servlet 类中,它通常只能通过以下方式注入@Inject
.
3.放入本地磁盘文件系统
这样你就可以像平常一样加载它java.io
使用绝对本地磁盘文件系统路径的方式:
InputStream input = new FileInputStream("/absolute/path/to/foo.properties");
// ...
请注意使用绝对路径的重要性。在 Java EE Web 应用程序中绝对不能使用相对本地磁盘文件系统路径。另请参阅下面的第一个“另请参阅”链接。
选择哪个?
只需权衡优点/缺点your自己对可维护性的看法。
如果属性文件是“静态”的并且在运行时不需要更改,那么您可以将它们保留在 WAR 中。
如果您希望能够从 Web 应用程序外部编辑属性文件,而不需要每次都重新构建和重新部署 WAR,那么请将其放在项目外部的类路径中(如果需要,请将目录添加到类路径中)。
如果您希望能够从 Web 应用程序内部以编程方式编辑属性文件,请使用Properties#store()
方法,将其放在 Web 应用程序之外。作为Properties#store()
需要一个Writer
,您不能使用磁盘文件系统路径。该路径又可以作为 VM 参数或系统属性传递到 Web 应用程序。作为预防措施,never use getRealPath() https://stackoverflow.com/questions/12160639/what-does-servletcontext-getrealpath-mean-and-when-should-i-use-it。部署文件夹中的所有更改都将在重新部署时丢失,原因很简单,这些更改不会反映在原始 WAR 文件中。
也可以看看:
- getResourceAsStream() 与 FileInputStream https://stackoverflow.com/questions/2308188/getresourceasstream-vs-fileinputstream
- 将目录添加到 tomcat 类路径 https://stackoverflow.com/questions/1300780/adding-a-directory-to-tomcat-classpath
- 以编程方式访问 JSF 应用程序中的属性文件 https://stackoverflow.com/questions/7952090/accessing-i18n-properties-file-in-a-jsf-application-programmatically/