java Maven 项目中的资源和配置加载
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16374235/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Resources and config loading in maven project
提问by LMnet
I'm using Maven for desktop applycation. I read about Maven standart directory layoutand I have this project structure for now:
我正在使用 Maven 进行桌面应用。我阅读了Maven 标准目录布局,现在我有这个项目结构:
App
|-- pom.xml
`-- src
|-- main
|-- java
| `-- java classes
|-- resources
| `-- images
| `-- app images
`--config
`--config.xml
I want to find a way to load my resources and config files. I read some articles and topics and found this (simplified example from my code):
我想找到一种方法来加载我的资源和配置文件。我阅读了一些文章和主题并发现了这一点(我的代码中的简化示例):
//class for loading config
public class Preferences {
public Preferences() {
InputStream image = Preferences.class.getResourceAsStream("images/image.png");
InputStream config = Preferences.class.getResourceAsStream("config.xml");
}
}
But image and config variables contains null. I was trying different variants of loading (from root folder, with this.getClass() instead of Preferences.class, and others), but I always have null. I really don't understand this resource loading system and I didn't find any good documentation about it. It would be nice, if somebody gives a good explanation about this mechanism (or just give a link on docs). So, the main question is: How can I load my resources and config files?
但是图像和配置变量包含空值。我正在尝试不同的加载变体(从根文件夹,使用 this.getClass() 而不是 Preferences.class 等),但我总是为 null。我真的不明白这个资源加载系统,我没有找到任何关于它的好的文档。如果有人对这个机制给出一个很好的解释(或者只是给出一个关于文档的链接),那就太好了。所以,主要问题是:如何加载我的资源和配置文件?
采纳答案by LMnet
I think I found the solution. As Juned Ahsan and mR_fr0g write, I need to use ClassLoader class, instead of this.getClass().getResource(). But, it works only for resource folder. But maven allows to add other folders as resource folders. I was just needed to add this section to pom.xml:
我想我找到了解决方案。正如 Juned Ahsan 和 mR_fr0g 所写,我需要使用 ClassLoader 类,而不是 this.getClass().getResource()。但是,它仅适用于资源文件夹。但是 maven 允许添加其他文件夹作为资源文件夹。我只需要将此部分添加到 pom.xml 中:
<build>
<resources>
<resource>
<directory>src/main/config</directory>
</resource>
</resources>
</build>
And working java code is:
工作Java代码是:
InputStream image = this.getClass().getClassLoader().getResourceAsStream("images/image.png");
InputStream config = ClassLoader.getSystemResourceAsStream("config.xml");
回答by WesternGun
You can use getResourceAsStream()
method of java.lang.Class
as you have done, but you have to add /
before the path.
你可以像你所做getResourceAsStream()
的java.lang.Class
那样使用方法,但你必须/
在路径之前添加。
This question is tricky.
这个问题很棘手。
1. Two methods with same name
1. 两个同名方法
First of all, exist two methods of same name and same signaturein these two classes:
首先,在这两个类中存在两个同名同名的方法:
java.lang.Class
java.lang.ClassLoader
They have the same name: getResource(String)
(and getResourceAsStream(String)
is alike).
它们具有相同的名称:(getResource(String)
并且getResourceAsStream(String)
相似)。
2. They accept params of different format
2. 他们接受不同格式的参数
Then, the param of them has different format:
然后,它们的参数具有不同的格式:
- The method
java.lang.Class.getResouce<asStream>()
accepts path with and without the leading/
, resulting in different resources searching strategies. If a path has no/
, Java will search the resource in the package/folder where the.class
file resides. If it has/
, Java will begin the searching from classpath root. The method
java.lang.ClassLoader.getResource<asStream>()
accepts only path without/
, because it always search from classpath. In a classpath based path,/
is not a valid character. **: As this answer states: this.getClass().getClassLoader().getResource("...") and NullPointerException
- 该方法
java.lang.Class.getResouce<asStream>()
接受有和没有前导的路径/
,导致不同的资源搜索策略。如果路径没有/
,Java 将在.class
文件所在的包/文件夹中搜索资源。如果有/
,Java 将从类路径根开始搜索。 该方法
java.lang.ClassLoader.getResource<asStream>()
只接受没有 的路径/
,因为它总是从类路径中搜索。在基于类路径的路径中,/
不是有效字符。**:正如这个答案所述:this.getClass().getClassLoader().getResource("...") 和 NullPointerException
How to add a folder to classpath? In Eclipse we resolve to the context menu of a project: "Build path" - "Configure build path..." and add some folder to build path.
如何将文件夹添加到类路径?在 Eclipse 中,我们解析到项目的上下文菜单:“构建路径”-“配置构建路径...”并添加一些文件夹到构建路径。
3. When it comes to Maven
3. 说到 Maven
At last, if a project is a Maven project, by default src/main/resources
is in the classpath, so we can use
最后,如果一个项目是Maven项目,默认src/main/resources
是在classpath中,所以我们可以使用
Class.getResource("/path-to-your-res");
or,
或者,
ClassLoader.getResource("path-to-your-res");
, to load anything under src/main/resources
.
, 加载src/main/resources
.
If we want to add another resources folder, as you have mentioned, it is done in pom.xml
. And they are added into classpath as well, done by Maven. No extra config is needed.
如果我们想添加另一个资源文件夹,正如你所提到的,它是在pom.xml
. 它们也被添加到类路径中,由 Maven 完成。不需要额外的配置。
4. Example
4. 例子
For example, if your config.ini
is under src/main/resources/settings
, myAvatar.gif
under src/main/images
, you can do:
例如,如果您config.ini
是 under src/main/resources/settings
,myAvatar.gif
under src/main/images
,您可以执行以下操作:
In pom.xml
:
在pom.xml
:
<build>
<resources>
<resource>
<directory>src/main/images</directory>
</resource>
</resources>
</build>
In code:
在代码中:
URL urlConfig = MyClass.class.getResource("/settings/config.ini"); //by default "src/main/resources/" is in classpath and no config needs to be changed.
InputStream inputAvatar = MyClass.class.getResourceAsStream("/myAvatar.gif"); //with changes in pom.xml now "src/main/images" is counted as resource folder, and added to classpath. So we use it directly.
We must use /
above.
我们必须使用/
上面的。
Or, with ClassLoader:
或者,使用类加载器:
URL urlConfig = MyClass.class.getClassLoader().getResource("settings/config.ini"); //no leading "/"!!!
InputStream inputAvatar = MyClass.class.getClassLoader().getResourceAsStream("myAvatar.gif"); //no leading "/"!!!
回答by mR_fr0g
public Preferences() {
InputStream image = this.getClass().getClassLoader().getResourceAsStream("image.png");
InputStream config = this.getClass().getClassLoader().getResourceAsStream("config.xml")
}
回答by Juned Ahsan
How about using this appraoch:
如何使用这种方法:
InputStream file = ClassLoader.getSystemResourceAsStream("res.txt");
or
或者
InputStream file = Thread.currentThread().getContextClassLoader().getResourceAsStream("MyProperty.properties");
As you currently have it there, that will look for the MyProperty.properties file at the top of your classpath. The could be in your src/main/resources directory or other src folder -- it would depend on how your application (jar/war) is built.
正如您目前拥有的那样,它将在您的类路径顶部查找 MyProperty.properties 文件。可能在您的 src/main/resources 目录或其他 src 文件夹中——这取决于您的应用程序 (jar/war) 的构建方式。
If you are building a jar then you should be able to unpack it and see your properties file at the top level of the jar. If you are building a war, maybe it should be in the WEB-INF/classes directory. Again, it depends on how it was built.
如果您正在构建一个 jar,那么您应该能够解压缩它并在 jar 的顶层查看您的属性文件。如果你正在构建一场War,也许它应该在 WEB-INF/classes 目录中。同样,这取决于它是如何构建的。
回答by J. L. Pacheco
Try to build the project before. If you just put the files in the resources folder then you need to build the project in order to copy the new resource files into target folder
尝试先构建项目。如果您只是将文件放在资源文件夹中,那么您需要构建项目才能将新资源文件复制到目标文件夹中