java - 使用 JSF 从 JAR 文件中加载属性文件

标签 java jsf

这是我的项目的 Maven 结构

app
  > common-module
  > webapp-module
  > batch-module
 pom.xml

The common-module exposes a Version class. This class is used by both webapp and batch modules.

The Version class has one unique static method called get. It returns the global version of the project.

The global version is stored in a properties file. When get is called from batch module (a standalone java application), the properties file is successfully loaded.

In the webapp, things are different. I have created a managed bean VersionBean that would permit any JSF page to call the get method. Whenever I use one of the following

FacesContext.getCurrentInstance().getExternalContext()

FacesContext.getCurrentInstance().getExternalContext().getContext()

Thread.currentThread().getClassLoader()

我永远找不到properties.file。

如何从托管 bean 加载位于 jar 文件中的属性文件 (getResourceAsStream)?

编辑
这是我根据 @BalusC 和 @eljunior 的建议提出的解决方案

VersionBean.java

@ManagedBean(eager=true)
@ApplicationScoped
public class VersionBean {
    private String version;
    @PostConstruct
    public void init(){
        version = Version.get();
    }
}

版本.java

public class Version {
    public static String get() {
        InputStream is = Version.class.getResourceAsStream("/version.properties");

        // Read InputStream and return version string ...
    }
}

最佳答案

我不确定 Maven 如何构建 WAR 以及您的属性文件实际位于何处,但我至少可以告诉 ExternalContext#getResourceAsStream(), Thread#getContextClassLoader()Class#getClassLoader() 的工作方式不同。

  1. ExternalContext#getResourceAsStream()
    ExternalContext#getResourceAsStream() 扫描 Web 内容文件夹中的 Web 应用程序资源(WAR 的 /WEB-INF/META-INF 文件夹位于此处)也驻留在)以及部署在 Web 应用程序的 /WEB-INF/lib 中的任何 JAR 文件的 /META-INF/resources 文件夹中。提供的路径始终相对于这些根文件夹,并且应以 / 开头。

    InputStream input = externalContext
        .getResourceAsStream("/WEB-INF/version.properties");
    
  2. Thread#getContextClassLoader()
    Thread#getContextClassLoader() 在类路径的“根”上运行。这涵盖了 webapp、appserver 和 JVM 的类路径所覆盖的所有文件夹。提供的路径始终相对于类路径根目录,并且不能以 / 开头。请注意,当属性文件包含在包中时,您应该将包结构视为文件系统路径,并以 / 作为分隔符。下面的示例假设它位于包 com.example.version 中。

    InputStream input = Thread.currentThread().getContextClassLoader()
        .getResourceAsStream("com/example/version/version.properties");
    
  3. Class#getClassLoader()
    Class#getClassLoader() 相对于类本身的位置进行操作。提供的路径可以是相对路径或绝对路径。如果是相对的,那么它是相对于类本身的位置的。如果是绝对的,那么它对于类路径根来说是绝对的。请注意,这不一定可以访问类路径覆盖的所有其他文件夹。下面的示例假设属性文件与 VersionBean 类位于同一包中:

    InputStream input = VersionBean.class
        .getResourceAsStream("version.properties");
    

    或者当它在另一个包中时,例如com.example.other(注意开头的/):

    InputStream input = VersionBean.class
        .getResourceAsStream("/com/example/other/version.properties");
    

关于java - 使用 JSF 从 JAR 文件中加载属性文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10873885/

相关文章:

java - 快速比较地理点之间的距离

JSF 用户界面 :include downside

java - JSF (facelets) IDE 代码完成

java - 由于某种原因,JSP 文档输出 XML 而不是 HTML

java - @Model Java 类中变量的范围是什么?

java - Spring 数据neo4j : correct way to handle relationships?

java - 工件的 IntelliJ Tomcat 部署顺序

java - 发现很长,需要 boolean 值(插入 SQLite [Android])

java - LinkedHashMap的Java实现

java - JSF:嵌套 ui:repeat 中的值绑定(bind)